Merged in release/2022-10-21 (pull request #597)

Release/2022 10 21
This commit is contained in:
Patrick Fic
2022-10-18 00:07:33 +00:00
15 changed files with 163 additions and 17 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project version="1.2" be_version="2.7.1"> <babeledit_project be_version="2.7.1" version="1.2">
<!-- <!--
BabelEdit project file BabelEdit project file
@@ -3078,6 +3078,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>generatepartslabel</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>iouexists</name> <name>iouexists</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -26210,6 +26231,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>alreadyaddedtoscoreboard</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>alreadyclosed</name> <name>alreadyclosed</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -27852,6 +27894,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>iou</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>job</name> <name>job</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -1,5 +1,5 @@
import { useApolloClient, useMutation } from "@apollo/client"; import { useApolloClient, useMutation } from "@apollo/client";
import { Button, Form, Modal, notification, Space } from "antd"; import { Button, Checkbox, Form, Modal, notification, Space } from "antd";
import _ from "lodash"; import _ from "lodash";
import React, { useEffect, useState, useMemo } from "react"; import React, { useEffect, useState, useMemo } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -26,6 +26,9 @@ import BillFormContainer from "../bill-form/bill-form.container";
import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility"; import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility";
import { handleUpload } from "../documents-upload/documents-upload.utility"; import { handleUpload } from "../documents-upload/documents-upload.utility";
import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility"; import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility";
import useLocalStorage from "../../utils/useLocalStorage";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
billEnterModal: selectBillEnterModal, billEnterModal: selectBillEnterModal,
@@ -38,6 +41,8 @@ const mapDispatchToProps = (dispatch) => ({
dispatch(insertAuditTrail({ jobid, operation })), dispatch(insertAuditTrail({ jobid, operation })),
}); });
const Templates = TemplateList("job_special");
function BillEnterModalContainer({ function BillEnterModalContainer({
billEnterModal, billEnterModal,
toggleModalVisible, toggleModalVisible,
@@ -54,7 +59,10 @@ function BillEnterModalContainer({
const [updateInventoryLines] = useMutation(UPDATE_INVENTORY_LINES); const [updateInventoryLines] = useMutation(UPDATE_INVENTORY_LINES);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const client = useApolloClient(); const client = useApolloClient();
const [generateLabel, setGenerateLabel] = useLocalStorage(
"enter_bill_generate_label",
false
);
const formValues = useMemo(() => { const formValues = useMemo(() => {
return { return {
...billEnterModal.context.bill, ...billEnterModal.context.bill,
@@ -275,6 +283,20 @@ function BillEnterModalContainer({
notification["success"]({ notification["success"]({
message: t("bills.successes.created"), message: t("bills.successes.created"),
}); });
if (generateLabel) {
GenerateDocument(
{
name: Templates.parts_invoice_label_single.key,
variables: {
id: billId,
},
},
{},
"p"
);
}
if (billEnterModal.actions.refetch) billEnterModal.actions.refetch(); if (billEnterModal.actions.refetch) billEnterModal.actions.refetch();
insertAuditTrail({ insertAuditTrail({
@@ -330,6 +352,12 @@ function BillEnterModalContainer({
}} }}
footer={ footer={
<Space> <Space>
<Checkbox
checked={generateLabel}
onChange={(e) => setGenerateLabel(e.target.checked)}
>
{t("bills.labels.generatepartslabel")}
</Checkbox>
<Button onClick={handleCancel}>{t("general.actions.cancel")}</Button> <Button onClick={handleCancel}>{t("general.actions.cancel")}</Button>
<Button loading={loading} onClick={() => form.submit()}> <Button loading={loading} onClick={() => form.submit()}>
{t("general.actions.save")} {t("general.actions.save")}

View File

@@ -1,4 +1,5 @@
import { useMutation, useLazyQuery } from "@apollo/client"; import { useMutation, useLazyQuery } from "@apollo/client";
import { CheckCircleOutlined } from "@ant-design/icons";
import { import {
Button, Button,
Card, Card,
@@ -141,6 +142,12 @@ export default function ScoreboardAddButton({
</Form> </Form>
)} )}
</div> </div>
{entryData && entryData.scoreboard && entryData.scoreboard[0] && (
<Space>
<CheckCircleOutlined style={{ color: "green" }} />
<span>{t("jobs.labels.alreadyaddedtoscoreboard")}</span>
</Space>
)}
</Card> </Card>
); );

View File

@@ -2,8 +2,9 @@ import {
ExclamationCircleFilled, ExclamationCircleFilled,
PauseCircleOutlined, PauseCircleOutlined,
WarningFilled, WarningFilled,
BranchesOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { Card, Col, Row, Space, Tag } from "antd"; import { Card, Col, Row, Space, Tag, Tooltip } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
@@ -78,6 +79,13 @@ export function JobsDetailHeader({ job, bodyshop, disabled }) {
{job.suspended && ( {job.suspended && (
<PauseCircleOutlined style={{ color: "orangered" }} /> <PauseCircleOutlined style={{ color: "orangered" }} />
)} )}
{job.iouparent && (
<Link to={`/manage/jobs/${job.iouparent}`}>
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{ color: "orangered" }} />
</Tooltip>
</Link>
)}
{job.production_vars && job.production_vars.alert ? ( {job.production_vars && job.production_vars.alert ? (
<ExclamationCircleFilled className="production-alert" /> <ExclamationCircleFilled className="production-alert" />
) : null} ) : null}

View File

@@ -2,9 +2,10 @@ import {
SyncOutlined, SyncOutlined,
ExclamationCircleFilled, ExclamationCircleFilled,
PauseCircleOutlined, PauseCircleOutlined,
BranchesOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { useQuery } from "@apollo/client"; import { useQuery } from "@apollo/client";
import { Button, Card, Grid, Input, Space, Table } from "antd"; import { Button, Card, Grid, Input, Space, Table, Tooltip } from "antd";
import queryString from "query-string"; import queryString from "query-string";
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -128,6 +129,11 @@ export function JobsList({ bodyshop }) {
{record.suspended && ( {record.suspended && (
<PauseCircleOutlined style={{ color: "orangered" }} /> <PauseCircleOutlined style={{ color: "orangered" }} />
)} )}
{record.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{ color: "orangered" }} />
</Tooltip>
)}
</Space> </Space>
</Link> </Link>
), ),

View File

@@ -2,9 +2,10 @@ import {
ExclamationCircleFilled, ExclamationCircleFilled,
PauseCircleOutlined, PauseCircleOutlined,
SyncOutlined, SyncOutlined,
BranchesOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { useQuery } from "@apollo/client"; import { useQuery } from "@apollo/client";
import { Button, Card, Grid, Input, Space, Table } from "antd"; import { Button, Card, Grid, Input, Space, Table, Tooltip } from "antd";
import queryString from "query-string"; import queryString from "query-string";
import React, { useMemo, useState } from "react"; import React, { useMemo, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -140,6 +141,11 @@ export function JobsReadyList({ bodyshop }) {
{record.suspended && ( {record.suspended && (
<PauseCircleOutlined style={{ color: "orangered" }} /> <PauseCircleOutlined style={{ color: "orangered" }} />
)} )}
{record.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{ color: "orangered" }} />
</Tooltip>
)}
</Space> </Space>
</Link> </Link>
), ),

View File

@@ -72,7 +72,8 @@ export function PartsOrderListTableComponent({
? bpoints[selectedBreakpoint[0]] ? bpoints[selectedBreakpoint[0]]
: "100%"; : "100%";
const responsibilityCenters = bodyshop.md_responsibility_centers; const responsibilityCenters = bodyshop.md_responsibility_centers;
const Templates = TemplateList("partsorder"); const Templates = TemplateList("partsorder", { job });
const { t } = useTranslation(); const { t } = useTranslation();
const [state, setState] = useState({ const [state, setState] = useState({
sortedInfo: {}, sortedInfo: {},

View File

@@ -3,8 +3,9 @@ import {
EyeFilled, EyeFilled,
DownloadOutlined, DownloadOutlined,
PauseCircleOutlined, PauseCircleOutlined,
BranchesOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { Card, Col, Row, Space } from "antd"; import { Card, Col, Row, Space, Tooltip } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
@@ -63,6 +64,11 @@ export default function ProductionBoardCard(
{card.suspended && ( {card.suspended && (
<PauseCircleOutlined style={{ color: "orangered" }} /> <PauseCircleOutlined style={{ color: "orangered" }} />
)} )}
{card.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{ color: "orangered" }} />
</Tooltip>
)}
<span style={{ fontWeight: "bolder" }}> <span style={{ fontWeight: "bolder" }}>
<Link <Link
to={ to={

View File

@@ -1,5 +1,5 @@
import { PauseCircleOutlined } from "@ant-design/icons"; import { PauseCircleOutlined, BranchesOutlined } from "@ant-design/icons";
import { Space } from "antd"; import { Space, Tooltip } from "antd";
import i18n from "i18next"; import i18n from "i18next";
import moment from "moment"; import moment from "moment";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
@@ -61,6 +61,11 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => {
{record.suspended && ( {record.suspended && (
<PauseCircleOutlined style={{ color: "orangered" }} /> <PauseCircleOutlined style={{ color: "orangered" }} />
)} )}
{record.iouparent && (
<Tooltip title={i18n.t("jobs.labels.iou")}>
<BranchesOutlined style={{ color: "orangered" }} />
</Tooltip>
)}
</Space> </Space>
</Link> </Link>
), ),

View File

@@ -6,6 +6,7 @@ export const QUERY_ALL_ACTIVE_JOBS = gql`
where: { status: { _in: $statuses } } where: { status: { _in: $statuses } }
order_by: { created_at: desc } order_by: { created_at: desc }
) { ) {
iouparent
ownr_fn ownr_fn
ownr_ln ownr_ln
ownr_co_nm ownr_co_nm
@@ -109,6 +110,7 @@ export const QUERY_EXACT_JOB_IN_PRODUCTION = gql`
query QUERY_EXACT_JOB_IN_PRODUCTION($id: uuid!) { query QUERY_EXACT_JOB_IN_PRODUCTION($id: uuid!) {
jobs(where: { id: { _eq: $id } }) { jobs(where: { id: { _eq: $id } }) {
id id
iouparent
status status
ro_number ro_number
comment comment
@@ -187,6 +189,7 @@ export const QUERY_EXACT_JOBS_IN_PRODUCTION = gql`
query QUERY_EXACT_JOBS_IN_PRODUCTION($ids: [uuid!]!) { query QUERY_EXACT_JOBS_IN_PRODUCTION($ids: [uuid!]!) {
jobs(where: { id: { _in: $ids } }) { jobs(where: { id: { _in: $ids } }) {
id id
iouparent
status status
ro_number ro_number
comment comment
@@ -269,6 +272,7 @@ export const QUERY_JOBS_IN_PRODUCTION = gql`
comment comment
status status
category category
iouparent
ro_number ro_number
ownr_fn ownr_fn
ownr_ln ownr_ln
@@ -609,6 +613,7 @@ export const GET_JOB_BY_PK = gql`
materials materials
auto_add_ats auto_add_ats
rate_ats rate_ats
iouparent
owner { owner {
id id
ownr_fn ownr_fn

View File

@@ -195,6 +195,7 @@
"entered_total": "Total of Entered Lines", "entered_total": "Total of Entered Lines",
"enteringcreditmemo": "You are entering a credit memo. Please ensure you are also entering positive values.", "enteringcreditmemo": "You are entering a credit memo. Please ensure you are also entering positive values.",
"federal_tax": "Federal Tax", "federal_tax": "Federal Tax",
"generatepartslabel": "Generate Parts Labels after Saving?",
"iouexists": "An IOU exists that is associated to this RO.", "iouexists": "An IOU exists that is associated to this RO.",
"local_tax": "Local Tax", "local_tax": "Local Tax",
"markexported": "Mark Exported", "markexported": "Mark Exported",
@@ -1552,6 +1553,7 @@
"adjustments": "Adjustments", "adjustments": "Adjustments",
"adminwarning": "Use the functionality on this page at your own risk. You are responsible for any and all changes to your data.", "adminwarning": "Use the functionality on this page at your own risk. You are responsible for any and all changes to your data.",
"allocations": "Allocations", "allocations": "Allocations",
"alreadyaddedtoscoreboard": "Job has already been added to scoreboard. Saving will update the previous entry.",
"alreadyclosed": "This job has already been closed.", "alreadyclosed": "This job has already been closed.",
"appointmentconfirmation": "Send confirmation to customer?", "appointmentconfirmation": "Send confirmation to customer?",
"associationwarning": "Any changes to associations will require updating the data from the new parent record to the job.", "associationwarning": "Any changes to associations will require updating the data from the new parent record to the job.",
@@ -1639,6 +1641,7 @@
"importnote": "The job was initially imported.", "importnote": "The job was initially imported.",
"inproduction": "In Production", "inproduction": "In Production",
"intakechecklist": "Intake Checklist", "intakechecklist": "Intake Checklist",
"iou": "IOU",
"job": "Job Details", "job": "Job Details",
"jobcosting": "Job Costing", "jobcosting": "Job Costing",
"jobtotals": "Job Totals", "jobtotals": "Job Totals",

View File

@@ -195,6 +195,7 @@
"entered_total": "", "entered_total": "",
"enteringcreditmemo": "", "enteringcreditmemo": "",
"federal_tax": "", "federal_tax": "",
"generatepartslabel": "",
"iouexists": "", "iouexists": "",
"local_tax": "", "local_tax": "",
"markexported": "", "markexported": "",
@@ -1552,6 +1553,7 @@
"adjustments": "", "adjustments": "",
"adminwarning": "", "adminwarning": "",
"allocations": "", "allocations": "",
"alreadyaddedtoscoreboard": "",
"alreadyclosed": "", "alreadyclosed": "",
"appointmentconfirmation": "¿Enviar confirmación al cliente?", "appointmentconfirmation": "¿Enviar confirmación al cliente?",
"associationwarning": "", "associationwarning": "",
@@ -1639,6 +1641,7 @@
"importnote": "", "importnote": "",
"inproduction": "", "inproduction": "",
"intakechecklist": "", "intakechecklist": "",
"iou": "",
"job": "", "job": "",
"jobcosting": "", "jobcosting": "",
"jobtotals": "", "jobtotals": "",

View File

@@ -195,6 +195,7 @@
"entered_total": "", "entered_total": "",
"enteringcreditmemo": "", "enteringcreditmemo": "",
"federal_tax": "", "federal_tax": "",
"generatepartslabel": "",
"iouexists": "", "iouexists": "",
"local_tax": "", "local_tax": "",
"markexported": "", "markexported": "",
@@ -1552,6 +1553,7 @@
"adjustments": "", "adjustments": "",
"adminwarning": "", "adminwarning": "",
"allocations": "", "allocations": "",
"alreadyaddedtoscoreboard": "",
"alreadyclosed": "", "alreadyclosed": "",
"appointmentconfirmation": "Envoyer une confirmation au client?", "appointmentconfirmation": "Envoyer une confirmation au client?",
"associationwarning": "", "associationwarning": "",
@@ -1639,6 +1641,7 @@
"importnote": "", "importnote": "",
"inproduction": "", "inproduction": "",
"intakechecklist": "", "intakechecklist": "",
"iou": "",
"job": "", "job": "",
"jobcosting": "", "jobcosting": "",
"jobtotals": "", "jobtotals": "",

View File

@@ -510,6 +510,12 @@ export const TemplateList = (type, context) => {
key: "parts_label_multiple", key: "parts_label_multiple",
disabled: false, disabled: false,
}, },
parts_invoice_label_single: {
title: i18n.t("printcenter.jobs.parts_invoice_label_single"),
description: "Parts Label Multiple",
key: "parts_invoice_label_single",
disabled: false,
},
csi_invitation_action: { csi_invitation_action: {
title: i18n.t("printcenter.jobs.csi_invitation_action"), title: i18n.t("printcenter.jobs.csi_invitation_action"),
description: "CSI invite", description: "CSI invite",

View File

@@ -479,9 +479,7 @@ exports.default = function ({
}, },
bodyshop.md_responsibility_centers.sales_tax_codes bodyshop.md_responsibility_centers.sales_tax_codes
); );
const account = responsibilityCenters.profits.find(
(c) => c.name === responsibilityCenters.defaults.profits["PAO"]
);
const QboTaxId = taxCodes[taxAccountCode]; const QboTaxId = taxCodes[taxAccountCode];
InvoiceLineAdd.push({ InvoiceLineAdd.push({
DetailType: "SalesItemLineDetail", DetailType: "SalesItemLineDetail",
@@ -493,7 +491,7 @@ exports.default = function ({
? { ClassRef: { value: classes[jobs_by_pk.class] } } ? { ClassRef: { value: classes[jobs_by_pk.class] } }
: {}), : {}),
ItemRef: { ItemRef: {
value: items[account.accountitem], value: items[responsibilityCenters.refund.accountitem],
}, },
TaxCodeRef: { TaxCodeRef: {
value: QboTaxId, value: QboTaxId,
@@ -504,9 +502,7 @@ exports.default = function ({
} else { } else {
InvoiceLineAdd.push({ InvoiceLineAdd.push({
ItemRef: { ItemRef: {
FullName: responsibilityCenters.profits.find( FullName: responsibilityCenters.refund.accountitem,
(c) => c.name === responsibilityCenters.defaults.profits["PAO"]
).accountitem,
}, },
Desc: "Adjustment", Desc: "Adjustment",
Quantity: 1, Quantity: 1,