From fc09871a472e039c30308ffd5c75f19dff5613ca Mon Sep 17 00:00:00 2001 From: swtmply Date: Mon, 3 Jul 2023 09:06:58 +0800 Subject: [PATCH] IO-2327 posting bills tests cases --- .../e2e/posting-bills/posting-bills.cy.js | 272 +++++++++++++++++- .../bill-cm-returns-table.component.jsx | 2 +- .../bill-detail-edit-component.jsx | 10 +- .../bill-detail-edit-return.component.jsx | 8 +- .../bill-form/bill-form.component.jsx | 7 +- .../bill-mark-exported-button.component.jsx | 8 +- .../bill-reexport-button.component.jsx | 8 +- .../bills-list-table.component.jsx | 4 +- .../job-bills-total.component.jsx | 70 +++-- .../job-lines-expander.component.jsx | 12 +- .../parts-order-list-table.component.jsx | 7 +- .../parts-order-modal.component.jsx | 8 +- 12 files changed, 370 insertions(+), 46 deletions(-) diff --git a/client/cypress/e2e/posting-bills/posting-bills.cy.js b/client/cypress/e2e/posting-bills/posting-bills.cy.js index 14ed8d03e..5df985be3 100644 --- a/client/cypress/e2e/posting-bills/posting-bills.cy.js +++ b/client/cypress/e2e/posting-bills/posting-bills.cy.js @@ -52,10 +52,10 @@ describe( // fill out form // data-cy="bill-form-invoice" - cy.get('[data-cy="bill-form-invoice"]').type(uniqueId()); + cy.get('[data-cy="bill-form-invoice"]').type(uniqueId("QBD246-00-")); cy.get("#bill-form-date").click(); - cy.get('[title="2023-06-22"]').should("be.visible").click(); + cy.get('[title="2023-06-30"]').should("be.visible").click(); // get table cy.get('[data-cy="bill-line-table"]').each(($row) => { @@ -75,9 +75,7 @@ describe( }); // Click save - cy.get('[data-cy="bill-form-save-button"]') - .should("not.be.disabled") - .click(); + cy.get('[data-cy="bill-form-save-button"]').click(); cy.get(".ant-notification-notice-message").contains( "Invoice added successfully." @@ -96,10 +94,10 @@ describe( // Select Line cy.antdSelect("bill-line", "-- Not On Estimate --"); // Fill the Form - cy.get('[data-cy="bill-form-invoice"]').type(uniqueId("DBP")); + cy.get('[data-cy="bill-form-invoice"]').type(uniqueId("QBD246-01-")); cy.get("#bill-form-date").click(); - cy.get('[title="2023-06-22"]').should("be.visible").click(); + cy.get('[title="2023-06-30"]').should("be.visible").click(); // get table cy.get('[data-cy="bill-line-table"]').each(($row) => { @@ -119,9 +117,7 @@ describe( }); // Click save - cy.get('[data-cy="bill-form-save-button"]') - .should("not.be.disabled") - .click(); + cy.get('[data-cy="bill-form-save-button"]').click(); cy.get(".ant-notification-notice-message").contains( "Invoice added successfully." @@ -140,10 +136,10 @@ describe( // Select Line cy.antdSelect("bill-line", "-- Not On Estimate --"); // Fill the Form - cy.get('[data-cy="bill-form-invoice"]').type(uniqueId("DBP")); + cy.get('[data-cy="bill-form-invoice"]').type(uniqueId("QBD246-02-")); cy.get("#bill-form-date").click(); - cy.get('[title="2023-06-22"]').should("be.visible").click(); + cy.get('[title="2023-06-30"]').should("be.visible").click(); // get table cy.get('[data-cy="bill-line-table"]').each(($row) => { @@ -190,5 +186,257 @@ describe( .find(".ant-upload #bill-document-upload") .selectFile("job.json", { force: true }); }); + + it("marks bill as exported", () => { + cy.get('[data-cy="bills-table"]') + .find(".ant-table-tbody") + .find("> tr:not(.ant-table-measure-row)") + .as("bills-table") + .should("not.have.class", "ant-table-placeholder"); + + cy.get("@bills-table") + .find('[data-cy="bill-exported-checkbox"]') + .not(":checked") + .first() + .as("export-status") + .parent() + .parent() + .parent() + .parent() + .find('[data-cy="edit-bill-button"]') + .click(); + + cy.location("search").should("include", "billid"); + cy.get('[data-cy="bill-mark-export-button"]') + .as("mark-for-export") + .click(); + cy.get("@mark-for-export").should("be.disabled"); + }); + + it("marks bill for re-export", () => { + cy.get('[data-cy="bills-table"]') + .find(".ant-table-tbody") + .find("> tr:not(.ant-table-measure-row)") + .as("bills-table") + .should("not.have.class", "ant-table-placeholder"); + + cy.get("@bills-table") + .find('[data-cy="bill-exported-checkbox"]') + .filter(":checked") + .first() + .as("export-status") + .parent() + .parent() + .parent() + .parent() + .find('[data-cy="edit-bill-button"]') + .click(); + + cy.location("search").should("include", "billid"); + cy.get('[data-cy="bill-mark-reexport-button"]') + .as("mark-for-reexport") + .click(); + cy.get("@mark-for-reexport").should("be.disabled"); + }); + } +); + +describe( + "Validating and calculating bills", + { + defaultCommandTimeout: 5000, + }, + () => { + beforeEach(() => { + cy.visit("/manage"); + + cy.get("body").then(($body) => { + if ($body.text().includes("Login")) { + // Log in + cy.get('[data-cy="username"]').type("john@imex.dev"); + cy.get('[data-cy="password"]').type("john123"); + cy.get('[data-cy="sign-in-button"]').click(); + } + + cy.get(".ant-table-tbody") + .should("be.visible") + .find("tr") + .should("not.have.class", "ant-table-placeholder"); + + cy.get(".ant-table-row").contains("QBD261").click(); + + cy.url().should("include", "/manage/jobs"); + + // Go to repair data tab + cy.get('[data-cy="tab-partssublet"]').should("be.visible").click(); + }); + }); + + it("validates auto reconciliation through posting bill", () => { + // Find the first row in the parts order + cy.get('[data-cy="part-orders-table"]') + .find(".ant-table-tbody") + .find("> tr:not(.ant-table-measure-row)") + .as("orders-table") + .should("not.have.class", "ant-table-placeholder"); + + cy.get("@orders-table") + .first() + .should("be.visible") + .find('[data-cy="receive-bill-button"]') + .click(); + + // fill out form + cy.get('[data-cy="bill-form-invoice"]').type(uniqueId("QBD261-0")); + + cy.get("#bill-form-date").click(); + cy.get('[title="2023-06-30"]').should("be.visible").click(); + + cy.get('[data-cy="bill-form-bill-total"]').type("70.46"); + cy.get('[data-cy="bill-line-actual-cost"]').type("67.10"); + + cy.get("#bill-form-discrepancy").should("have.text", "$0.00"); + + // Click save + cy.get('[data-cy="bill-form-save-button"]').click(); + + cy.get("#retailtotal").should("have.text", "$83.87"); + + cy.get(".discrepancy").each(($statistic) => { + cy.wrap($statistic).should("have.text", "$0.00"); + }); + }); + + it("returning item and validating statistics", () => { + cy.get('[data-cy="bills-table"]') + .find(".ant-table-tbody") + .find("> tr:not(.ant-table-measure-row)") + .as("bills-table") + .should("not.have.class", "ant-table-placeholder"); + + cy.get("@bills-table") + .first() + .should("not.be.disabled") + .find('[data-cy="return-items-button"]') + .click(); + + cy.get('[data-cy="billline-checkbox"]').check(); + cy.get('[data-cy="billline-return-items-ok-button"]').click(); + + cy.get("#order-quantity").type("1", { force: true, multiple: true }); + cy.get('[data-cy="part-order-select-none"]').click({ + multiple: true, + force: true, + }); + cy.get('[data-cy="order-part-submit"]').click({ + multiple: true, + force: true, + }); + + cy.get("#totalReturns").should("have.text", "$83.87"); + cy.get("#calculatedcreditsnotreceived").should("have.text", "$83.87"); + cy.get("#creditsnotreceived").should("have.text", "$83.87"); + }); + + it("receives credit memo without return part", () => { + // Find the first row in the parts order + cy.get('[data-cy="part-orders-table"]') + .find(".ant-table-tbody") + .find("> tr:not(.ant-table-measure-row)") + .as("orders-table") + .should("not.have.class", "ant-table-placeholder"); + + cy.get("@orders-table") + .find('[data-cy="part-order-return-checkbox"]') + .filter(":checked") + .first() + .parent() + .parent() + .parent() + .parent() + .find('[data-cy="receive-bill-button"]') + .click(); + + // fill out form + cy.get('[data-cy="bill-form-invoice"]').type(uniqueId("QBD261-01-")); + + cy.get("#bill-form-date").click(); + cy.get('[title="2023-06-30"]').should("be.visible").click(); + + cy.get('[data-cy="bill-form-bill-total"]').type("70.46"); + cy.get('[data-cy="bill-line-actual-cost"]').type("67.10"); + + cy.get("#bill-form-discrepancy").should("have.text", "$0.00"); + + // Click save + cy.get('[data-cy="bill-form-save-button"]').click(); + + cy.get("#totalReturns").should("have.text", "$83.87"); + cy.get("#calculatedcreditsnotreceived").should("have.text", "$0.00"); + cy.get("#creditsnotreceived").should("have.text", "$83.87"); + }); + + it("receives credit memo with return part", () => { + // Find the first row in the parts order + cy.get('[data-cy="part-orders-table"]') + .find(".ant-table-tbody") + .find("> tr:not(.ant-table-measure-row)") + .as("orders-table") + .should("not.have.class", "ant-table-placeholder"); + + cy.get("@orders-table") + .find('[data-cy="part-order-return-checkbox"]') + .filter(":checked") + .first() + .parent() + .parent() + .parent() + .parent() + .find('[data-cy="receive-bill-button"]') + .click(); + + // fill out form + cy.get('[data-cy="bill-form-invoice"]').type(uniqueId("QBD261-02-")); + + cy.get("#bill-form-date").click(); + cy.get('[title="2023-06-30"]').should("be.visible").click(); + + cy.get('[data-cy="bill-form-bill-total"]').type("70.46"); + cy.get('[data-cy="bill-line-actual-cost"]').type("67.10"); + + cy.get("#bill-form-discrepancy").should("have.text", "$0.00"); + + cy.get('[data-cy="mark-as-received-checkbox"]').check(); + + // Click save + cy.get('[data-cy="bill-form-save-button"]').click(); + + cy.get("#totalReturns").should("have.text", "$83.87"); + cy.get("#calculatedcreditsnotreceived").should("have.text", "$0.00"); + cy.get("#creditsnotreceived").should("have.text", "$0.00"); + }); + + it("views the row expander if it has the order and bill", () => { + cy.get('[data-cy="tab-repairdata"]').should("be.visible").click(); + + cy.get('[data-cy="filter-parts-button"]') + .should("not.be.disabled") + .click(); + + cy.get('[data-cy="repair-data-table"]') + .find(".ant-table-tbody") + .find("> tr:not(.ant-table-measure-row)") + .first() + .next() + .find("td") + .first() + .click(); + + cy.get('[data-cy="parts-bills-order"]') + .should("be.visible") + .find("li") + .first() + .should("not.have.text", "This part has not yet been ordered."); + }); } ); diff --git a/client/src/components/bill-cm-returns-table/bill-cm-returns-table.component.jsx b/client/src/components/bill-cm-returns-table/bill-cm-returns-table.component.jsx index 47588ef1c..36101d552 100644 --- a/client/src/components/bill-cm-returns-table/bill-cm-returns-table.component.jsx +++ b/client/src/components/bill-cm-returns-table/bill-cm-returns-table.component.jsx @@ -117,7 +117,7 @@ export default function BillCmdReturnsTableComponent({ name={[field.name, "cm_received"]} valuePropName="checked" > - + diff --git a/client/src/components/bill-detail-edit/bill-detail-edit-component.jsx b/client/src/components/bill-detail-edit/bill-detail-edit-component.jsx index 1ed87c7c3..6b3769e64 100644 --- a/client/src/components/bill-detail-edit/bill-detail-edit-component.jsx +++ b/client/src/components/bill-detail-edit/bill-detail-edit-component.jsx @@ -194,8 +194,14 @@ export function BillDetailEditcontainer({ {t("general.actions.save")} - - + + } /> diff --git a/client/src/components/bill-detail-edit/bill-detail-edit-return.component.jsx b/client/src/components/bill-detail-edit/bill-detail-edit-return.component.jsx index 81571f8b0..ebd999269 100644 --- a/client/src/components/bill-detail-edit/bill-detail-edit-return.component.jsx +++ b/client/src/components/bill-detail-edit/bill-detail-edit-return.component.jsx @@ -77,11 +77,14 @@ export function BillDetailEditReturn({ return ( <> setVisible(false)} destroyOnClose title={t("bills.actions.return")} onOk={() => form.submit()} + okButtonProps={{ + "data-cy": "billline-return-items-ok-button", + }} >
- + @@ -173,6 +176,7 @@ export function BillDetailEditReturn({
); diff --git a/client/src/components/bill-reexport-button/bill-reexport-button.component.jsx b/client/src/components/bill-reexport-button/bill-reexport-button.component.jsx index 8ed0f3724..089a405f0 100644 --- a/client/src/components/bill-reexport-button/bill-reexport-button.component.jsx +++ b/client/src/components/bill-reexport-button/bill-reexport-button.component.jsx @@ -24,7 +24,12 @@ export default connect( mapDispatchToProps )(BillMarkForReexportButton); -export function BillMarkForReexportButton({ bodyshop, authLevel, bill }) { +export function BillMarkForReexportButton({ + bodyshop, + authLevel, + bill, + ...props +}) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); @@ -73,6 +78,7 @@ export function BillMarkForReexportButton({ bodyshop, authLevel, bill }) { loading={loading} disabled={!bill.exported} onClick={handleUpdate} + {...props} > {t("bills.labels.markforreexport")} diff --git a/client/src/components/bills-list-table/bills-list-table.component.jsx b/client/src/components/bills-list-table/bills-list-table.component.jsx index f455ae3cb..a109f4b1b 100644 --- a/client/src/components/bills-list-table/bills-list-table.component.jsx +++ b/client/src/components/bills-list-table/bills-list-table.component.jsx @@ -138,7 +138,9 @@ export function BillsListTableComponent({ sorter: (a, b) => a.exported - b.exported, sortOrder: state.sortedInfo.columnKey === "exported" && state.sortedInfo.order, - render: (text, record) => , + render: (text, record) => ( + + ), }, { title: t("general.labels.actions"), diff --git a/client/src/components/job-bills-total/job-bills-total.component.jsx b/client/src/components/job-bills-total/job-bills-total.component.jsx index 701ebe1c6..66f809958 100644 --- a/client/src/components/job-bills-total/job-bills-total.component.jsx +++ b/client/src/components/job-bills-total/job-bills-total.component.jsx @@ -127,7 +127,10 @@ export default function JobBillsTotalComponent({ > ( + {billTotals.toFormat()} + )} /> = @@ -145,7 +148,12 @@ export default function JobBillsTotalComponent({ valueStyle={{ color: discrepancy.getAmount() === 0 ? "green" : "red", }} - value={discrepancy.toFormat()} + // value={discrepancy.toFormat()} + valueRender={() => ( + + {discrepancy.toFormat()} + + )} /> + @@ -178,7 +186,12 @@ export default function JobBillsTotalComponent({ valueStyle={{ color: discrepWithLbrAdj.getAmount() === 0 ? "green" : "red", }} - value={discrepWithLbrAdj.toFormat()} + // value={discrepWithLbrAdj.toFormat()} + valueRender={() => ( + + {discrepWithLbrAdj.toFormat()} + + )} /> + @@ -193,7 +206,10 @@ export default function JobBillsTotalComponent({ > ( + {totalReturns.toFormat()} + )} /> = @@ -211,7 +227,12 @@ export default function JobBillsTotalComponent({ valueStyle={{ color: discrepWithCms.getAmount() === 0 ? "green" : "red", }} - value={discrepWithCms.toFormat()} + // value={discrepWithCms.toFormat()} + valueRender={() => ( + + {discrepWithCms.toFormat()} + + )} /> @@ -231,7 +252,10 @@ export default function JobBillsTotalComponent({ > ( + {totalReturns.toFormat()} + )} /> = 0 - ? calculatedCreditsNotReceived.toFormat() - : Dinero().toFormat() - } + // value={ + // calculatedCreditsNotReceived.getAmount() >= 0 + // ? calculatedCreditsNotReceived.toFormat() + // : Dinero().toFormat() + // } + valueRender={() => ( + + {calculatedCreditsNotReceived.getAmount() >= 0 + ? calculatedCreditsNotReceived.toFormat() + : Dinero().toFormat()} + + )} /> = 0 - ? totalReturnsMarkedNotReceived.toFormat() - : Dinero().toFormat() - } + // value={ + // totalReturnsMarkedNotReceived.getAmount() >= 0 + // ? totalReturnsMarkedNotReceived.toFormat() + // : Dinero().toFormat() + // } + valueRender={() => ( + + {totalReturnsMarkedNotReceived.getAmount() >= 0 + ? totalReturnsMarkedNotReceived.toFormat() + : Dinero().toFormat()} + + )} /> diff --git a/client/src/components/job-detail-lines/job-lines-expander.component.jsx b/client/src/components/job-detail-lines/job-lines-expander.component.jsx index 06e00c729..ffa11fe2f 100644 --- a/client/src/components/job-detail-lines/job-lines-expander.component.jsx +++ b/client/src/components/job-detail-lines/job-lines-expander.component.jsx @@ -22,12 +22,12 @@ export default function JobLinesExpander({ jobline, jobid }) { if (error) return ; return ( - + {t("parts_orders.labels.parts_orders")} - + {data.parts_order_lines.length > 0 ? ( data.parts_order_lines.map((line) => ( @@ -43,7 +43,7 @@ export default function JobLinesExpander({ jobline, jobid }) { )) ) : ( - + {t("parts_orders.labels.notyetordered")} )} @@ -51,7 +51,7 @@ export default function JobLinesExpander({ jobline, jobid }) { {t("bills.labels.bills")} - + {data.billlines.length > 0 ? ( data.billlines.map((line) => ( @@ -71,7 +71,7 @@ export default function JobLinesExpander({ jobline, jobid }) { - {`${t("billlines.fields.actual_cost")}: `} + {`${t("billlines.fields.actual_cost")}: `} {line.actual_cost} @@ -83,7 +83,7 @@ export default function JobLinesExpander({ jobline, jobid }) { )) ) : ( - + {t("parts_orders.labels.notyetordered")} )} diff --git a/client/src/components/parts-order-list-table/parts-order-list-table.component.jsx b/client/src/components/parts-order-list-table/parts-order-list-table.component.jsx index 311052947..e6f4434a2 100644 --- a/client/src/components/parts-order-list-table/parts-order-list-table.component.jsx +++ b/client/src/components/parts-order-list-table/parts-order-list-table.component.jsx @@ -246,7 +246,12 @@ export function PartsOrderListTableComponent({ sorter: (a, b) => a.return - b.return, sortOrder: state.sortedInfo.columnKey === "return" && state.sortedInfo.order, - render: (text, record) => , + render: (text, record) => ( + + ), }, { title: t("parts_orders.fields.deliver_by"), diff --git a/client/src/components/parts-order-modal/parts-order-modal.component.jsx b/client/src/components/parts-order-modal/parts-order-modal.component.jsx index 14d56d0fb..038d119f7 100644 --- a/client/src/components/parts-order-modal/parts-order-modal.component.jsx +++ b/client/src/components/parts-order-modal/parts-order-modal.component.jsx @@ -256,7 +256,7 @@ export function PartsOrderModalComponent({ }, ]} > - + setSendType(e.target.value)} > - + {t("general.labels.none")}