IO-793 Add additional job totals calculations to pli.
This commit is contained in:
@@ -2055,6 +2055,48 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>creditsnotreceived</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>creditsreceived</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>dedfromlbr</name>
|
<name>dedfromlbr</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -2370,6 +2412,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>totalreturns</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
</children>
|
</children>
|
||||||
</folder_node>
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ import AlertComponent from "../alert/alert.component";
|
|||||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||||
import "./job-bills-total.styles.scss";
|
import "./job-bills-total.styles.scss";
|
||||||
|
|
||||||
export default function JobBillsTotalComponent({ loading, bills, jobTotals }) {
|
export default function JobBillsTotalComponent({
|
||||||
|
loading,
|
||||||
|
bills,
|
||||||
|
partsOrders,
|
||||||
|
jobTotals,
|
||||||
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
if (loading) return <LoadingSkeleton />;
|
if (loading) return <LoadingSkeleton />;
|
||||||
@@ -20,6 +25,19 @@ export default function JobBillsTotalComponent({ loading, bills, jobTotals }) {
|
|||||||
let billTotals = Dinero();
|
let billTotals = Dinero();
|
||||||
let billCms = Dinero();
|
let billCms = Dinero();
|
||||||
let lbrAdjustments = Dinero();
|
let lbrAdjustments = Dinero();
|
||||||
|
let totalReturns = Dinero();
|
||||||
|
|
||||||
|
partsOrders.forEach((p) =>
|
||||||
|
p.parts_order_lines.forEach((pol) => {
|
||||||
|
if (p.return) {
|
||||||
|
totalReturns = totalReturns.add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round((pol.cost || 0) * 100),
|
||||||
|
}).multiply(pol.quantity)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
bills.forEach((i) =>
|
bills.forEach((i) =>
|
||||||
i.billlines.forEach((il) => {
|
i.billlines.forEach((il) => {
|
||||||
@@ -50,11 +68,13 @@ export default function JobBillsTotalComponent({ loading, bills, jobTotals }) {
|
|||||||
const totalPartsSublet = Dinero(totals.parts.parts.total).add(
|
const totalPartsSublet = Dinero(totals.parts.parts.total).add(
|
||||||
Dinero(totals.parts.sublets.total)
|
Dinero(totals.parts.sublets.total)
|
||||||
);
|
);
|
||||||
|
|
||||||
const discrepancy = totalPartsSublet.subtract(billTotals);
|
const discrepancy = totalPartsSublet.subtract(billTotals);
|
||||||
|
|
||||||
const discrepWithLbrAdj = discrepancy.add(lbrAdjustments);
|
const discrepWithLbrAdj = discrepancy.add(lbrAdjustments);
|
||||||
|
|
||||||
const discrepWithCms = discrepWithLbrAdj.subtract(billCms);
|
const discrepWithCms = discrepWithLbrAdj.subtract(billCms);
|
||||||
|
const creditsNotReceived = totalReturns.subtract(billCms);
|
||||||
return (
|
return (
|
||||||
<Card title={t("jobs.labels.jobtotals")}>
|
<Card title={t("jobs.labels.jobtotals")}>
|
||||||
<Space wrap size="large">
|
<Space wrap size="large">
|
||||||
@@ -95,6 +115,21 @@ export default function JobBillsTotalComponent({ loading, bills, jobTotals }) {
|
|||||||
}}
|
}}
|
||||||
value={discrepWithCms.toFormat()}
|
value={discrepWithCms.toFormat()}
|
||||||
/>
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("bills.labels.totalreturns")}
|
||||||
|
value={totalReturns.toFormat()}
|
||||||
|
/>{" "}
|
||||||
|
<Statistic
|
||||||
|
title={t("bills.labels.creditsreceived")}
|
||||||
|
value={billCms.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("bills.labels.creditsnotreceived")}
|
||||||
|
valueStyle={{
|
||||||
|
color: creditsNotReceived.getAmount === 0 ? "green" : "red",
|
||||||
|
}}
|
||||||
|
value={creditsNotReceived.toFormat()}
|
||||||
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export default function JobsDetailPliComponent({
|
|||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<JobBillsTotal
|
<JobBillsTotal
|
||||||
bills={billsQuery.data ? billsQuery.data.bills : []}
|
bills={billsQuery.data ? billsQuery.data.bills : []}
|
||||||
|
partsOrders={billsQuery.data ? billsQuery.data.parts_orders : []}
|
||||||
loading={billsQuery.loading}
|
loading={billsQuery.loading}
|
||||||
jobTotals={job.job_totals}
|
jobTotals={job.job_totals}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -233,15 +233,12 @@ export function PartsOrderListTableComponent({
|
|||||||
state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("parts_orders.fields.db_price"),
|
title: t("parts_orders.fields.quantity"),
|
||||||
dataIndex: "db_price",
|
dataIndex: "quantity",
|
||||||
key: "db_price",
|
key: "quantity",
|
||||||
sorter: (a, b) => a.db_price - b.db_price,
|
sorter: (a, b) => a.quantity - b.quantity,
|
||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "db_price" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "quantity" && state.sortedInfo.order,
|
||||||
render: (text, record) => (
|
|
||||||
<CurrencyFormatter>{record.db_price}</CurrencyFormatter>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -255,7 +252,7 @@ export function PartsOrderListTableComponent({
|
|||||||
<CurrencyFormatter>{record.act_price}</CurrencyFormatter>
|
<CurrencyFormatter>{record.act_price}</CurrencyFormatter>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
...(selectedPartsOrderRecord && selectedPartsOrderRecord.isReturn
|
...(selectedPartsOrderRecord && selectedPartsOrderRecord.return
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
title: t("parts_orders.fields.cost"),
|
title: t("parts_orders.fields.cost"),
|
||||||
|
|||||||
@@ -141,6 +141,8 @@
|
|||||||
"bill_total": "Bill Total Amount",
|
"bill_total": "Bill Total Amount",
|
||||||
"billcmtotal": "Retail Total of Credit Memos",
|
"billcmtotal": "Retail Total of Credit Memos",
|
||||||
"bills": "Bills",
|
"bills": "Bills",
|
||||||
|
"creditsnotreceived": "Credits Not Received",
|
||||||
|
"creditsreceived": "Credits Received",
|
||||||
"dedfromlbr": "Deducted from Labor",
|
"dedfromlbr": "Deducted from Labor",
|
||||||
"deleteconfirm": "Are you sure you want to delete this bill? It cannot be undone. If this bill has deductions from labors, manual changes may be required.",
|
"deleteconfirm": "Are you sure you want to delete this bill? It cannot be undone. If this bill has deductions from labors, manual changes may be required.",
|
||||||
"discrepancy": "Discrepancy",
|
"discrepancy": "Discrepancy",
|
||||||
@@ -155,7 +157,8 @@
|
|||||||
"noneselected": "No bill selected.",
|
"noneselected": "No bill selected.",
|
||||||
"retailtotal": "Retail Total of Bill (Ex. Taxes)",
|
"retailtotal": "Retail Total of Bill (Ex. Taxes)",
|
||||||
"state_tax": "State Tax",
|
"state_tax": "State Tax",
|
||||||
"subtotal": "Subtotal"
|
"subtotal": "Subtotal",
|
||||||
|
"totalreturns": "Total Returns"
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"created": "Invoice added successfully.",
|
"created": "Invoice added successfully.",
|
||||||
|
|||||||
@@ -141,6 +141,8 @@
|
|||||||
"bill_total": "",
|
"bill_total": "",
|
||||||
"billcmtotal": "",
|
"billcmtotal": "",
|
||||||
"bills": "",
|
"bills": "",
|
||||||
|
"creditsnotreceived": "",
|
||||||
|
"creditsreceived": "",
|
||||||
"dedfromlbr": "",
|
"dedfromlbr": "",
|
||||||
"deleteconfirm": "",
|
"deleteconfirm": "",
|
||||||
"discrepancy": "",
|
"discrepancy": "",
|
||||||
@@ -155,7 +157,8 @@
|
|||||||
"noneselected": "",
|
"noneselected": "",
|
||||||
"retailtotal": "",
|
"retailtotal": "",
|
||||||
"state_tax": "",
|
"state_tax": "",
|
||||||
"subtotal": ""
|
"subtotal": "",
|
||||||
|
"totalreturns": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"created": "",
|
"created": "",
|
||||||
|
|||||||
@@ -141,6 +141,8 @@
|
|||||||
"bill_total": "",
|
"bill_total": "",
|
||||||
"billcmtotal": "",
|
"billcmtotal": "",
|
||||||
"bills": "",
|
"bills": "",
|
||||||
|
"creditsnotreceived": "",
|
||||||
|
"creditsreceived": "",
|
||||||
"dedfromlbr": "",
|
"dedfromlbr": "",
|
||||||
"deleteconfirm": "",
|
"deleteconfirm": "",
|
||||||
"discrepancy": "",
|
"discrepancy": "",
|
||||||
@@ -155,7 +157,8 @@
|
|||||||
"noneselected": "",
|
"noneselected": "",
|
||||||
"retailtotal": "",
|
"retailtotal": "",
|
||||||
"state_tax": "",
|
"state_tax": "",
|
||||||
"subtotal": ""
|
"subtotal": "",
|
||||||
|
"totalreturns": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"created": "",
|
"created": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user