diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 23707d6e7..f453df8c6 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -8864,6 +8864,27 @@ + + tt_enforce_hours_for_tech_console + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + use_fippa false @@ -17310,6 +17331,27 @@ + + total + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + totals false @@ -33806,6 +33848,27 @@ errors + + deleting + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + noaccess false @@ -34367,6 +34430,27 @@ + + deleteconfirm + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + existing_owners false @@ -34477,6 +34561,27 @@ successes + + delete + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + save false @@ -44980,6 +45085,27 @@ + + hoursenteredmorethanavailable + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -47292,6 +47418,27 @@ errors + + deleting + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + noaccess false @@ -47916,6 +48063,27 @@ labels + + deleteconfirm + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + fromvehicle false @@ -48005,6 +48173,27 @@ successes + + delete + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + save false 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/production-list-columns/production-list-columns.data.js b/client/src/components/production-list-columns/production-list-columns.data.js index bd2f15817..7d122200d 100644 --- a/client/src/components/production-list-columns/production-list-columns.data.js +++ b/client/src/components/production-list-columns/production-list-columns.data.js @@ -91,11 +91,13 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => { b.v_make_desc + b.v_model_desc ), sortOrder: - state.sortedInfo.columnKey === "ownr" && state.sortedInfo.order, + state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order, render: (text, record) => ( - {`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${ - record.v_model_desc || "" - } ${record.v_color || ""} ${record.plate_no || ""}`} + {`${ + record.v_model_yr || "" + } ${record.v_make_desc || ""} ${record.v_model_desc || ""} ${ + record.v_color || "" + } ${record.plate_no || ""}`} ), }, { diff --git a/client/src/components/production-list-table/production-list-table.component.jsx b/client/src/components/production-list-table/production-list-table.component.jsx index 6595476d5..746d956ab 100644 --- a/client/src/components/production-list-table/production-list-table.component.jsx +++ b/client/src/components/production-list-table/production-list-table.component.jsx @@ -81,7 +81,7 @@ export function ProductionListTable({ state, activeStatuses: bodyshop.md_ro_statuses.active_statuses, }).find((e) => e.key === k.key), - width: k.width, + width: k.width ?? 100, }; })) || [] @@ -267,6 +267,8 @@ export function ProductionListTable({ sortOrder: state.sortedInfo.columnKey === c.key && state.sortedInfo.order, title: headerItem(c), + ellipsis: true, + width: c.width ?? 100, onHeaderCell: (column) => ({ width: column.width, onResize: handleResize(index), @@ -276,11 +278,12 @@ export function ProductionListTable({ rowKey="id" loading={loading} dataSource={dataSource} - // scroll={{ x: true }} + scroll={{ x: 1000 }} onChange={handleTableChange} /> ); } + export default connect(mapStateToProps, null)(ProductionListTable); diff --git a/client/src/components/production-list-table/production-list-table.resizeable.component.jsx b/client/src/components/production-list-table/production-list-table.resizeable.component.jsx index 2f1324999..07b47c87a 100644 --- a/client/src/components/production-list-table/production-list-table.resizeable.component.jsx +++ b/client/src/components/production-list-table/production-list-table.resizeable.component.jsx @@ -3,8 +3,18 @@ import { Resizable } from "react-resizable"; export default function ResizableComponent(props) { const { onResize, width, ...restProps } = props; + + if (!width) { + return ; + } + return ( - + ); diff --git a/client/src/components/scoreboard-day-stats/scoreboard-day-stats.component.jsx b/client/src/components/scoreboard-day-stats/scoreboard-day-stats.component.jsx index 36b4a028b..497eab209 100644 --- a/client/src/components/scoreboard-day-stats/scoreboard-day-stats.component.jsx +++ b/client/src/components/scoreboard-day-stats/scoreboard-day-stats.component.jsx @@ -4,6 +4,7 @@ import React from "react"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useTranslation } from "react-i18next"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, }); @@ -13,6 +14,7 @@ const mapDispatchToProps = (dispatch) => ({ export function ScoreboardDayStats({ bodyshop, date, entries }) { const { dailyPaintTarget, dailyBodyTarget } = bodyshop.scoreboard_target; + const { t } = useTranslation(); //let totalHrs = 0; const paintHrs = entries.reduce((acc, value) => { @@ -41,6 +43,10 @@ export function ScoreboardDayStats({ bodyshop, date, entries }) { label="P" value={paintHrs.toFixed(1)} /> + ); } diff --git a/client/src/components/scoreboard-targets-table/scoreboard-targets-table.component.jsx b/client/src/components/scoreboard-targets-table/scoreboard-targets-table.component.jsx index 6f22b3b8a..558b217b6 100644 --- a/client/src/components/scoreboard-targets-table/scoreboard-targets-table.component.jsx +++ b/client/src/components/scoreboard-targets-table/scoreboard-targets-table.component.jsx @@ -184,14 +184,56 @@ export function ScoreboardTargetsTable({ bodyshop, scoreBoardlist }) { value={(values.todayPaint + values.todayBody).toFixed(1)} /> - + + + - - + + + + + + + + + e.id === (technician && technician.id) @@ -129,6 +141,51 @@ export function TechClockOffButton({ required: true, //message: t("general.validation.required"), }, + ({ getFieldValue }) => ({ + validator(rule, value) { + console.log( + bodyshop.tt_enforce_hours_for_tech_console + ); + if (!bodyshop.tt_enforce_hours_for_tech_console) { + return Promise.resolve(); + } + if ( + !value || + getFieldValue("cost_center") === null || + !lineTicketData + ) + return Promise.resolve(); + + //Check the cost center, + const totals = CalculateAllocationsTotals( + bodyshop, + lineTicketData.joblines, + lineTicketData.timetickets, + lineTicketData.jobs_by_pk.lbr_adjustments + ); + + const fieldTypeToCheck = + bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber + ? "mod_lbr_ty" + : "cost_center"; + + const costCenterDiff = totals.find( + (total) => + total[fieldTypeToCheck] === + getFieldValue("cost_center") + )?.difference; + + if (value > costCenterDiff) + return Promise.reject( + t( + "timetickets.validation.hoursenteredmorethanavailable" + ) + ); + else { + return Promise.resolve(); + } + }, + }), ]} > @@ -178,7 +235,11 @@ export function TechClockOffButton({ {!isShiftTicket && ( - + )} 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..c0cf7b024 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 @@ -1,4 +1,4 @@ -import { useQuery } from "@apollo/client"; +import { useLazyQuery } from "@apollo/client"; import { Form, Input, InputNumber, Select, Switch } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; @@ -14,6 +14,7 @@ import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormDateTimePicker from "../form-date-time-picker/form-date-time-picker.component"; import JobSearchSelect from "../job-search-select/job-search-select.component"; import LaborAllocationsTable from "../labor-allocations-table/labor-allocations-table.component"; +import { CalculateAllocationsTotals } from "../labor-allocations-table/labor-allocations-table.utility"; 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"; @@ -38,7 +39,11 @@ export function TimeTicketModalComponent({ employeeSelectDisabled, }) { const { t } = useTranslation(); - + const [loadLineTicketData, { called, loading, data: lineTicketData }] = + useLazyQuery(GET_LINE_TICKET_BY_PK, { + fetchPolicy: "network-only", + nextFetchPolicy: "network-only", + }); const CostCenterSelect = ({ emps, value, ...props }) => { return (