import job from "../../fixtures/jobs/job-3.json"; import job2 from "../../fixtures/jobs/job-4.json"; import moment from "moment"; import Dinero from "dinero.js"; const uuid = () => Cypress._.random(0, 1e6); describe( "Billing job parts orders", { defaultCommandTimeout: 5000, }, () => { const today = moment(new Date()).format("YYYY-MM-DD"); beforeEach(() => { cy.viewport(1280, 720); cy.visit("/manage/jobs"); cy.intercept("POST", Cypress.env("graphql_dev_endpoint"), (req) => { if (req.body.operationName === "SEARCH_VENDOR_AUTOCOMPLETE") { req.alias = "vendors"; } }); cy.get('[data-cy="active-jobs-table"]') .find(".ant-table-tbody") .find("> tr:not(.ant-table-measure-row)") .as("active-jobs-table") .should("not.have.class", "ant-table-placeholder"); cy.get("@active-jobs-table") .contains(job.clm_no) .first() .parent() .find('[data-cy="active-job-link"]') .click(); // Go to repair data tab cy.get('[data-cy="tab-partssublet"]').should("be.visible").click(); }); it("receives a part 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 // data-cy="bill-form-invoice" cy.get('[data-cy="bill-form-invoice"]').type(uuid()); cy.get("#bill-form-date").click(); cy.get(`[title="${today}"]`).should("be.visible").click({ force: true }); cy.get('[data-cy="bill-line-table"]').each(($row) => { // get retail amount cy.wrap($row) .find('[data-cy="bill-line-actual-price"]') .click({ force: true, multiple: true }); cy.wrap($row) .find('[data-cy="bill-line-actual-cost"]') .click({ multiple: true }); }); cy.get('[data-cy="bill-line-actual-cost"]').then((cells) => { const totals = cells.toArray().map((el) => Number(el.value)); const sum = Cypress._.sum(totals); cy.get('[data-cy="bill-form-bill-total"]').type(sum); }); // // Click save cy.get('[data-cy="bill-form-save-button"]').click(); cy.get(".ant-notification-notice-message").contains( "Invoice added successfully." ); }); it("posts bill directly", () => { cy.get('[data-cy="bills-post-button"]').should("be.visible").click(); // Add New Line cy.get('[data-cy="bill-line-add-button"]') .should("not.be.disabled") .click(); // Select Vendor cy.antdSelect("bill-vendor"); // Select Line cy.antdSelect("bill-line", "-- Not On Estimate --"); // Fill the Form cy.get('[data-cy="bill-form-invoice"]').type(uuid()); cy.get("#bill-form-date").click(); cy.get(`[title="${today}"]`).should("be.visible").click({ force: true }); cy.get('[data-cy="bill-line-table"]').each(($row) => { // get retail amount cy.wrap($row) .find('[data-cy="bill-line-actual-price"]') .click({ force: true, multiple: true }); cy.wrap($row) .find('[data-cy="bill-line-actual-cost"]') .click({ multiple: true }); }); cy.get('[data-cy="bill-line-actual-cost"]').then((cells) => { const totals = cells.toArray().map((el) => Number(el.value)); const sum = Cypress._.sum(totals); cy.get('[data-cy="bill-form-bill-total"]').type(sum); }); cy.antdSelect("bill-cost-center"); // Click save cy.get('[data-cy="bill-form-save-button"]').click(); cy.get(".ant-notification-notice-message").contains( "Invoice added successfully." ); }); it("posts a bill with save and new", () => { cy.get('[data-cy="bills-post-button"]').should("be.visible").click(); // Add New Line cy.get('[data-cy="bill-line-add-button"]') .should("not.be.disabled") .click(); // Select Vendor cy.antdSelect("bill-vendor"); // Select Line cy.antdSelect("bill-line", "-- Not On Estimate --"); // Fill the Form cy.get('[data-cy="bill-form-invoice"]').type(uuid()); cy.get("#bill-form-date").click(); cy.get(`[title="${today}"]`).should("be.visible").click({ force: true }); cy.get('[data-cy="bill-line-table"]').each(($row) => { // get retail amount cy.wrap($row) .find('[data-cy="bill-line-actual-price"]') .click({ force: true, multiple: true }); cy.wrap($row) .find('[data-cy="bill-line-actual-cost"]') .click({ multiple: true }); }); cy.get('[data-cy="bill-line-actual-cost"]').then((cells) => { const totals = cells.toArray().map((el) => Number(el.value)); const sum = Cypress._.sum(totals); cy.get('[data-cy="bill-form-bill-total"]').type(sum); }); cy.antdSelect("bill-cost-center"); // Click save cy.get('[data-cy="bill-form-savenew-button"]') .should("not.be.disabled") .click(); cy.get(".ant-notification-notice-message").contains( "Invoice added successfully." ); }); it("uploads a document to a bill", () => { 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("be.visible") .find('[data-cy="edit-bill-button"]') .click(); cy.location("search").should("include", "billid"); cy.get('[data-cy="bill-edit-form"]') .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.only( "Validating and calculating bills", { defaultCommandTimeout: 10000, }, () => { const today = moment(new Date()).format("YYYY-MM-DD"); const jobLines = job2.joblines.data.filter( (line) => line.part_type === "PAS" || line.part_type === "PAE" ); const linesTotal = jobLines.reduce( (prev, line) => prev + line.act_price, 0 ); beforeEach(() => { cy.viewport(1280, 720); cy.visit("/manage/jobs"); cy.intercept("POST", Cypress.env("graphql_dev_endpoint"), (req) => { if (req.body.operationName === "SEARCH_VENDOR_AUTOCOMPLETE") { req.alias = "vendors"; } }); cy.get('[data-cy="active-jobs-table"]') .find(".ant-table-tbody") .find("> tr:not(.ant-table-measure-row)") .as("active-jobs-table") .should("not.have.class", "ant-table-placeholder"); cy.get("@active-jobs-table") .contains(job2.clm_no) .first() .parent() .find('[data-cy="active-job-link"]') .click(); // 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(uuid()); cy.get("#bill-form-date").click(); cy.get(`[title="${today}"]`).should("be.visible").click({ force: true }); cy.get('[data-cy="bill-line-table"]').each(($row) => { // get retail amount cy.wrap($row) .find('[data-cy="bill-line-actual-price"]') .as("retailPrice") .click({ force: true, multiple: true }); cy.wrap($row) .find('[data-cy="bill-line-actual-cost"]') .click({ multiple: true }); }); cy.get('[data-cy="bill-line-actual-cost"]').then((cells) => { const totals = cells.toArray().map((el) => Number(el.value)); const sum = Cypress._.sum(totals); cy.get('[data-cy="bill-form-bill-total"]').type(sum); // Get taxes add it to the sum cy.get('[data-cy="bill-form-tax"]').then((taxes) => { const subtotals = taxes .toArray() .map((el) => Number(el.innerText.substring(1))); const totalTax = Cypress._.sum(subtotals); const billAmount = sum + totalTax; cy.get('[data-cy="bill-form-bill-total"]') .find("input") .clear() .type(billAmount); }); }); cy.get("#bill-form-discrepancy").should("have.text", "$0.00"); // Click save cy.get('[data-cy="bill-form-save-button"]').click(); cy.get("@retailPrice") .invoke("val") .then((val) => { const discrepancy = linesTotal - Number(val); cy.get("#retailtotal").should("have.text", `$${val}`); cy.get(".discrepancy").each(($statistic) => { cy.wrap($statistic).should( "have.text", Dinero({ amount: discrepancy, precision: 0, }).toFormat() ); }); }); }); it.only("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") .find('[data-cy="credit-memo-checkbox"]') .filter(":not(:checked)") .first() .should("not.be.disabled") .parent() .parent() .parent() .parent() .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('[data-cy="billline-actual-price"]') .find(".ant-form-item-control-input-content") .then((prices) => { const totals = prices .toArray() .map((el) => Number(el.innerText.substring(1))); const sum = Cypress._.sum(totals); const price = Dinero({ amount: sum * 100, }).toFormat(); cy.get('[data-cy="order-quantity"]').each((input) => { cy.wrap(input).type("1"); }); cy.get('[data-cy="part-order-select-none"]').click(); cy.get('[data-cy="order-part-submit"]').click(); cy.get("#totalReturns").should("have.text", price); cy.get("#calculatedcreditsnotreceived").should("have.text", price); cy.get("#creditsnotreceived").should("have.text", price); }); }); 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(uuid()); cy.get("#bill-form-date").click(); cy.get(`[title="${today}"]`).should("be.visible").click({ force: true }); cy.get('[data-cy="bill-line-table"]').each(($row) => { // get retail amount cy.wrap($row) .find('[data-cy="bill-line-actual-price"]') .click({ force: true, multiple: true }); cy.wrap($row) .find('[data-cy="bill-line-actual-cost"]') .click({ multiple: true }); }); cy.get('[data-cy="bill-line-actual-cost"]').then((cells) => { cy.get('[data-cy="bill-line-actual-price"]').then((priceCells) => { const totals = cells.toArray().map((el) => Number(el.value)); const priceTotals = priceCells .toArray() .map((el) => Number(el.value)); const sum = Cypress._.sum(totals); const priceSum = Cypress._.sum(priceTotals); cy.get('[data-cy="bill-form-bill-total"]').type(sum); // Get taxes add it to the sum cy.get('[data-cy="bill-form-tax"]').then((taxes) => { const subtotals = taxes .toArray() .map((el) => Number(el.innerText.substring(1))); const totalTax = Cypress._.sum(subtotals); const billAmount = sum + totalTax; cy.get('[data-cy="bill-form-bill-total"]') .find("input") .clear() .type(billAmount); }); cy.get("#bill-form-discrepancy").should("have.text", "$0.00"); cy.get('[data-cy="bill-form-save-button"]').click(); cy.get("#totalReturns") .invoke("text") .then((value) => { // TODO check if negative transform to 0 const totalReturns = Number(value.substring(1)) - priceSum < 0 ? 0 : Number(value.substring(1)) - priceSum; cy.get("#calculatedcreditsnotreceived").should( "have.text", Dinero({ amount: totalReturns, precision: 0, }).toFormat() ); }); }); }); }); 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(uuid()); cy.get("#bill-form-date").click(); cy.get(`[title="${today}"]`).should("be.visible").click({ force: true }); cy.get('[data-cy="bill-line-table"]').each(($row) => { // get retail amount cy.wrap($row) .find('[data-cy="bill-line-actual-price"]') .click({ force: true, multiple: true }); cy.wrap($row) .find('[data-cy="bill-line-actual-cost"]') .click({ multiple: true }); }); cy.get('[data-cy="bill-line-actual-cost"]').then((cells) => { const totals = cells.toArray().map((el) => Number(el.value)); const sum = Cypress._.sum(totals); cy.get('[data-cy="bill-form-bill-total"]').type(sum); // Get taxes add it to the sum cy.get('[data-cy="bill-form-tax"]').then((taxes) => { const subtotals = taxes .toArray() .map((el) => Number(el.innerText.substring(1))); const totalTax = Cypress._.sum(subtotals); const billAmount = sum + totalTax; cy.get('[data-cy="bill-form-bill-total"]') .find("input") .clear() .type(billAmount); }); }); 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(); // TODO add assertion to the total cy.get("#calculatedcreditsnotreceived").should("have.text", "$0.00"); cy.get("#creditsnotreceived").should("have.text", "$0.00"); }); // TODO add more assertions to the parts table 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."); }); } );