From 196bdd83ba0abfd3c94ccae2f7a78c70c42966c3 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 5 Apr 2023 09:13:37 -0700 Subject: [PATCH 01/30] IO-2206 Payroll UI updates for discussions with Rome Clients. --- .../labor-allocations-table.utility.js | 4 - .../time-ticket-calculator.component.jsx | 142 ++++++++++++++++++ .../time-ticket-modal.component.jsx | 37 +++-- client/src/graphql/jobs-lines.queries.js | 38 +++++ 4 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 client/src/components/time-ticket-calculator/time-ticket-calculator.component.jsx diff --git a/client/src/components/labor-allocations-table/labor-allocations-table.utility.js b/client/src/components/labor-allocations-table/labor-allocations-table.utility.js index 2ce5b4a0b..d236de913 100644 --- a/client/src/components/labor-allocations-table/labor-allocations-table.utility.js +++ b/client/src/components/labor-allocations-table/labor-allocations-table.utility.js @@ -6,10 +6,6 @@ export const CalculateAllocationsTotals = ( timetickets, adjustments = [] ) => { - console.log( - "🚀 ~ file: labor-allocations-table.utility.js ~ line 9 ~ adjustments", - adjustments - ); const responsibilitycenters = bodyshop.md_responsibility_centers; const jobCodes = joblines.map((item) => item.mod_lbr_ty); //.filter((value, index, self) => self.indexOf(value) === index && !!value); diff --git a/client/src/components/time-ticket-calculator/time-ticket-calculator.component.jsx b/client/src/components/time-ticket-calculator/time-ticket-calculator.component.jsx new file mode 100644 index 000000000..a36f1dd49 --- /dev/null +++ b/client/src/components/time-ticket-calculator/time-ticket-calculator.component.jsx @@ -0,0 +1,142 @@ +import { DownOutlined } from "@ant-design/icons"; +import { + Button, + Checkbox, + Col, + Form, + InputNumber, + Popover, + Radio, + Row, + Space, + Spin, +} from "antd"; +import React, { useState } from "react"; +import { GET_JOB_INFO_DRAW_CALCULATIONS } from "../../graphql/jobs-lines.queries"; +import { useQuery } from "@apollo/client"; + +export default function TimeTicketCalculatorComponent({ + setProductiveHours, + + jobid, +}) { + const { loading, data: lineTicketData } = useQuery(GET_JOB_INFO_DRAW_CALCULATIONS, { + variables: { id: jobid }, + skip: !jobid, + fetchPolicy: "network-only", + nextFetchPolicy: "network-only", + }); + + const [visible, setVisible] = useState(false); + const handleOpenChange = (flag) => setVisible(flag); + const handleFinish = ({ type, hourstype, percent }) => { + //setProductiveHours(values); + //setVisible(false); + const eligibleHours = Array.isArray(hourstype) + ? lineTicketData.joblines.reduce( + (acc, val) => + acc + (hourstype.includes(val.mod_lbr_ty) ? val.mod_lb_hrs : 0), + 0 + ) + : lineTicketData.joblines.reduce( + (acc, val) => + acc + (hourstype === val.mod_lbr_ty ? val.mod_lb_hrs : 0), + 0 + ); + if (type === "draw") { + setProductiveHours(eligibleHours * (percent / 100)); + } else if (type === "cut") { + setProductiveHours(eligibleHours * (percent / 100)); + console.log( + "Cut selected, rate set to: ", + lineTicketData.jobs_by_pk[`rate_${hourstype.toLowerCase()}`] + ); + } + }; + + const popContent = ( + +
+ + + Draw + Cut of Sale + + + + + {({ getFieldValue }) => ( + + {getFieldValue("type") === "draw" ? ( + + + + + Body + + + + + Refinish + + + + + Mechanical + + + + + Frame + + + + + Glass + + + + + ) : ( + + Body + + Refinish + + Mechanical + + Frame + + Glass + + )} + + )} + + + + + + +
+
+ ); + + return ( + + + + ); +} 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 6f61fccf0..d74069cd9 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 @@ -18,6 +18,7 @@ import LayoutFormRow from "../layout-form-row/layout-form-row.component"; 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"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -172,20 +173,28 @@ export function TimeTicketModalComponent({ {() => ( - - - + <> + + + + + form.setFieldsValue({ productivehrs }) + } + /> + )} Date: Wed, 5 Apr 2023 17:21:47 -0700 Subject: [PATCH 02/30] IO-2086 Resolve imports for additional classes with gallery. --- .../jobs-documents-gallery.external.component.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.external.component.jsx b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.external.component.jsx index fe23d8ceb..5465bbf5c 100644 --- a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.external.component.jsx +++ b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.external.component.jsx @@ -1,5 +1,5 @@ import React, { useEffect } from "react"; -import Gallery from "react-grid-gallery"; +import { Gallery } from "react-grid-gallery"; import { useTranslation } from "react-i18next"; import { GenerateSrcUrl, GenerateThumbUrl } from "./job-documents.utility"; @@ -39,7 +39,7 @@ function JobsDocumentGalleryExternal({ { + onSelect={(index, image) => { setgalleryImages( galleryImages.map((g, idx) => index === idx ? { ...g, isSelected: !g.isSelected } : g From 146bf95e514ed42ade587e6ee925d924c8dd5b38 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 5 Apr 2023 17:22:18 -0700 Subject: [PATCH 03/30] IO-2086 Resolve additional gallery import issue & tech login issue. --- .../jobs-documents-local-gallery.external.component.jsx | 7 +++---- .../tech-job-clock-out-button.component.jsx | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.external.component.jsx b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.external.component.jsx index 46625f419..49fef085e 100644 --- a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.external.component.jsx +++ b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.external.component.jsx @@ -1,5 +1,5 @@ import React, { useEffect } from "react"; -import Gallery from "react-grid-gallery"; +import { Gallery } from "react-grid-gallery"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; @@ -38,7 +38,7 @@ function JobDocumentsLocalGalleryExternal({ const { t } = useTranslation(); useEffect(() => { - if ( jobId) { + if (jobId) { getJobMedia(jobId); } }, [jobId, getJobMedia]); @@ -65,8 +65,7 @@ function JobDocumentsLocalGalleryExternal({
{ + onSelect={(index, image) => { setgalleryImages( galleryImages.map((g, idx) => index === idx ? { ...g, isSelected: !g.isSelected } : g 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 7ea864ad5..85589b13d 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 @@ -59,7 +59,7 @@ export function TechClockOffButton({ emps && emps.rates.filter((r) => r.cost_center === values.cost_center)[0] ?.rate, - flat_rate: emps.flat_rate, + flat_rate: emps && emps.flat_rate, ciecacode: bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber ? values.cost_center From 27a67c5f4a7b4ace76a2af03f819d855769af4b0 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 6 Apr 2023 10:36:29 -0700 Subject: [PATCH 04/30] Added team pay calculator. --- .../time-ticket-list-team-pay.component.jsx | 276 ++++++++++++++++++ .../time-ticket-list.component.jsx | 15 + ...me-tickets-summary-employees.component.jsx | 22 +- 3 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 client/src/components/time-ticket-list/time-ticket-list-team-pay.component.jsx diff --git a/client/src/components/time-ticket-list/time-ticket-list-team-pay.component.jsx b/client/src/components/time-ticket-list/time-ticket-list-team-pay.component.jsx new file mode 100644 index 000000000..ca13499d2 --- /dev/null +++ b/client/src/components/time-ticket-list/time-ticket-list-team-pay.component.jsx @@ -0,0 +1,276 @@ +import { + Button, + Form, + InputNumber, + Modal, + Radio, + Select, + Space, + Table, + Typography, +} from "antd"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import FormDatePicker from "../form-date-picker/form-date-picker.component"; +import JobSearchSelectComponent from "../job-search-select/job-search-select.component"; +import LayoutFormRow from "../layout-form-row/layout-form-row.component"; +import Dinero from "dinero.js"; +import { useQuery } from "@apollo/client"; +import { GET_JOB_INFO_DRAW_CALCULATIONS } from "../../graphql/jobs-lines.queries"; +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop, +}); +const mapDispatchToProps = (dispatch) => ({}); +export default connect( + mapStateToProps, + mapDispatchToProps +)(TimeTicketListTeamPay); + +export function TimeTicketListTeamPay({ bodyshop, context, actions }) { + const { refetch } = actions; + const { jobId } = context; + const [visible, setVisible] = useState(false); + const [form] = Form.useForm(); + const { t } = useTranslation(); + const { loading, data: lineTicketData } = useQuery( + GET_JOB_INFO_DRAW_CALCULATIONS, + { + variables: { id: jobId }, + skip: !jobId, + fetchPolicy: "network-only", + nextFetchPolicy: "network-only", + } + ); + + const handleOk = () => { + setVisible(false); + }; + + return ( + <> + setVisible(false)} + > +
+ + + {() => ( + + + + )} + + + + + + + + +