From eb8e9b10ef5a5ab4179ced1602601b29ed81bb99 Mon Sep 17 00:00:00 2001 From: Allan Carr Date: Wed, 14 Feb 2024 16:47:25 -0800 Subject: [PATCH] IO-2631 Update Scheduled Completion on Supp --- .../jobs-available-table.container.jsx | 48 +++++-- .../jobs-detail-header.component.jsx | 4 +- .../jobs-find-modal.component.jsx | 133 +++++++++++++++--- .../jobs-find-modal.container.jsx | 4 + client/src/translations/en_us/common.json | 2 + client/src/translations/es/common.json | 2 + client/src/translations/fr/common.json | 2 + 7 files changed, 165 insertions(+), 30 deletions(-) diff --git a/client/src/components/jobs-available-table/jobs-available-table.container.jsx b/client/src/components/jobs-available-table/jobs-available-table.container.jsx index 12d10baf9..54920ec91 100644 --- a/client/src/components/jobs-available-table/jobs-available-table.container.jsx +++ b/client/src/components/jobs-available-table/jobs-available-table.container.jsx @@ -6,7 +6,7 @@ import { useQuery, } from "@apollo/client"; import { useTreatments } from "@splitsoftware/splitio-react"; -import { Col, notification, Row } from "antd"; +import { Col, Row, notification } from "antd"; import Axios from "axios"; import Dinero from "dinero.js"; import moment from "moment"; @@ -30,8 +30,8 @@ import { selectBodyshop, selectCurrentUser, } from "../../redux/user/user.selectors"; -import confirmDialog from "../../utils/asyncConfirm"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import confirmDialog from "../../utils/asyncConfirm"; import CriticalPartsScan from "../../utils/criticalPartsScan"; import AlertComponent from "../alert/alert.component"; import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component"; @@ -73,7 +73,15 @@ export function JobsAvailableContainer({ const [selectedJob, setSelectedJob] = useState(null); const [selectedOwner, setSelectedOwner] = useState(null); - const [partsQueueToggle, setPartsQueueToggle] = useState(bodyshop.md_functionality_toggles.parts_queue_toggle); + const [partsQueueToggle, setPartsQueueToggle] = useState( + bodyshop.md_functionality_toggles.parts_queue_toggle + ); + const [updateSchComp, setSchComp] = useState({ + actual_in: moment(), + checked: false, + scheduled_completion: moment(), + automatic: false, + }); const [insertLoading, setInsertLoading] = useState(false); @@ -197,11 +205,16 @@ export function JobsAvailableContainer({ notification["error"]({ message: t("jobs.errors.creating", { error: err.message }), }); - refetch().catch(e => {console.error(`Something went wrong in jobs available table container - ${err.message || ''}`)}); + refetch().catch((e) => { + console.error( + `Something went wrong in jobs available table container - ${ + err.message || "" + }` + ); + }); setInsertLoading(false); setPartsQueueToggle(bodyshop.md_functionality_toggles.parts_queue_toggle); } - }; //Supplement scenario @@ -225,6 +238,23 @@ export function JobsAvailableContainer({ //IO-539 Check for Parts Rate on PAL for SGI use case. await CheckTaxRates(supp, bodyshop); + if (updateSchComp.checked === true) { + if (updateSchComp.automatic === true) { + const job_hrs = supp.joblines.data.reduce( + (acc, val) => acc + val.mod_lb_hrs, + 0 + ); + const num_days = job_hrs / bodyshop.target_touchtime; + supp.actual_in = updateSchComp.actual_in; + supp.scheduled_completion = moment(updateSchComp.actual_in).add( + num_days, + "days" + ); + } else { + supp.scheduled_completion = updateSchComp.scheduled_completion; + } + } + delete supp.owner; delete supp.vehicle; delete supp.ins_co_nm; @@ -261,9 +291,9 @@ export function JobsAvailableContainer({ }, }); - setPartsQueueToggle(bodyshop.md_functionality_toggles.parts_queue_toggle); + setPartsQueueToggle(bodyshop.md_functionality_toggles.parts_queue_toggle); - if (CriticalPartsScanning.treatment === "on") { + if (CriticalPartsScanning.treatment === "on") { CriticalPartsScan(updateResult.data.update_jobs.returning[0].id); } if (updateResult.errors) { @@ -367,7 +397,6 @@ export function JobsAvailableContainer({ if (error) return ; - return ( diff --git a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx index 7c58eda52..40c7aa4db 100644 --- a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx +++ b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx @@ -131,12 +131,10 @@ export function JobsDetailHeader({ job, bodyshop, disabled }) { ))} )} - - - + {job.special_coverage_policy && ( diff --git a/client/src/components/jobs-find-modal/jobs-find-modal.component.jsx b/client/src/components/jobs-find-modal/jobs-find-modal.component.jsx index 37a88e1ef..7616377f0 100644 --- a/client/src/components/jobs-find-modal/jobs-find-modal.component.jsx +++ b/client/src/components/jobs-find-modal/jobs-find-modal.component.jsx @@ -1,9 +1,11 @@ import { SyncOutlined } from "@ant-design/icons"; -import { Checkbox, Divider, Input, Table, Button } from "antd"; -import React from "react"; +import { Button, Checkbox, Divider, Input, Space, Table } from "antd"; +import moment from "moment"; +import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import PhoneFormatter from "../../utils/PhoneFormatter"; +import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component"; import OwnerNameDisplay from "../owner-name-display/owner-name-display.component"; export default function JobsFindModalComponent({ @@ -16,11 +18,13 @@ export default function JobsFindModalComponent({ jobsListRefetch, partsQueueToggle, setPartsQueueToggle, + updateSchComp, + setSchComp, }) { const { t } = useTranslation(); const [modalSearch, setModalSearch] = modalSearchState; const [importOptions, setImportOptions] = importOptionsState; - + const [checkUTT, setCheckUTT] = useState(false); const columns = [ { title: t("jobs.fields.ro_number"), @@ -142,6 +146,35 @@ export default function JobsFindModalComponent({ if (record) { if (record.id) { setSelectedJob(record.id); + if (record.actual_in && record.scheduled_completion) { + setSchComp({ + ...updateSchComp, + actual_in: record.actual_in, + scheduled_completion: record.scheduled_completion, + }); + } else { + if (record.actual_in && !record.scheduled_completion) { + setSchComp({ + ...updateSchComp, + actual_in: record.actual_in, + scheduled_completion: moment(), + }); + } + if (!record.actual_in && record.scheduled_completion) { + setSchComp({ + ...updateSchComp, + actual_in: moment(), + scheduled_completion: moment(record.scheduled_completion), + }); + } + if (!record.actual_in && !record.scheduled_completion) { + setSchComp({ + ...updateSchComp, + actual_in: moment(), + scheduled_completion: moment(), + }); + } + } return; } } @@ -177,6 +210,35 @@ export default function JobsFindModalComponent({ rowSelection={{ onSelect: (props) => { setSelectedJob(props.id); + if (props.actual_in && props.scheduled_completion) { + setSchComp({ + ...updateSchComp, + actual_in: props.actual_in, + scheduled_completion: props.scheduled_completion, + }); + } else { + if (props.actual_in && !props.scheduled_completion) { + setSchComp({ + ...updateSchComp, + actual_in: props.actual_in, + scheduled_completion: moment(), + }); + } + if (!props.actual_in && props.scheduled_completion) { + setSchComp({ + ...updateSchComp, + actual_in: moment(), + scheduled_completion: moment(props.scheduled_completion), + }); + } + if (!props.actual_in && !props.scheduled_completion) { + setSchComp({ + ...updateSchComp, + actual_in: moment(), + scheduled_completion: moment(), + }); + } + } }, type: "radio", selectedRowKeys: [selectedJob], @@ -190,23 +252,58 @@ export default function JobsFindModalComponent({ }} /> - - setImportOptions({ - ...importOptions, - overrideHeaders: e.target.checked, - }) - } - > - {t("jobs.labels.override_header")} - - + + setImportOptions({ + ...importOptions, + overrideHeaders: e.target.checked, + }) + } + > + {t("jobs.labels.override_header")} + + setPartsQueueToggle(e.target.checked)} - > - {t("bodyshop.fields.md_functionality_toggles.parts_queue_toggle")} - + > + {t("bodyshop.fields.md_functionality_toggles.parts_queue_toggle")} + + + setSchComp({ ...updateSchComp, checked: e.target.checked }) + } + > + {t("jobs.labels.update_scheduled_completion")} + + {updateSchComp.checked === true ? ( + <> + {checkUTT === false ? ( + { + setSchComp({ ...updateSchComp, scheduled_completion: e }); + }} + /> + ) : null} + { + setCheckUTT(e.target.checked); + setSchComp({ + ...updateSchComp, + scheduled_completion: null, + automatic: true, + }); + }} + > + {t("jobs.labels.calc_scheuled_completion")} + + + ) : null} + ); } diff --git a/client/src/components/jobs-find-modal/jobs-find-modal.container.jsx b/client/src/components/jobs-find-modal/jobs-find-modal.container.jsx index 64dc8be9a..e6b4ab25e 100644 --- a/client/src/components/jobs-find-modal/jobs-find-modal.container.jsx +++ b/client/src/components/jobs-find-modal/jobs-find-modal.container.jsx @@ -26,6 +26,8 @@ export default connect( modalSearchState, partsQueueToggle, setPartsQueueToggle, + updateSchComp, + setSchComp, ...modalProps }) { const { t } = useTranslation(); @@ -95,6 +97,8 @@ export default connect( modalSearchState={modalSearchState} partsQueueToggle={partsQueueToggle} setPartsQueueToggle={setPartsQueueToggle} + updateSchComp={updateSchComp} + setSchComp={setSchComp} /> ) : null} diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index af575757c..37244a6b1 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -1732,6 +1732,7 @@ "ca_gst_all_if_null": "If the Job is marked as a \"GST Registrant\" and this value is set to $0, the customer will be responsible for paying all of the GST by default. ", "calc_repair_days": "Calculated Repair Days", "calc_repair_days_tt": "This is the approximate number of days required to complete the repair according to the target touch time in your shop configuration (current set to {{target_touchtime}}).", + "calc_scheuled_completion": "Calculate Scheduled Completion", "cards": { "customer": "Customer Information", "damage": "Area of Damage", @@ -1891,6 +1892,7 @@ "total_sales": "Total Sales", "totals": "Totals", "unvoidnote": "This Job was unvoided.", + "update_scheduled_completion": "Update Scheduled Completion?", "vehicle_info": "Vehicle", "vehicleassociation": "Vehicle Association", "viewallocations": "View Allocations", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 5e57e0911..aefd39986 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -1732,6 +1732,7 @@ "ca_gst_all_if_null": "", "calc_repair_days": "", "calc_repair_days_tt": "", + "calc_scheuled_completion": "", "cards": { "customer": "Información al cliente", "damage": "Área de Daño", @@ -1891,6 +1892,7 @@ "total_sales": "", "totals": "", "unvoidnote": "", + "update_scheduled_completion": "", "vehicle_info": "Vehículo", "vehicleassociation": "", "viewallocations": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 92616ae1c..29a33c94f 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -1732,6 +1732,7 @@ "ca_gst_all_if_null": "", "calc_repair_days": "", "calc_repair_days_tt": "", + "calc_scheuled_completion": "", "cards": { "customer": "Informations client", "damage": "Zone de dommages", @@ -1891,6 +1892,7 @@ "total_sales": "", "totals": "", "unvoidnote": "", + "update_scheduled_completion": "", "vehicle_info": "Véhicule", "vehicleassociation": "", "viewallocations": "",