Compare commits

...

22 Commits

Author SHA1 Message Date
Patrick Fic
b8e4520366 Resolve ES Lint error. 2024-04-08 11:05:12 -07:00
Patrick Fic
a2a7c1c58c Add contextRefect to payment export buttons. 2024-04-08 09:48:39 -07:00
Patrick Fic
1469960643 Resolve payment refetch. 2024-04-05 12:52:26 -07:00
Patrick Fic
d7caaecaf7 Merge branch 'feature/IO-2458-RO-Closer' into test-AIO 2024-04-04 20:42:17 -07:00
Patrick Fic
7ece1256f2 Uncomment ProManager calculations. 2024-04-04 20:01:47 -07:00
Patrick Fic
a43134511b Merge branch 'release/2024-04-05' into test-AIO 2024-04-04 12:56:09 -07:00
Patrick Fic
b188cce3ea Merge branch 'test-AIO' of bitbucket.org:snaptsoft/bodyshop into test-AIO 2024-04-04 12:52:02 -07:00
Patrick Fic
39d4f56812 Merge branch 'hotfix/AIO/2024-04-04' into test-AIO 2024-04-04 11:32:01 -07:00
Patrick Fic
f85e3d8d60 Resolve job costing. 2024-04-04 11:31:37 -07:00
Patrick Fic
c33eaa6c68 Merged in feature/IO-2458-RO-Closer (pull request #1390)
Feature/IO-2458 RO Closer
2024-04-04 18:14:11 +00:00
Patrick Fic
37196e65c3 Add schema changes for RO Guard to bodyshop table. 2024-04-03 09:46:52 -07:00
Allan Carr
b20c605c85 Merged in feature/IO-2568-Payment-Modal-Button-Spacing (pull request #1384)
IO-2568 Payment Modal Button Spacing

Approved-by: Dave Richer
2024-04-02 19:03:49 +00:00
Allan Carr
d8ac708536 Merged in feature/IO-2552-PVRT-Button-Spacing (pull request #1386)
IO-2552 PVRT Button Spacing and Alignment

Approved-by: Dave Richer
2024-04-02 19:03:36 +00:00
Allan Carr
8a32fe50f3 Merged in feature/IO-2730-Bill-Search-Result-Align (pull request #1383)
IO-2730 Bill Search Result Align

Approved-by: Dave Richer
2024-04-02 19:03:06 +00:00
Allan Carr
7897a490bd Merged in feature/IO-2563-Repair-Line-Expander-Bills-Transaltion (pull request #1385)
IO-2563 Repair LIne Expander Bills Translation

Approved-by: Dave Richer
2024-04-02 19:02:50 +00:00
Allan Carr
17d73fc6d7 Merged in feature/IO-2553-Edit-CC-Unsaved-Changes (pull request #1388)
IO-2553 Unsaved Changes on Edit CC

Approved-by: Dave Richer
2024-04-02 19:02:28 +00:00
Allan Carr
7d1910086e IO-2553 Unsaved Changes on Edit CC
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-04-02 10:39:41 -07:00
Allan Carr
817c41afb9 IO-2552 PVRT Button Spacing and Alignment
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-04-01 14:27:25 -07:00
Allan Carr
04315a9045 IO-2563 Repair LIne Expander Bills Translation
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-04-01 14:07:58 -07:00
Allan Carr
d0871ffe21 IO-2568 Payment Modal Button Spacing
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-04-01 13:52:25 -07:00
Allan Carr
dca587d6e0 IO-2730 Bill Search Result Align
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-04-01 13:20:30 -07:00
Allan Carr
19ec4cb021 Merged in release/2024-03-28 (pull request #1382)
Release/2024 03 28
2024-03-28 21:15:25 +00:00
16 changed files with 106 additions and 69 deletions

View File

@@ -1,9 +1,8 @@
import React, { useState } from "react";
import { Button, Form, InputNumber, Popover } from "antd";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { useTranslation } from "react-i18next";
import { CalculatorFilled } from "@ant-design/icons"; import { CalculatorFilled } from "@ant-design/icons";
import { Button, Form, InputNumber, Popover, Space } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { logImEXEvent } from "../../firebase/firebase.utils";
export default function CABCpvrtCalculator({ disabled, form }) { export default function CABCpvrtCalculator({ disabled, form }) {
const [visibility, setVisibility] = useState(false); const [visibility, setVisibility] = useState(false);
@@ -27,10 +26,14 @@ export default function CABCpvrtCalculator({ disabled, form }) {
<Form.Item name="days" label={t("jobs.labels.ca_bc_pvrt.days")}> <Form.Item name="days" label={t("jobs.labels.ca_bc_pvrt.days")}>
<InputNumber precision={0} min={0} /> <InputNumber precision={0} min={0} />
</Form.Item> </Form.Item>
<Button type="primary" htmlType="submit"> <div style={{ display: "flex", justifyContent: "flex-end" }}>
{t("general.actions.calculate")} <Space>
</Button> <Button type="primary" htmlType="submit">
<Button onClick={() => setVisibility(false)}>Close</Button> {t("general.actions.calculate")}
</Button>
<Button onClick={() => setVisibility(false)}>Close</Button>
</Space>
</div>
</Form> </Form>
</div> </div>
); );

View File

@@ -11,11 +11,15 @@ import CourtesyCarFuelSlider from "../courtesy-car-fuel-select/courtesy-car-fuel
import CourtesyCarReadiness from "../courtesy-car-readiness-select/courtesy-car-readiness-select.component"; import CourtesyCarReadiness from "../courtesy-car-readiness-select/courtesy-car-readiness-select.component";
import CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status-select.component"; import CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status-select.component";
import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormDatePicker from "../form-date-picker/form-date-picker.component";
//import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component"; import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component"; import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function CourtesyCarCreateFormComponent({ form, saveLoading }) { export default function CourtesyCarCreateFormComponent({
form,
saveLoading,
newCC,
}) {
const { t } = useTranslation(); const { t } = useTranslation();
const client = useApolloClient(); const client = useApolloClient();
@@ -30,7 +34,7 @@ export default function CourtesyCarCreateFormComponent({ form, saveLoading }) {
} }
/> />
{/* <FormFieldsChanged form={form} /> */} {newCC ? null : <FormFieldsChanged form={form} />}
<LayoutFormRow header={t("courtesycars.labels.vehicle")}> <LayoutFormRow header={t("courtesycars.labels.vehicle")}>
<Form.Item <Form.Item
label={t("courtesycars.fields.year")} label={t("courtesycars.fields.year")}

View File

@@ -97,7 +97,7 @@ export function JobLinesExpander({ jobline, jobid, bodyshop }) {
: [ : [
{ {
key: "no-orders", key: "no-orders",
children: t("parts_orders.labels.notyetordered") children: t("bills.labels.nobilllines")
} }
] ]
} }

View File

@@ -592,32 +592,35 @@ function ResolveCCCLineIssues(estData, bodyshop) {
//Group by line no //Group by line no
// For everything but the first one, strip out the price number in // For everything but the first one, strip out the price number in
// InstanceRenderManager({executeFunction:true, args:[], promanager: () => { InstanceRenderManager({
// const groupedByLineRef = _.groupBy(estData.joblines.data, "line_ref"); executeFunction: true,
// Object.keys(groupedByLineRef).forEach((lineRef) => { args: [],
// let index0ActPrice; promanager: () => {
// groupedByLineRef[lineRef].forEach((line, index) => { const groupedByLineRef = _.groupBy(estData.joblines.data, "line_ref");
// //Let the first one keep it Object.keys(groupedByLineRef).forEach((lineRef) => {
// if (index === 0){ let index0ActPrice;
// index0ActPrice = line.act_price; groupedByLineRef[lineRef].forEach((line, index) => {
// return;} //Let the first one keep it
// //Web Est seems to have additional costs with UNQ_SEQ 0. Keep them all? if (index === 0) {
// if (line.unq_seq === 0) return; index0ActPrice = line.act_price;
// if(index0ActPrice !== line.act_price){ return;
// line.notes += ` | Price override.`; }
// return; //Web Est seems to have additional costs with UNQ_SEQ 0. Keep them all?
// } if (line.unq_seq === 0) return;
// const indexInEstData = estData.joblines.data.findIndex( if (index0ActPrice !== line.act_price) {
// (l) => l.unq_seq === line.unq_seq line.notes += ` | Price override.`;
// ); return;
// estData.joblines.data[ }
// indexInEstData const indexInEstData = estData.joblines.data.findIndex((l) => l.unq_seq === line.unq_seq);
// ].notes += ` | Scrubbed due to the line_ref issue. (prev act price = ${estData.joblines.data[indexInEstData].act_price})`; estData.joblines.data[
// estData.joblines.data[indexInEstData].act_price = 0; indexInEstData
// estData.joblines.data[indexInEstData].db_price = 0; ].notes += ` | Scrubbed due to the line_ref issue. (prev act price = ${estData.joblines.data[indexInEstData].act_price})`;
// }); estData.joblines.data[indexInEstData].act_price = 0;
// }) estData.joblines.data[indexInEstData].db_price = 0;
// }}) });
});
}
});
InstanceRenderManager({ InstanceRenderManager({
executeFunction: true, executeFunction: true,

View File

@@ -8,16 +8,18 @@ import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
import { UPDATE_PAYMENT } from "../../graphql/payments.queries"; import { UPDATE_PAYMENT } from "../../graphql/payments.queries";
import { setModalContext } from "../../redux/modals/modals.actions"; import { setModalContext } from "../../redux/modals/modals.actions";
import { selectCurrentUser } from "../../redux/user/user.selectors"; import { selectCurrentUser } from "../../redux/user/user.selectors";
import { selectPayment } from "../../redux/modals/modals.selectors";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser currentUser: selectCurrentUser,
paymentModal: selectPayment
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
setPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "payment" })) setPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "payment" }))
}); });
const PaymentMarkForExportButton = ({ bodyshop, payment, refetch, setPaymentContext, currentUser }) => { const PaymentMarkForExportButton = ({ bodyshop, payment, refetch, setPaymentContext, currentUser, paymentModal }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [insertExportLog, { loading: exportLogLoading }] = useMutation(INSERT_EXPORT_LOG); const [insertExportLog, { loading: exportLogLoading }] = useMutation(INSERT_EXPORT_LOG);
const [updatePayment, { loading: updatePaymentLoading }] = useMutation(UPDATE_PAYMENT); const [updatePayment, { loading: updatePaymentLoading }] = useMutation(UPDATE_PAYMENT);
@@ -56,16 +58,19 @@ const PaymentMarkForExportButton = ({ bodyshop, payment, refetch, setPaymentCont
refetch refetch
}, },
context: { context: {
...paymentModal.context,
...payment, ...payment,
exportedat: today exportedat: today
} }
}); });
if (refetch) if (refetch) {
refetch( if (paymentModal.context.refetchRequiresContext) {
paymentUpdateResponse && refetch(paymentUpdateResponse && paymentUpdateResponse.data.update_payments.returning[0]);
paymentUpdateResponse.data.update_payments.returning[0] } else {
); refetch();
}
}
} else { } else {
notification["error"]({ notification["error"]({
message: t("payments.errors.exporting", { message: t("payments.errors.exporting", {

View File

@@ -1,5 +1,4 @@
import { useMutation } from "@apollo/client"; import { useMutation } from "@apollo/client";
import { Button, Form, Modal, notification, Space } from "antd"; import { Button, Form, Modal, notification, Space } from "antd";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -91,7 +90,13 @@ function PaymentModalContainer({ paymentModal, toggleModalVisible, bodyshop, cur
} }
} }
if (actions.refetch) actions.refetch(updatedPayment && updatedPayment.data.update_payments.returning[0]); if (actions.refetch) {
if (context.refetchRequiresContext) {
actions.refetch(updatedPayment && updatedPayment.data.update_payments.returning[0]);
} else {
actions.refetch();
}
}
if (enterAgain) { if (enterAgain) {
const prev = form.getFieldsValue(["date"]); const prev = form.getFieldsValue(["date"]);
@@ -166,13 +171,7 @@ function PaymentModalContainer({ paymentModal, toggleModalVisible, bodyshop, cur
</Space> </Space>
)} )}
<Form <Form onFinish={handleFinish} autoComplete={"off"} form={form} layout="vertical" disabled={context?.exportedat}>
onFinish={handleFinish}
autoComplete={"off"}
form={form}
layout="vertical"
disabled={context?.exportedat}
>
<PaymentForm form={form} /> <PaymentForm form={form} />
</Form> </Form>
</Modal> </Modal>

View File

@@ -5,12 +5,18 @@ import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { UPDATE_PAYMENT } from "../../graphql/payments.queries"; import { UPDATE_PAYMENT } from "../../graphql/payments.queries";
import { setModalContext } from "../../redux/modals/modals.actions"; import { setModalContext } from "../../redux/modals/modals.actions";
import { selectPayment } from "../../redux/modals/modals.selectors";
import { createStructuredSelector } from "reselect";
const mapStateToProps = createStructuredSelector({
paymentModal: selectPayment
});
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
setPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "payment" })) setPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "payment" }))
}); });
const PaymentReexportButton = ({ payment, refetch, setPaymentContext }) => { const PaymentReexportButton = ({ paymentModal, payment, refetch, setPaymentContext }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [updatePayment, { loading }] = useMutation(UPDATE_PAYMENT); const [updatePayment, { loading }] = useMutation(UPDATE_PAYMENT);
@@ -34,15 +40,19 @@ const PaymentReexportButton = ({ payment, refetch, setPaymentContext }) => {
refetch refetch
}, },
context: { context: {
...paymentModal.context,
...payment, ...payment,
exportedat: null exportedat: null
} }
}); });
if (refetch)
refetch( if (refetch) {
paymentUpdateResponse && if (paymentModal.context.refetchRequiresContext) {
paymentUpdateResponse.data.update_payments.returning[0] refetch(paymentUpdateResponse && paymentUpdateResponse.data.update_payments.returning[0]);
); } else {
refetch();
}
}
} else { } else {
notification["error"]({ notification["error"]({
message: t("payments.errors.exporting", { message: t("payments.errors.exporting", {
@@ -59,4 +69,4 @@ const PaymentReexportButton = ({ payment, refetch, setPaymentContext }) => {
); );
}; };
export default connect(null, mapDispatchToProps)(PaymentReexportButton); export default connect(mapStateToProps, mapDispatchToProps)(PaymentReexportButton);

View File

@@ -171,7 +171,7 @@ export function PaymentsListPaginated({
} }
: refetch : refetch
}, },
context: apolloResults ? apolloResults : record context: { ...(apolloResults ? apolloResults : record), refetchRequiresContext: true }
}); });
}} }}
> >

