diff --git a/client/src/components/courtesy-car-form/courtesy-car-form.component.jsx b/client/src/components/courtesy-car-form/courtesy-car-form.component.jsx index 1e95960a9..1e9574d1b 100644 --- a/client/src/components/courtesy-car-form/courtesy-car-form.component.jsx +++ b/client/src/components/courtesy-car-form/courtesy-car-form.component.jsx @@ -215,10 +215,7 @@ export default function CourtesyCarCreateFormComponent({ form, saveLoading }) { > - +
@@ -235,8 +232,9 @@ export default function CourtesyCarCreateFormComponent({ form, saveLoading }) { > {() => { const nextservicekm = form.getFieldValue("nextservicekm"); - const mileageOver = - nextservicekm && nextservicekm <= form.getFieldValue("mileage"); + const mileageOver = nextservicekm + ? nextservicekm <= form.getFieldValue("mileage") + : false; if (mileageOver) return ( diff --git a/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx b/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx index b11d57f5a..7b5cc8ec2 100644 --- a/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx +++ b/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx @@ -73,10 +73,10 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) { render: (text, record) => { const { nextservicedate, nextservicekm, mileage } = record; - const mileageOver = nextservicekm <= mileage; + const mileageOver = nextservicekm ? nextservicekm <= mileage : false; const dueForService = - nextservicedate && dayjs(nextservicedate).isBefore(dayjs()); + nextservicedate && dayjs(nextservicedate).end('day').isSameOrBefore(dayjs()); 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 30bb98560..9ae08588d 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 @@ -221,6 +221,11 @@ export function JobsDetailHeader({ job, bodyshop, disabled }) { {`${job.v_vin || t("general.labels.na")}`} + {bodyshop.pbs_serialnumber || bodyshop.cdk_dealerid ? ( + job.v_vin.length !== 17 ? ( + + ) : null + ) : null} {job.regie_number || t("general.labels.na")} diff --git a/client/src/components/production-list-columns/production-list-columns.add.component.jsx b/client/src/components/production-list-columns/production-list-columns.add.component.jsx index fb346ace2..7088f6726 100644 --- a/client/src/components/production-list-columns/production-list-columns.add.component.jsx +++ b/client/src/components/production-list-columns/production-list-columns.add.component.jsx @@ -24,6 +24,7 @@ export function ProductionColumnsComponent({ columnState, technician, bodyshop, + data, tableState, }) { const [columns, setColumns] = columnState; @@ -36,6 +37,7 @@ export function ProductionColumnsComponent({ bodyshop, technician, state: tableState, + data, activeStatuses: bodyshop.md_ro_statuses.active_statuses, }).filter((i) => i.key === e.key), ]); @@ -44,6 +46,7 @@ export function ProductionColumnsComponent({ const columnKeys = columns.map((i) => i.key); const cols = dataSource({ technician, + data, state: tableState, activeStatuses: bodyshop.md_ro_statuses.active_statuses, }); 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 e9b57df19..003a3b864 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 @@ -1,4 +1,4 @@ -import { PauseCircleOutlined, BranchesOutlined } from "@ant-design/icons"; +import { BranchesOutlined, PauseCircleOutlined } from "@ant-design/icons"; import { Space, Tooltip } from "antd"; import i18n from "i18next"; import dayjs from "../../utils/day"; @@ -6,6 +6,7 @@ import { Link } from "react-router-dom"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { TimeFormatter } from "../../utils/DateFormatter"; import PhoneFormatter from "../../utils/PhoneFormatter"; +import { onlyUnique } from "../../utils/arrayHelper"; import { alphaSort, dateSort, statusSort } from "../../utils/sorters"; import JobAltTransportChange from "../job-at-change/job-at-change.component"; import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component"; @@ -25,7 +26,7 @@ import ProductionListColumnCategory from "./production-list-columns.status.categ import ProductionListColumnStatus from "./production-list-columns.status.component"; import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component"; -const r = ({ technician, state, activeStatuses, bodyshop }) => { +const r = ({ technician, state, activeStatuses, data, bodyshop }) => { return [ { title: i18n.t("jobs.actions.viewdetail"), @@ -536,6 +537,36 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => { ), }, + { + title: i18n.t("jobs.labels.estimator"), + dataIndex: "estimator", + key: "estimator", + sorter: (a, b) => + alphaSort( + `${a.est_ct_fn || ""} ${a.est_ct_ln || ""}`.trim(), + `${b.est_ct_fn || ""} ${b.est_ct_ln || ""}`.trim() + ), + sortOrder: + state.sortedInfo.columnKey === "estimator" && state.sortedInfo.order, + filters: + (data && + data + .map((j) => `${j.est_ct_fn || ""} ${j.est_ct_ln || ""}`.trim()) + .filter(onlyUnique) + .map((s) => { + return { + text: s || "N/A", + value: [s], + }; + })) || + [], + onFilter: (value, record) => + value.includes( + `${record.est_ct_fn || ""} ${record.est_ct_ln || ""}`.trim() + ), + render: (text, record) => + `${record.est_ct_fn || ""} ${record.est_ct_ln || ""}`.trim(), + }, //Added as a place holder for St Claude. Not implemented as it requires another join for a field used by only 1 client. // { diff --git a/client/src/components/production-list-table/production-list-table-view-select.component.jsx b/client/src/components/production-list-table/production-list-table-view-select.component.jsx index 48a1f7222..dd58b5d16 100644 --- a/client/src/components/production-list-table/production-list-table-view-select.component.jsx +++ b/client/src/components/production-list-table/production-list-table-view-select.component.jsx @@ -24,6 +24,7 @@ export function ProductionListTable({ technician, currentUser, state, + data, setColumns, setState, }) { @@ -41,6 +42,7 @@ export function ProductionListTable({ bodyshop, technician, state, + data: data, activeStatuses: bodyshop.md_ro_statuses.active_statuses, }).find((e) => e.key === k.key), width: k.width, @@ -95,6 +97,7 @@ export function ProductionListTable({ ...ProductionListColumns({ technician, state, + data: data, activeStatuses: bodyshop.md_ro_statuses.active_statuses, }).find((e) => e.key === k.key), width: k.width, 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 b817a379d..fcce11281 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 @@ -1,8 +1,8 @@ import {SyncOutlined} from "@ant-design/icons"; import {useSplitTreatments} from "@splitsoftware/splitio-react"; -import {Button, Dropdown, Input, Space, Statistic, Table,} from "antd"; +import {Button, Dropdown, Input, Space, Statistic, Table} from "antd"; import {PageHeader} from "@ant-design/pro-layout"; -import React, {useMemo, useState} from "react"; +import React, {useEffect, useMemo, useState} from "react"; import ReactDragListView from "react-drag-listview"; import {useTranslation} from "react-i18next"; import {connect} from "react-redux"; @@ -66,6 +66,7 @@ export function ProductionListTable({loading, data, refetch, bodyshop, technicia bodyshop, technician, state, + data, activeStatuses: bodyshop.md_ro_statuses.active_statuses, }).find((e) => e.key === k.key), width: k.width ?? 100, @@ -74,6 +75,34 @@ export function ProductionListTable({loading, data, refetch, bodyshop, technicia [] ); + useEffect(() => { + const newColumns = + (state && + matchingColumnConfig && + matchingColumnConfig.columns.columnKeys.map((k) => { + return { + ...ProductionListColumns({ + bodyshop, + technician, + state, + data: data, + activeStatuses: bodyshop.md_ro_statuses.active_statuses, + }).find((e) => e.key === k.key), + width: k.width ?? 100, + }; + })) || + []; + setColumns(newColumns); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + //state, + matchingColumnConfig, + bodyshop, + technician, + data, + ]); //State removed from dependency array as it causes race condition when removing columns from table view and is not needed. + + const handleTableChange = (pagination, filters, sorter) => { setState({ ...state, @@ -89,10 +118,11 @@ export function ProductionListTable({loading, data, refetch, bodyshop, technicia setColumns(columnsCopy); }; - const removeColumn = (e) => { - const {key} = e; - setColumns(columns.filter((i) => i.key !== key)); - }; + const removeColumn = (e) => { + const { key } = e; + const newColumns = columns.filter((i) => i.key !== key); + setColumns(newColumns); + }; const handleResize = (index) => @@ -221,6 +251,7 @@ export function ProductionListTable({loading, data, refetch, bodyshop, technicia { exports.generate_payment_url = async (req, res) => { logger.log("intellipay-payment-url", "DEBUG", req.user?.email, null, null); const shopCredentials = await getShopCredentials(req.body.bodyshop); + try { const options = { method: "POST", @@ -139,7 +140,12 @@ exports.generate_payment_url = async (req, res) => { //TODO: Move these to environment variables/database. data: qs.stringify({ ...shopCredentials, - ...req.body, + //...req.body, + amount: Dinero({ amount: Math.round(req.body.amount * 100) }).toFormat( + "0.00" + ), + account: req.body.account, + invoice: req.body.invoice, createshorturl: true, //The postback URL is set at the CP teller global terminal settings page. }),