diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 207a52a84..eb4440d6e 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -1474,6 +1474,27 @@ + + admin_jobuninvoice + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + admin_jobunvoid false @@ -3571,6 +3592,27 @@ validation + + closingperiod + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + inventoryquantity false @@ -4205,6 +4247,27 @@ + + closingperiod + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + country false @@ -23710,6 +23773,27 @@ + + date_void + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + ded_amt false @@ -28490,6 +28574,27 @@ + + closingperiod + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + contracts false @@ -36032,6 +36137,27 @@ errors + + accepting + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + creating false @@ -40888,6 +41014,27 @@ + + parts_return_slip + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + sublet_order false @@ -44739,6 +44886,27 @@ + + work_in_progress_jobs + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + work_in_progress_labour false diff --git a/client/src/components/job-detail-lines/job-lines-expander.component.jsx b/client/src/components/job-detail-lines/job-lines-expander.component.jsx index 06e00c729..b64924210 100644 --- a/client/src/components/job-detail-lines/job-lines-expander.component.jsx +++ b/client/src/components/job-detail-lines/job-lines-expander.component.jsx @@ -8,7 +8,18 @@ import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateFormatter } from "../../utils/DateFormatter"; import AlertComponent from "../alert/alert.component"; -export default function JobLinesExpander({ jobline, jobid }) { +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop, +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) +}); +export default connect(mapStateToProps, mapDispatchToProps)(JobLinesExpander); + +export function JobLinesExpander({ jobline, jobid, bodyshop }) { const { t } = useTranslation(); const { loading, error, data } = useQuery(GET_JOB_LINE_ORDERS, { fetchPolicy: "network-only", @@ -23,7 +34,7 @@ export default function JobLinesExpander({ jobline, jobid }) { return ( - + {t("parts_orders.labels.parts_orders")} @@ -49,7 +60,7 @@ export default function JobLinesExpander({ jobline, jobid }) { )} - + {t("bills.labels.bills")} {data.billlines.length > 0 ? ( @@ -71,7 +82,7 @@ export default function JobLinesExpander({ jobline, jobid }) { - {`${t("billlines.fields.actual_cost")}: `} + {`${t("billlines.fields.actual_cost")}: `} {line.actual_cost} @@ -89,6 +100,37 @@ export default function JobLinesExpander({ jobline, jobid }) { )} + + + {t("parts_dispatch.labels.parts_dispatch")} + + + {data.parts_dispatch_lines.length > 0 ? ( + data.parts_dispatch_lines.map((line) => ( + + } wrap> + + {line.parts_dispatch.number} + + { + bodyshop.employees.find( + (e) => e.id === line.parts_dispatch.employeeid + )?.first_name + } + + {t("parts_dispatch_lines.fields.accepted_at")} + {line.accepted_at} + + + + )) + ) : ( + + {t("parts_orders.labels.notyetordered")} + + )} + + ); } diff --git a/client/src/components/job-line-location-popup/job-line-location-popup.component.jsx b/client/src/components/job-line-location-popup/job-line-location-popup.component.jsx index 16bb32fed..312506511 100644 --- a/client/src/components/job-line-location-popup/job-line-location-popup.component.jsx +++ b/client/src/components/job-line-location-popup/job-line-location-popup.component.jsx @@ -1,4 +1,4 @@ -import { notification, Select } from "antd"; +import { notification, Select, Space } from "antd"; import React, { useEffect, useState } from "react"; import { useMutation } from "@apollo/client"; import { useTranslation } from "react-i18next"; @@ -75,7 +75,10 @@ export function JobLineLocationPopup({ bodyshop, jobline, disabled }) { style={{ width: "100%", minHeight: "2rem", cursor: "pointer" }} onClick={() => !disabled && setEditing(true)} > - {jobline.location} + + {jobline.location} + {jobline.parts_dispatch_lines.length > 0 && "-Disp"} + ); } diff --git a/client/src/components/parts-dispatch-expander/parts-dispatch-expander.component.jsx b/client/src/components/parts-dispatch-expander/parts-dispatch-expander.component.jsx index 131fd7802..26130bf50 100644 --- a/client/src/components/parts-dispatch-expander/parts-dispatch-expander.component.jsx +++ b/client/src/components/parts-dispatch-expander/parts-dispatch-expander.component.jsx @@ -1,10 +1,35 @@ -import { Button, Card, Col, Row, Table } from "antd"; +import { useMutation } from "@apollo/client"; +import { Button, Card, Col, Row, Table, notification } from "antd"; +import moment from "moment-business-days"; import React from "react"; import { useTranslation } from "react-i18next"; +import { UPDATE_PARTS_DISPATCH_LINE } from "../../graphql/parts-dispatch.queries"; import { DateTimeFormatter } from "../../utils/DateFormatter"; export default function PartsDispatchExpander({ dispatch, job }) { const { t } = useTranslation(); + const [updateDispatchLine] = useMutation(UPDATE_PARTS_DISPATCH_LINE); + + const handleAccept = async ({ partsDispatchLineId }) => { + const accepted_at = moment(); + const result = await updateDispatchLine({ + variables: { id: partsDispatchLineId, line: { accepted_at } }, + optimisticResponse: { + update_parts_dispatch_lines_by_pk: { + accepted_at, + id: partsDispatchLineId, + }, + }, + }); + if (result.errors) { + notification.open({ + type: "error", + message: t("parts_dispatch.errors.accepting", { + error: JSON.stringify(result.errors), + }), + }); + } + }; const columns = [ { @@ -32,7 +57,11 @@ export default function PartsDispatchExpander({ dispatch, job }) { record.accepted_at ? ( {record.accepted_at} ) : ( - + ), }, ]; diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index 7bb943162..00ec87252 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -2149,6 +2149,18 @@ export const GET_JOB_LINE_ORDERS = gql` } } } + parts_dispatch_lines(where: { joblineid: { _eq: $joblineid } }) { + id + accepted_at + quantity + parts_dispatch { + id + employeeid + dispatched_at + dispatched_by + number + } + } parts_order_lines(where: { job_line_id: { _eq: $joblineid } }) { id act_price diff --git a/client/src/graphql/parts-dispatch.queries.js b/client/src/graphql/parts-dispatch.queries.js index d4f5e940b..eafb1d7c0 100644 --- a/client/src/graphql/parts-dispatch.queries.js +++ b/client/src/graphql/parts-dispatch.queries.js @@ -54,6 +54,7 @@ export const GET_UNACCEPTED_PARTS_DISPATCH = gql` dispatched_by parts_dispatch_lines { id + accepted_at jobline { line_desc id @@ -64,3 +65,15 @@ export const GET_UNACCEPTED_PARTS_DISPATCH = gql` } } `; + +export const UPDATE_PARTS_DISPATCH_LINE = gql` + mutation UPDATE_PARTS_DISPATCH_LINE( + $id: uuid! + $line: parts_dispatch_lines_set_input! + ) { + update_parts_dispatch_lines_by_pk(pk_columns: { id: $id }, _set: $line) { + accepted_at + id + } + } +`; diff --git a/client/src/pages/tech-dispatched-parts/tech-dispatched-parts.page.jsx b/client/src/pages/tech-dispatched-parts/tech-dispatched-parts.page.jsx index d87b5a9ad..9508b8bad 100644 --- a/client/src/pages/tech-dispatched-parts/tech-dispatched-parts.page.jsx +++ b/client/src/pages/tech-dispatched-parts/tech-dispatched-parts.page.jsx @@ -4,9 +4,9 @@ import { SyncOutlined, } from "@ant-design/icons"; import { useQuery } from "@apollo/client"; -import { Button, Card, Input, Space, Table } from "antd"; +import { Button, Card, Space, Table } from "antd"; import queryString from "query-string"; -import React, { useState } from "react"; +import React from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { useHistory, useLocation } from "react-router-dom"; diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 55ac3b850..1649a7387 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -2141,6 +2141,7 @@ "accept": "Accept" }, "errors": { + "accepting": "Error accepting parts dispatch. {{error}}", "creating": "Error dispatching parts. {{error}}" }, "fields": { @@ -2433,7 +2434,7 @@ "jobs": { "individual_job_note": "Job Note RO: {{ro_number}}", "parts_order": "Parts Order PO: {{ro_number}} - {{name}}", - "parts_return_slip":"Parts Return PO: {{ro_number}} - {{name}}", + "parts_return_slip": "Parts Return PO: {{ro_number}} - {{name}}", "sublet_order": "Sublet Order PO: {{ro_number}} - {{name}}" } }, diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 03b36ef94..b42056762 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -2141,6 +2141,7 @@ "accept": "" }, "errors": { + "accepting": "", "creating": "" }, "fields": { diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 0d16c4e16..a7a45d1a4 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -2141,6 +2141,7 @@ "accept": "" }, "errors": { + "accepting": "", "creating": "" }, "fields": {