View File

@@ -41,7 +41,7 @@ export const QUERY_AVAILABLE_CC = gql`
`; `;
export const CHECK_CC_FLEET_NUMBER = gql` export const CHECK_CC_FLEET_NUMBER = gql`
query CHECK_VENDOR_NAME($name: String!) { query CHECK_CC_FLEET_NUMBER($name: String!) {
courtesycars_aggregate(where: { fleetnumber: { _ilike: $name } }) { courtesycars_aggregate(where: { fleetnumber: { _ilike: $name } }) {
aggregate { aggregate {
count count

View File

@@ -216,7 +216,7 @@ export function BillsListPage({ loading, data, refetch, total, setPartsOrderCont
extra={ extra={
<Space wrap> <Space wrap>
{search.search && ( {search.search && (
<> <Space align="center">
<Typography.Title level={4}> <Typography.Title level={4}>
{t("general.labels.searchresults", { search: search.search })} {t("general.labels.searchresults", { search: search.search })}
</Typography.Title> </Typography.Title>
@@ -229,7 +229,7 @@ export function BillsListPage({ loading, data, refetch, total, setPartsOrderCont
> >
{t("general.actions.clear")} {t("general.actions.clear")}
</Button> </Button>
</> </Space>
)} )}
<Button onClick={() => refetch()}> <Button onClick={() => refetch()}>
<SyncOutlined /> <SyncOutlined />

View File

@@ -72,7 +72,11 @@ export function CourtesyCarCreateContainer({ bodyshop, setBreadcrumbs, setSelect
<RbacWrapper action="courtesycar:create"> <RbacWrapper action="courtesycar:create">
<FeatureWrapperComponent featureName="courtesycars"> <FeatureWrapperComponent featureName="courtesycars">
<Form form={form} autoComplete="new-password" onFinish={handleFinish} layout="vertical"> <Form form={form} autoComplete="new-password" onFinish={handleFinish} layout="vertical">
<CourtesyCarFormComponent form={form} saveLoading={loading} /> <CourtesyCarFormComponent
form={form}
saveLoading={loading}
newCC={true}
/>
</Form> </Form>
</FeatureWrapperComponent> </FeatureWrapperComponent>
</RbacWrapper> </RbacWrapper>

View File

@@ -223,8 +223,9 @@
"markexported": "Mark Exported", "markexported": "Mark Exported",
"markforreexport": "Mark for Re-export", "markforreexport": "Mark for Re-export",
"new": "New Bill", "new": "New Bill",
"nobilllines": "This part has not yet been recieved.",
"noneselected": "No bill selected.", "noneselected": "No bill selected.",
"onlycmforinvoiced": "Only credit memos can be entered for any Job that has been invoiced, exported, or voided.", "onlycmforinvoiced": "Only credit memos can be entered for any Job that has been invoiced, exported, or voided.",
"printlabels": "Print Labels", "printlabels": "Print Labels",
"retailtotal": "Bills Retail Total", "retailtotal": "Bills Retail Total",
"savewithdiscrepancy": "You are about to save this bill with a discrepancy. The system will continue to use the calculated amount using the bill lines. Press cancel to return to the bill.", "savewithdiscrepancy": "You are about to save this bill with a discrepancy. The system will continue to use the calculated amount using the bill lines. Press cancel to return to the bill.",

View File

@@ -969,6 +969,7 @@
- md_rbac - md_rbac
- md_referral_sources - md_referral_sources
- md_responsibility_centers - md_responsibility_centers
- md_ro_guard
- md_ro_statuses - md_ro_statuses
- md_tasks_presets - md_tasks_presets
- md_to_emails - md_to_emails
@@ -1068,6 +1069,7 @@
- md_rbac - md_rbac
- md_referral_sources - md_referral_sources
- md_responsibility_centers - md_responsibility_centers
- md_ro_guard
- md_ro_statuses - md_ro_statuses
- md_tasks_presets - md_tasks_presets
- md_to_emails - md_to_emails

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."bodyshops" add column "md_ro_guard" jsonb
-- null default jsonb_build_object();

View File

@@ -0,0 +1,2 @@
alter table "public"."bodyshops" add column "md_ro_guard" jsonb
null default jsonb_build_object();

View File

@@ -770,7 +770,7 @@ const getAdditionalCostCenter = (jl, profitCenters) => {
return profitCenters["TOW"]; return profitCenters["TOW"];
} else if (jl.act_price > 0) { } else if (jl.act_price > 0) {
//TODO:AIO Ensure that this is tested. //TODO:AIO Ensure that this is tested.
ret.profitcenter_part = defaults.profits["PAO"]; return profitCenters["PAO"];
} else { } else {
return null; return null;
} }