From 3e8660bb61384ae743ea8623bed1b6edfcccb3c0 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 3 Aug 2023 14:14:01 -0700 Subject: [PATCH 1/2] Validation and confirmation messages. --- bodyshop_translations.babel | 42 ++++++++++++++++ ...or-allocations-table.payroll.component.jsx | 43 ++++++++++++++-- .../tech-sider/tech-sider.component.jsx | 49 +++++++++++-------- .../time-ticket-task-modal.component.jsx | 2 +- .../tech-assigned-prod-jobs.component.jsx | 2 +- client/src/translations/en_us/common.json | 4 +- client/src/translations/es/common.json | 4 +- client/src/translations/fr/common.json | 4 +- server/payroll/pay-all.js | 16 +++--- 9 files changed, 127 insertions(+), 39 deletions(-) diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index c41c57d59..af0d662cb 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -46289,6 +46289,27 @@ + + payall + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + shiftalreadyclockedon false @@ -47249,6 +47270,27 @@ + + payall + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + diff --git a/client/src/components/labor-allocations-table/labor-allocations-table.payroll.component.jsx b/client/src/components/labor-allocations-table/labor-allocations-table.payroll.component.jsx index 0aa62216e..504d0dce6 100644 --- a/client/src/components/labor-allocations-table/labor-allocations-table.payroll.component.jsx +++ b/client/src/components/labor-allocations-table/labor-allocations-table.payroll.component.jsx @@ -1,5 +1,14 @@ -import { Button, Card, Col, Row, Space, Table, Typography } from "antd"; -import { SyncOutlined } from '@ant-design/icons' +import { + Button, + Card, + Col, + Row, + Space, + Table, + Typography, + notification, +} from "antd"; +import { SyncOutlined } from "@ant-design/icons"; import axios from "axios"; import _ from "lodash"; import React, { useEffect, useMemo, useState } from "react"; @@ -225,10 +234,34 @@ export function PayrollLaborAllocationsTable({ } diff --git a/client/src/components/tech-sider/tech-sider.component.jsx b/client/src/components/tech-sider/tech-sider.component.jsx index aaac65512..c53eadee0 100644 --- a/client/src/components/tech-sider/tech-sider.component.jsx +++ b/client/src/components/tech-sider/tech-sider.component.jsx @@ -1,4 +1,8 @@ -import Icon, { SearchOutlined, ScheduleOutlined } from "@ant-design/icons"; +import Icon, { + SearchOutlined, + ScheduleOutlined, + UserAddOutlined, +} from "@ant-design/icons"; import { Layout, Menu } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -68,19 +72,28 @@ export function TechSider({ {t("menus.tech.joblookup")} {Enhanced_Payroll.treatment === "on" ? ( - } - onClick={() => { - setTimeTicketTaskContext({ - actions: {}, - context: { jobid: null }, - }); - }} - > - {t("menus.tech.claimtask")} - + <> + } + > + {t("menus.tech.assignedjobs")} + + } + onClick={() => { + setTimeTicketTaskContext({ + actions: {}, + context: { jobid: null }, + }); + }} + > + {t("menus.tech.claimtask")} + + ) : ( {t("menus.tech.productionboard")} - } - > - {t("menus.tech.assignedjobs")} - + {() => { const { task } = form.getFieldsValue(); - const theTaskPreset = bodyshop.md_tasks_presets.presets.find( + const theTaskPreset = bodyshop.md_tasks_presets?.presets?.find( (tp) => tp.name === task ); diff --git a/client/src/pages/tech-assigned-prod-jobs/tech-assigned-prod-jobs.component.jsx b/client/src/pages/tech-assigned-prod-jobs/tech-assigned-prod-jobs.component.jsx index b971bd368..65b71f409 100644 --- a/client/src/pages/tech-assigned-prod-jobs/tech-assigned-prod-jobs.component.jsx +++ b/client/src/pages/tech-assigned-prod-jobs/tech-assigned-prod-jobs.component.jsx @@ -178,7 +178,7 @@ export function TechAssignedProdJobs({ }, }, { - title: t("jobs.labels.actions"), + title: t("general.labels.actions"), dataIndex: "actions", key: "actions", render: (text, record) => ( diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index b2ce6edf4..73ee81162 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -2746,6 +2746,7 @@ "deleting": "Error deleting time ticket. {{message}}", "noemployeeforuser": "Unable to use Shift Clock", "noemployeeforuser_sub": "An employee record has not been created for this user. Please create one before using the shift clock. ", + "payall": "Error flagging hours. {{error}}", "shiftalreadyclockedon": "You are already clocked onto a shift. Unable to create shift entry." }, "fields": { @@ -2796,7 +2797,8 @@ "clockedout": "Clocked out successfully.", "committed": "Time Tickets Committed Successfully", "created": "Time ticket entered successfully.", - "deleted": "Time ticket deleted successfully." + "deleted": "Time ticket deleted successfully.", + "payall": "All hours paid out successfully." }, "validation": { "clockoffmustbeafterclockon": "Clock off time must be the same or after clock in time.", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 511517aeb..2f8e3997c 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -2746,6 +2746,7 @@ "deleting": "", "noemployeeforuser": "", "noemployeeforuser_sub": "", + "payall": "", "shiftalreadyclockedon": "" }, "fields": { @@ -2796,7 +2797,8 @@ "clockedout": "", "committed": "", "created": "", - "deleted": "" + "deleted": "", + "payall": "" }, "validation": { "clockoffmustbeafterclockon": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index d134b4a6f..eba3149a7 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -2746,6 +2746,7 @@ "deleting": "", "noemployeeforuser": "", "noemployeeforuser_sub": "", + "payall": "", "shiftalreadyclockedon": "" }, "fields": { @@ -2796,7 +2797,8 @@ "clockedout": "", "committed": "", "created": "", - "deleted": "" + "deleted": "", + "payall": "" }, "validation": { "clockoffmustbeafterclockon": "", diff --git a/server/payroll/pay-all.js b/server/payroll/pay-all.js index 81f8ff9d5..935c7d566 100644 --- a/server/payroll/pay-all.js +++ b/server/payroll/pay-all.js @@ -32,7 +32,7 @@ exports.payall = async function (req, res) { const { employeeHash, assignmentHash } = CalculateExpectedHoursForJob(job); const ticketHash = CalculateTicketsHoursForJob(job); if (assignmentHash.unassigned > 0) { - res.json({ success: false, error: "Unassigned hours." }); + res.json({ success: false, error: "Not all hours have been assigned." }); return; } @@ -65,7 +65,7 @@ exports.payall = async function (req, res) { cost_center: job.bodyshop.md_responsibility_centers.defaults.costs[key], flat_rate: true, - memo: `*SYS-PAY* Add unflagged hours. (${req.user.email})`, + memo: `Add unflagged hours. (${req.user.email})`, }); }); } else { @@ -83,7 +83,7 @@ exports.payall = async function (req, res) { job.bodyshop.md_responsibility_centers.defaults.costs[ path.mod_lbr_ty ], - memo: `*SYS-PAY* Add unflagged hours. (${req.user.email})`, + memo: `Add unflagged hours. (${req.user.email})`, }); } } else if (diff.op === "update") { @@ -102,7 +102,7 @@ exports.payall = async function (req, res) { job.bodyshop.md_responsibility_centers.defaults.costs[ path.mod_lbr_ty ], - memo: `*SYS-PAY* Adjust flagged hours per assignment. (${req.user.email})`, + memo: `Adjust flagged hours per assignment. (${req.user.email})`, }); } else { //Has to be a delete @@ -124,7 +124,7 @@ exports.payall = async function (req, res) { cost_center: job.bodyshop.md_responsibility_centers.defaults.costs[key], flat_rate: true, - memo: `*SYS-PAY* Remove flagged hours per assignment. (${req.user.email})`, + memo: `Remove flagged hours per assignment. (${req.user.email})`, }); }); } else { @@ -142,7 +142,7 @@ exports.payall = async function (req, res) { path.mod_lbr_ty ], flat_rate: true, - memo: `*SYS-PAY* Remove flagged hours per assignment. (${req.user.email})`, + memo: `Remove flagged hours per assignment. (${req.user.email})`, }); } } @@ -163,10 +163,10 @@ exports.payall = async function (req, res) { jobid, { jobid: jobid, - error, + error: JSON.stringify(error), } ); - res.status(503).send(); + res.status(400).json({ error: error.message }); } }; From ad7ff62b56a726732a5b1af3d6b8eb9d5cb58a87 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 14 Aug 2023 15:28:10 -0700 Subject: [PATCH 2/2] Shift employee cost centers to follow DMS standard. --- .../shop-employees/shop-employees-form.component.jsx | 9 +++++++-- .../shop-info/shop-info.task-presets.component.jsx | 8 -------- .../tech-job-clock-in-form.component.jsx | 8 +++++++- .../tech-job-clock-in-form.container.jsx | 10 ++++++---- .../tech-job-clock-out-button.component.jsx | 11 ++++++++++- .../time-ticket-modal/time-ticket-modal.component.jsx | 8 +++++++- .../time-ticket-modal/time-ticket-modal.container.jsx | 9 +++++++-- 7 files changed, 44 insertions(+), 19 deletions(-) diff --git a/client/src/components/shop-employees/shop-employees-form.component.jsx b/client/src/components/shop-employees/shop-employees-form.component.jsx index 782c0dff8..3cedf6512 100644 --- a/client/src/components/shop-employees/shop-employees-form.component.jsx +++ b/client/src/components/shop-employees/shop-employees-form.component.jsx @@ -36,6 +36,7 @@ import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import ShopEmployeeAddVacation from "./shop-employees-add-vacation.component"; +import { useTreatments } from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -56,7 +57,11 @@ export function ShopEmployeesFormComponent({ bodyshop }) { fetchPolicy: "network-only", nextFetchPolicy: "network-only", }); - + const { Enhanced_Payroll } = useTreatments( + ["Enhanced_Payroll"], + {}, + bodyshop.imexshopid + ); const client = useApolloClient(); useEffect(() => { if (data && data.employees_by_pk) form.setFieldsValue(data.employees_by_pk); @@ -362,7 +367,7 @@ export function ShopEmployeesFormComponent({ bodyshop }) { {t("timetickets.labels.shift")} - {bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber + {bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatment === "on" ? CiecaSelect(false, true) : bodyshop.md_responsibility_centers.costs.map( (c) => ( diff --git a/client/src/components/shop-info/shop-info.task-presets.component.jsx b/client/src/components/shop-info/shop-info.task-presets.component.jsx index 82d49227d..0ebdf5815 100644 --- a/client/src/components/shop-info/shop-info.task-presets.component.jsx +++ b/client/src/components/shop-info/shop-info.task-presets.component.jsx @@ -143,14 +143,6 @@ export function ShopInfoTaskPresets({ bodyshop, form }) { {t("joblines.fields.lbr_types.LAM")} - - - {t("joblines.fields.lbr_types.LAM")} - - e.id === technician.id)[0]; return (
@@ -53,7 +59,7 @@ export function TechClockInComponent({ form, bodyshop, technician }) { {item.cost_center === "timetickets.labels.shift" ? t(item.cost_center) - : bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber + : bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatment === "on" ? t( `joblines.fields.lbr_types.${item.cost_center.toUpperCase()}` ) diff --git a/client/src/components/tech-job-clock-in-form/tech-job-clock-in-form.container.jsx b/client/src/components/tech-job-clock-in-form/tech-job-clock-in-form.container.jsx index 7754c07f2..838c83851 100644 --- a/client/src/components/tech-job-clock-in-form/tech-job-clock-in-form.container.jsx +++ b/client/src/components/tech-job-clock-in-form/tech-job-clock-in-form.container.jsx @@ -12,6 +12,7 @@ import TechClockInComponent from "./tech-job-clock-in-form.component"; import TechJobPrintTickets from "../tech-job-print-tickets/tech-job-print-tickets.component"; import moment from "moment"; import { setModalContext } from "../../redux/modals/modals.actions"; +import { useTreatments } from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ technician: selectTechnician, @@ -26,9 +27,10 @@ export function TechClockInContainer({ technician, bodyshop, }) { - console.log( - "🚀 ~ file: tech-job-clock-in-form.container.jsx:29 ~ technician:", - technician + const { Enhanced_Payroll } = useTreatments( + ["Enhanced_Payroll"], + {}, + bodyshop.imexshopid ); const [form] = Form.useForm(); const [loading, setLoading] = useState(false); @@ -56,7 +58,7 @@ export function TechClockInContainer({ jobid: values.jobid, cost_center: values.cost_center, ciecacode: - bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber + bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatment === 'on' ? values.cost_center : Object.keys( bodyshop.md_responsibility_centers.defaults.costs diff --git a/client/src/components/tech-job-clock-out-button/tech-job-clock-out-button.component.jsx b/client/src/components/tech-job-clock-out-button/tech-job-clock-out-button.component.jsx index d1c5c3528..321ef903d 100644 --- a/client/src/components/tech-job-clock-out-button/tech-job-clock-out-button.component.jsx +++ b/client/src/components/tech-job-clock-out-button/tech-job-clock-out-button.component.jsx @@ -24,6 +24,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import { CalculateAllocationsTotals } from "../labor-allocations-table/labor-allocations-table.utility"; import TechJobClockoutDelete from "../tech-job-clock-out-delete/tech-job-clock-out-delete.component"; import { LaborAllocationContainer } from "../time-ticket-modal/time-ticket-modal.component"; +import { useTreatments } from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -43,6 +44,12 @@ export function TechClockOffButton({ const [updateTimeticket] = useMutation(UPDATE_TIME_TICKET); const [updateJobStatus] = useMutation(UPDATE_JOB_STATUS); const [form] = Form.useForm(); + const { Enhanced_Payroll } = useTreatments( + ["Enhanced_Payroll"], + {}, + bodyshop.imexshopid + ); + const { queryLoading, data: lineTicketData } = useQuery( GET_LINE_TICKET_BY_PK, { @@ -76,7 +83,9 @@ export function TechClockOffButton({ ?.rate, flat_rate: emps && emps.flat_rate, ciecacode: - bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber + bodyshop.cdk_dealerid || + bodyshop.pbs_serialnumber || + Enhanced_Payroll.treatment === "on" ? values.cost_center : Object.keys( bodyshop.md_responsibility_centers.defaults.costs diff --git a/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx b/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx index fcf4ac4e8..2325e4e66 100644 --- a/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx +++ b/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx @@ -20,6 +20,7 @@ import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component"; import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component"; import TimeTicketList from "../time-ticket-list/time-ticket-list.component"; import TimeTicketCalculatorComponent from "../time-ticket-calculator/time-ticket-calculator.component"; +import { useTreatments } from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -41,6 +42,11 @@ export function TimeTicketModalComponent({ employeeSelectDisabled, }) { const { t } = useTranslation(); + const { Enhanced_Payroll } = useTreatments( + ["Enhanced_Payroll"], + {}, + bodyshop.imexshopid + ); const [loadLineTicketData, { called, loading, data: lineTicketData }] = useLazyQuery(GET_LINE_TICKET_BY_PK, { fetchPolicy: "network-only", @@ -58,7 +64,7 @@ export function TimeTicketModalComponent({ {item.cost_center === "timetickets.labels.shift" ? t(item.cost_center) - : bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber + : bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatment === 'on' ? t( `joblines.fields.lbr_types.${item.cost_center.toUpperCase()}` ) diff --git a/client/src/components/time-ticket-modal/time-ticket-modal.container.jsx b/client/src/components/time-ticket-modal/time-ticket-modal.container.jsx index 4ae2913b6..e70cc4e5c 100644 --- a/client/src/components/time-ticket-modal/time-ticket-modal.container.jsx +++ b/client/src/components/time-ticket-modal/time-ticket-modal.container.jsx @@ -15,6 +15,7 @@ import { selectTimeTicket } from "../../redux/modals/modals.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors"; import TimeTicketModalComponent from "./time-ticket-modal.component"; import TimeTicketsCommitToggleComponent from "../time-tickets-commit-toggle/time-tickets-commit-toggle.component"; +import { useTreatments } from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ timeTicketModal: selectTimeTicket, @@ -35,7 +36,11 @@ export function TimeTicketModalContainer({ const [enterAgain, setEnterAgain] = useState(false); const [insertTicket] = useMutation(INSERT_NEW_TIME_TICKET); const [updateTicket] = useMutation(UPDATE_TIME_TICKET); - + const { Enhanced_Payroll } = useTreatments( + ["Enhanced_Payroll"], + {}, + bodyshop.imexshopid + ); const { data: EmployeeAutoCompleteData } = useQuery(QUERY_ACTIVE_EMPLOYEES, { skip: !timeTicketModal.visible, fetchPolicy: "network-only", @@ -147,7 +152,7 @@ export function TimeTicketModalContainer({ if (!!changedFields.cost_center && !!EmployeeAutoCompleteData) { form.setFieldsValue({ ciecacode: - bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber + bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatments === 'on' ? changedFields.cost_center : Object.keys( bodyshop.md_responsibility_centers.defaults.costs