Merge branch 'master-AIO' into feature/IO-3286-Additional-Product-Fruit-IDs

This commit is contained in:
Allan Carr
2025-07-11 10:31:22 -07:00
7 changed files with 4005 additions and 3974 deletions

View File

@@ -25,6 +25,7 @@ import BillFormContainer from "../bill-form/bill-form.container";
import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility"; import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility";
import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility"; import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility";
import { handleUpload } from "../documents-upload/documents-upload.utility"; import { handleUpload } from "../documents-upload/documents-upload.utility";
import { handleUpload as handleUploadToImageProxy } from "../documents-upload-imgproxy/documents-upload-imgproxy.utility";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
billEnterModal: selectBillEnterModal, billEnterModal: selectBillEnterModal,
@@ -53,10 +54,10 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop,
const notification = useNotification(); const notification = useNotification();
const { const {
treatments: { Enhanced_Payroll } treatments: { Enhanced_Payroll, Imgproxy }
} = useSplitTreatments({ } = useSplitTreatments({
attributes: {}, attributes: {},
names: ["Enhanced_Payroll"], names: ["Enhanced_Payroll", "Imgproxy"],
splitKey: bodyshop.imexshopid splitKey: bodyshop.imexshopid
}); });
@@ -297,6 +298,24 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop,
notification notification
}); });
}); });
} else {
//Check if using Imgproxy or cloudinary
if (Imgproxy.treatment === "on") {
upload.forEach((u) => {
handleUploadToImageProxy(
{ file: u.originFileObj },
{
bodyshop: bodyshop,
uploaded_by: currentUser.email,
jobId: values.jobid,
billId: billId,
tagsArray: null,
callback: null
},
notification
);
});
} else { } else {
upload.forEach((u) => { upload.forEach((u) => {
handleUpload( handleUpload(
@@ -314,6 +333,7 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop,
}); });
} }
} }
}
/////////////////////////// ///////////////////////////
setLoading(false); setLoading(false);
notification["success"]({ notification["success"]({

View File

@@ -1,5 +1,5 @@
import { Col, Row } from "antd"; import { Col, Row } from "antd";
import React, { useEffect } from "react"; import { useEffect } from "react";
import ScoreboardChart from "../scoreboard-chart/scoreboard-chart.component"; import ScoreboardChart from "../scoreboard-chart/scoreboard-chart.component";
import ScoreboardLastDays from "../scoreboard-last-days/scoreboard-last-days.component"; import ScoreboardLastDays from "../scoreboard-last-days/scoreboard-last-days.component";
import ScoreboardTargetsTable from "../scoreboard-targets-table/scoreboard-targets-table.component"; import ScoreboardTargetsTable from "../scoreboard-targets-table/scoreboard-targets-table.component";
@@ -31,13 +31,13 @@ export function ScoreboardDisplayComponent({ bodyshop }) {
const { data } = scoreboardSubscription; const { data } = scoreboardSubscription;
const client = useApolloClient(); const client = useApolloClient();
const scoreBoardlist = (data && data.scoreboard) || []; const scoreBoardlist = data?.scoreboard || [];
const sbEntriesByDate = {}; const sbEntriesByDate = {};
scoreBoardlist.forEach((i) => { scoreBoardlist.forEach((i) => {
const entryDate = i.date; const entryDate = i.date;
if (!!!sbEntriesByDate[entryDate]) { if (!sbEntriesByDate[entryDate]) {
sbEntriesByDate[entryDate] = []; sbEntriesByDate[entryDate] = [];
} }
sbEntriesByDate[entryDate].push(i); sbEntriesByDate[entryDate].push(i);
@@ -58,10 +58,9 @@ export function ScoreboardDisplayComponent({ bodyshop }) {
}); });
appointments = data.appointments; appointments = data.appointments;
} }
dayjs.updateLocale(dayjs.locale(), {
dayjs.updateLocale("ca", {
workingWeekdays: translateSettingsToWorkingDays(bodyshop.workingdays), workingWeekdays: translateSettingsToWorkingDays(bodyshop.workingdays),
...(appointments ...(appointments?.length
? { ? {
holidays: appointments.map((h) => dayjs(h.start).format("MM-DD-YYYY")) holidays: appointments.map((h) => dayjs(h.start).format("MM-DD-YYYY"))
} }
@@ -78,11 +77,9 @@ export function ScoreboardDisplayComponent({ bodyshop }) {
<Col span={24}> <Col span={24}>
<ScoreboardTargetsTable scoreBoardlist={scoreBoardlist} /> <ScoreboardTargetsTable scoreBoardlist={scoreBoardlist} />
</Col> </Col>
<Col span={24}> <Col span={24}>
<ScoreboardLastDays sbEntriesByDate={sbEntriesByDate} /> <ScoreboardLastDays sbEntriesByDate={sbEntriesByDate} />
</Col> </Col>
<Col span={24}> <Col span={24}>
<ScoreboardChart sbEntriesByDate={sbEntriesByDate} /> <ScoreboardChart sbEntriesByDate={sbEntriesByDate} />
</Col> </Col>

View File

@@ -14,6 +14,7 @@ import PhoneFormItem, { PhoneItemFormatterValidation } from "../form-items-forma
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component"; import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";
// eslint-disable-next-line no-undef
const timeZonesList = Intl.supportedValuesOf("timeZone"); const timeZonesList = Intl.supportedValuesOf("timeZone");
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop bodyshop: selectBodyshop
@@ -143,8 +144,9 @@ export function ShopInfoGeneral({ form, bodyshop }) {
<InputNumber min={0} /> <InputNumber min={0} />
</Form.Item> </Form.Item>
</LayoutFormRow> </LayoutFormRow>
<FeatureWrapper featureName="export" noauth={() => null}>
<LayoutFormRow header={t("bodyshop.labels.accountingsetup")} id="accountingsetup"> <LayoutFormRow header={t("bodyshop.labels.accountingsetup")} id="accountingsetup">
{HasFeatureAccess({ featureName: "export", bodyshop }) && (
<>
<Form.Item label={t("bodyshop.labels.qbo")} valuePropName="checked" name={["accountingconfig", "qbo"]}> <Form.Item label={t("bodyshop.labels.qbo")} valuePropName="checked" name={["accountingconfig", "qbo"]}>
<Switch /> <Switch />
</Form.Item> </Form.Item>
@@ -218,6 +220,8 @@ export function ShopInfoGeneral({ form, bodyshop }) {
> >
<Switch /> <Switch />
</Form.Item> </Form.Item>
</>
)}
<Form.Item <Form.Item
label={t("bodyshop.fields.inhousevendorid")} label={t("bodyshop.fields.inhousevendorid")}
name={"inhousevendorid"} name={"inhousevendorid"}
@@ -252,6 +256,8 @@ export function ShopInfoGeneral({ form, bodyshop }) {
<Form.Item label={t("bodyshop.fields.state_tax_id")} name="state_tax_id"> <Form.Item label={t("bodyshop.fields.state_tax_id")} name="state_tax_id">
<Input /> <Input />
</Form.Item> </Form.Item>
{HasFeatureAccess({ featureName: "bills", bodyshop }) && (
<>
{InstanceRenderManager({ {InstanceRenderManager({
imex: ( imex: (
<Form.Item <Form.Item
@@ -292,6 +298,8 @@ export function ShopInfoGeneral({ form, bodyshop }) {
> >
<InputNumber /> <InputNumber />
</Form.Item> </Form.Item>
</>
)}
<Form.Item <Form.Item
name={["md_payment_types"]} name={["md_payment_types"]}
label={t("bodyshop.fields.md_payment_types")} label={t("bodyshop.fields.md_payment_types")}
@@ -317,9 +325,8 @@ export function ShopInfoGeneral({ form, bodyshop }) {
> >
<Select mode="tags" /> <Select mode="tags" />
</Form.Item> </Form.Item>
<Form.Item name={["enforce_class"]} label={t("bodyshop.fields.enforce_class")} valuePropName="checked"> {HasFeatureAccess({ featureName: "export", bodyshop }) && (
<Switch /> <>
</Form.Item>
<Form.Item <Form.Item
name={["accountingconfig", "ReceivableCustomField1"]} name={["accountingconfig", "ReceivableCustomField1"]}
label={t("bodyshop.fields.ReceivableCustomField", { number: 1 })} label={t("bodyshop.fields.ReceivableCustomField", { number: 1 })}
@@ -353,6 +360,9 @@ export function ShopInfoGeneral({ form, bodyshop }) {
> >
<Select mode="tags" /> <Select mode="tags" />
</Form.Item> </Form.Item>
<Form.Item name={["enforce_class"]} label={t("bodyshop.fields.enforce_class")} valuePropName="checked">
<Switch />
</Form.Item>
{ClosingPeriod.treatment === "on" && ( {ClosingPeriod.treatment === "on" && (
<Form.Item <Form.Item
name={["accountingconfig", "ClosingPeriod"]} name={["accountingconfig", "ClosingPeriod"]}
@@ -371,8 +381,9 @@ export function ShopInfoGeneral({ form, bodyshop }) {
<Input /> <Input />
</Form.Item> </Form.Item>
)} )}
</>
)}
</LayoutFormRow> </LayoutFormRow>
</FeatureWrapper>
<FeatureWrapper featureName="scoreboard" noauth={() => null}> <FeatureWrapper featureName="scoreboard" noauth={() => null}>
<LayoutFormRow header={t("bodyshop.labels.scoreboardsetup")} id="scoreboardsetup"> <LayoutFormRow header={t("bodyshop.labels.scoreboardsetup")} id="scoreboardsetup">
<Form.Item <Form.Item
@@ -822,7 +833,11 @@ export function ShopInfoGeneral({ form, bodyshop }) {
}} }}
</Form.List> </Form.List>
</LayoutFormRow> </LayoutFormRow>
<LayoutFormRow grow header=<span id="insurancecos-header">{t("bodyshop.labels.insurancecos")}</span> id="insurancecos"> <LayoutFormRow
grow
header=<span id="insurancecos-header">{t("bodyshop.labels.insurancecos")}</span>
id="insurancecos"
>
<Form.List name={["md_ins_cos"]}> <Form.List name={["md_ins_cos"]}>
{(fields, { add, remove, move }) => { {(fields, { add, remove, move }) => {
return ( return (

View File

@@ -1,7 +1,7 @@
import Icon, { FieldTimeOutlined } from "@ant-design/icons"; import Icon, { FieldTimeOutlined } from "@ant-design/icons";
import { Card, Tabs } from "antd"; import { Card, Tabs } from "antd";
import queryString from "query-string"; import queryString from "query-string";
import React, { useEffect } from "react"; import { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { FaShieldAlt } from "react-icons/fa"; import { FaShieldAlt } from "react-icons/fa";
import { connect } from "react-redux"; import { connect } from "react-redux";
@@ -78,7 +78,7 @@ export function ScoreboardContainer({ setBreadcrumbs, setSelectedHeader }) {
<RbacWrapper action="scoreboard:view"> <RbacWrapper action="scoreboard:view">
<Tabs <Tabs
activeKey={tab || "sb"} activeKey={tab || "sb"}
destroyInactiveTabPane destroyOnHidden
onChange={(key) => { onChange={(key) => {
searchParams.tab = key; searchParams.tab = key;
history({ history({

View File

@@ -381,7 +381,7 @@ async function CalculateRatesTotals({ job, client }) {
if (item.mod_lbr_ty) { if (item.mod_lbr_ty) {
//Check to see if it has 0 hours and a price instead. //Check to see if it has 0 hours and a price instead.
if (item.mod_lb_hrs === 0 && item.act_price > 0 && item.lbr_op === "OP14") { if (item.lbr_op === "OP14" && item.act_price > 0 && (!item.part_type || item.mod_lb_hrs === 0)) {
//Scenario where SGI may pay out hours using a part price. //Scenario where SGI may pay out hours using a part price.
if (!ret[item.mod_lbr_ty.toLowerCase()].total) { if (!ret[item.mod_lbr_ty.toLowerCase()].total) {
ret[item.mod_lbr_ty.toLowerCase()].total = Dinero(); ret[item.mod_lbr_ty.toLowerCase()].total = Dinero();

View File

@@ -314,7 +314,8 @@ function CalculateRatesTotals(ratesList) {
if (item.mod_lbr_ty) { if (item.mod_lbr_ty) {
//Check to see if it has 0 hours and a price instead. //Check to see if it has 0 hours and a price instead.
if (item.mod_lb_hrs === 0 && item.act_price > 0 && item.lbr_op === "OP14") { //Extend for when there are hours and a price.
if (item.lbr_op === "OP14" && item.act_price > 0 && (!item.part_type || item.mod_lb_hrs === 0)) {
//Scenario where SGI may pay out hours using a part price. //Scenario where SGI may pay out hours using a part price.
if (!ret[item.mod_lbr_ty.toLowerCase()].total) { if (!ret[item.mod_lbr_ty.toLowerCase()].total) {
ret[item.mod_lbr_ty.toLowerCase()].total = Dinero(); ret[item.mod_lbr_ty.toLowerCase()].total = Dinero();