diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index c905978c4..61ce03247 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -28335,6 +28335,27 @@ + + pimraryamountpayable + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + plitooltips @@ -35325,6 +35346,27 @@ + + external + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + findermodal false diff --git a/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx b/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx index 70c4703ff..956cb4761 100644 --- a/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx +++ b/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx @@ -7,7 +7,10 @@ import { connect } from "react-redux"; import { useHistory, useLocation, useParams } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import { logImEXEvent } from "../../../../firebase/firebase.utils"; -import { MARK_LATEST_APPOINTMENT_AS_ARRIVED } from "../../../../graphql/appointments.queries"; +import { + MARK_APPOINTMENT_ARRIVED, + MARK_LATEST_APPOINTMENT_ARRIVED, +} from "../../../../graphql/appointments.queries"; import { UPDATE_JOB } from "../../../../graphql/jobs.queries"; import { selectBodyshop, @@ -41,7 +44,8 @@ export function JobChecklistForm({ const { t } = useTranslation(); const [intakeJob] = useMutation(UPDATE_JOB); const [loading, setLoading] = useState(false); - const [markAptArrived] = useMutation(MARK_LATEST_APPOINTMENT_AS_ARRIVED); + const [markAptArrived] = useMutation(MARK_APPOINTMENT_ARRIVED); + const [markLatestAptArrived] = useMutation(MARK_LATEST_APPOINTMENT_ARRIVED); const [updateOwner] = useMutation(UPDATE_OWNER); const { jobId } = useParams(); @@ -125,6 +129,18 @@ export function JobChecklistForm({ variables: { appointmentId: search.appointmentId }, }); + if (!!appUpdate.errors) { + notification["error"]({ + message: t("checklist.errors.complete", { + error: JSON.stringify(result.errors), + }), + }); + } + } else if (type === "intake" && !search.appointmentId) { + const appUpdate = await markLatestAptArrived({ + variables: { jobId: jobId }, + }); + if (!!appUpdate.errors) { notification["error"]({ message: t("checklist.errors.complete", { @@ -133,6 +149,7 @@ export function JobChecklistForm({ }); } } + if (type === "intake" && job.owner && job.owner.id) { //Updae Owner Allow to Text const updateOwnerResult = await updateOwner({ @@ -175,12 +192,7 @@ export function JobChecklistForm({ }); } }; - console.log(job, { - removeFromProduction: true, - actual_completion: - job && job.actual_completion && moment(job.actual_completion), - actual_delivery: job && job.actual_delivery && moment(job.actual_delivery), - }); + return ( {t("jobs.labels.multipayers")} {Qb_Multi_Ar.treatment === "on" && ( - - ({ - validator(_, value) { - let totalAllocated = Dinero(); + + + ({ + validator(_, value) { + let totalAllocated = Dinero(); - const payers = form.getFieldValue("qb_multiple_payers"); - payers && - payers.forEach((payer) => { - totalAllocated = totalAllocated.add( - Dinero({ - amount: Math.round((payer?.amount || 0) * 100), - }) - ); - }); - const discrep = job.job_totals - ? Dinero(job.job_totals.totals.total_repairs).subtract( - totalAllocated - ) - : Dinero(); - return discrep.getAmount() > 0 - ? Promise.resolve() - : Promise.reject( - new Error( - t("jobs.labels.additionalpayeroverallocation") + const payers = form.getFieldValue("qb_multiple_payers"); + payers && + payers.forEach((payer) => { + totalAllocated = totalAllocated.add( + Dinero({ + amount: Math.round((payer?.amount || 0) * 100), + }) + ); + }); + const discrep = job.job_totals + ? Dinero(job.job_totals.totals.total_repairs).subtract( + totalAllocated ) - ); - }, - }), - ]} - > - {(fields, { add, remove }) => { - return ( -
- {fields.map((field, index) => ( - - - - - + + - - - + + + - { - remove(field.name); - }} - /> - + { + remove(field.name); + }} + /> + + + ))} + + - ))} - - - -
- ); - }} -
- - {() => { - //Perform Calculation to determine discrepancy. - let totalAllocated = Dinero(); + + ); + }} +
+ + + + {() => { + //Perform Calculation to determine discrepancy. + let totalAllocated = Dinero(); - const payers = form.getFieldValue("qb_multiple_payers"); - payers && - payers.forEach((payer) => { - totalAllocated = totalAllocated.add( - Dinero({ amount: Math.round((payer?.amount || 0) * 100) }) - ); - }); - const discrep = job.job_totals - ? Dinero(job.job_totals.totals.total_repairs).subtract( - totalAllocated - ) - : Dinero(); - return ( - - - - - - = - 0 ? "green" : "red", - }} - value={discrep.toFormat()} - /> - - ); - }} - -
+ const payers = form.getFieldValue("qb_multiple_payers"); + payers && + payers.forEach((payer) => { + totalAllocated = totalAllocated.add( + Dinero({ + amount: Math.round((payer?.amount || 0) * 100), + }) + ); + }); + const discrep = job.job_totals + ? Dinero(job.job_totals.totals.total_repairs).subtract( + totalAllocated + ) + : Dinero(); + return ( + + + + + - + + = + 0 ? "green" : "red", + }} + value={discrep.toFormat()} + /> + + ); + }} + + + )} diff --git a/client/src/pages/parts-queue/parts-queue.page.component.jsx b/client/src/pages/parts-queue/parts-queue.page.component.jsx index c9725a905..5d6226bdb 100644 --- a/client/src/pages/parts-queue/parts-queue.page.component.jsx +++ b/client/src/pages/parts-queue/parts-queue.page.component.jsx @@ -1,6 +1,7 @@ import { SyncOutlined } from "@ant-design/icons"; import { useQuery } from "@apollo/client"; import { Button, Card, Input, Space, Table } from "antd"; +import _ from "lodash"; import queryString from "query-string"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -14,7 +15,6 @@ import OwnerNameDisplay from "../../components/owner-name-display/owner-name-dis import ProductionListColumnComment from "../../components/production-list-columns/production-list-columns.comment.component"; import { QUERY_PARTS_QUEUE } from "../../graphql/jobs.queries"; import { selectBodyshop } from "../../redux/user/user.selectors"; -import { onlyUnique } from "../../utils/arrayHelper"; import { DateTimeFormatter, TimeAgoFormatter } from "../../utils/DateFormatter"; import { alphaSort, dateSort } from "../../utils/sorters"; import useLocalStorage from "../../utils/useLocalStorage"; @@ -94,6 +94,14 @@ export function PartsQueuePageComponent({ bodyshop }) { // searchParams.page = pagination.current; searchParams.sortcolumn = sorter.columnKey; searchParams.sortorder = sorter.order; + + if (filters.status) { + searchParams.statusFilters = JSON.stringify( + _.flattenDeep(filters.status) + ); + } else { + delete searchParams.statusFilters; + } setFilter(filters); history.push({ search: queryString.stringify(searchParams) }); }; @@ -136,19 +144,14 @@ export function PartsQueuePageComponent({ bodyshop }) { key: "status", sorter: (a, b) => alphaSort(a.status, b.status), sortOrder: sortcolumn === "status" && sortorder, + filteredValue: statusFilters ? JSON.parse(statusFilters) : null, filters: - (jobs && - jobs - .map((j) => j.status) - .filter(onlyUnique) - .map((s) => { - return { - text: s || "No Status*", - value: [s], - }; - })) || - [], - onFilter: (value, record) => value.includes(record.status), + bodyshop.md_ro_statuses.active_statuses.map((s) => { + return { + text: s || "No Status*", + value: [s], + }; + }) || [], render: (text, record) => { return record.status || t("general.labels.na"); }, diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 3570e04dc..ea078dada 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -1662,6 +1662,7 @@ "partsfilter": "Parts Only", "partssubletstotal": "Parts & Sublets Total", "partstotal": "Parts Total (ex. Taxes)", + "pimraryamountpayable": "Total Primary Payable", "plitooltips": { "billtotal": "The total amount of all bill lines that have been posted against this RO (not including credits, taxes, or labor adjustments).", "calculatedcreditsnotreceived": "The calculated credits not received is derived by subtracting the amount of credit memos entered from the retail total of returns created. This does not take into account whether the credit was marked as received. You can find more information here.", @@ -2090,6 +2091,7 @@ "customer": "Customer", "edit": "Edit Payment", "electronicpayment": "Use Electronic Payment Processing?", + "external": "External", "findermodal": "ICBC Payment Finder", "insurance": "Insurance", "new": "New Payment", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 919e650e9..a479d3208 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -1662,6 +1662,7 @@ "partsfilter": "", "partssubletstotal": "", "partstotal": "", + "pimraryamountpayable": "", "plitooltips": { "billtotal": "", "calculatedcreditsnotreceived": "", @@ -2090,6 +2091,7 @@ "customer": "", "edit": "", "electronicpayment": "", + "external": "", "findermodal": "", "insurance": "", "new": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 82294d431..7f8077f2e 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -1662,6 +1662,7 @@ "partsfilter": "", "partssubletstotal": "", "partstotal": "", + "pimraryamountpayable": "", "plitooltips": { "billtotal": "", "calculatedcreditsnotreceived": "", @@ -2090,6 +2091,7 @@ "customer": "", "edit": "", "electronicpayment": "", + "external": "", "findermodal": "", "insurance": "", "new": "",