@@ -1,4 +1,4 @@
|
|||||||
<babeledit_project be_version="2.7.1" version="1.2">
|
<babeledit_project version="1.2" be_version="2.7.1">
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
BabelEdit project file
|
BabelEdit project file
|
||||||
@@ -2674,6 +2674,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>calculatedcreditsnotreceived</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>creditsnotreceived</name>
|
<name>creditsnotreceived</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -27096,6 +27117,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>calculatedcreditsnotreceived</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>creditmemos</name>
|
<name>creditmemos</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -159,11 +159,11 @@ function BillEnterModalContainer({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const markPolReceived = outstanding_returns.filter(
|
const markPolReceived =
|
||||||
(o) => o.cm_received === true
|
outstanding_returns &&
|
||||||
);
|
outstanding_returns.filter((o) => o.cm_received === true);
|
||||||
|
|
||||||
if (markPolReceived.length > 0) {
|
if (markPolReceived && markPolReceived.length > 0) {
|
||||||
const r2 = await updatePartsOrderLines({
|
const r2 = await updatePartsOrderLines({
|
||||||
variables: { partsLineIds: markPolReceived.map((p) => p.id) },
|
variables: { partsLineIds: markPolReceived.map((p) => p.id) },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ export function BillsListTableComponent({
|
|||||||
});
|
});
|
||||||
// const search = queryString.parse(useLocation().search);
|
// const search = queryString.parse(useLocation().search);
|
||||||
// const selectedBill = search.billid;
|
// const selectedBill = search.billid;
|
||||||
|
const [searchText, setSearchText] = useState("");
|
||||||
|
|
||||||
const Templates = TemplateList("bill");
|
const Templates = TemplateList("bill");
|
||||||
const bills = billsQuery.data ? billsQuery.data.bills : [];
|
const bills = billsQuery.data ? billsQuery.data.bills : [];
|
||||||
const { refetch } = billsQuery;
|
const { refetch } = billsQuery;
|
||||||
@@ -166,6 +168,24 @@ export function BillsListTableComponent({
|
|||||||
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
|
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const filteredBills = bills
|
||||||
|
? searchText === ""
|
||||||
|
? bills
|
||||||
|
: bills.filter(
|
||||||
|
(b) =>
|
||||||
|
(b.invoice_number || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(b.vendor.name || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(b.total || "")
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase())
|
||||||
|
)
|
||||||
|
: [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
title={t("bills.labels.bills")}
|
title={t("bills.labels.bills")}
|
||||||
@@ -206,8 +226,10 @@ export function BillsListTableComponent({
|
|||||||
|
|
||||||
<Input.Search
|
<Input.Search
|
||||||
placeholder={t("general.labels.search")}
|
placeholder={t("general.labels.search")}
|
||||||
|
value={searchText}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
setSearchText(e.target.value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
@@ -220,7 +242,7 @@ export function BillsListTableComponent({
|
|||||||
}}
|
}}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
dataSource={bills}
|
dataSource={filteredBills}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ export default function JobBillsTotalComponent({
|
|||||||
let billCms = Dinero();
|
let billCms = Dinero();
|
||||||
let lbrAdjustments = Dinero();
|
let lbrAdjustments = Dinero();
|
||||||
let totalReturns = Dinero();
|
let totalReturns = Dinero();
|
||||||
|
let totalReturnsMarkedNotReceived = Dinero();
|
||||||
|
let totalReturnsMarkedReceived = Dinero();
|
||||||
|
|
||||||
partsOrders.forEach((p) =>
|
partsOrders.forEach((p) =>
|
||||||
p.parts_order_lines.forEach((pol) => {
|
p.parts_order_lines.forEach((pol) => {
|
||||||
@@ -35,6 +37,24 @@ export default function JobBillsTotalComponent({
|
|||||||
amount: Math.round((pol.act_price || 0) * 100),
|
amount: Math.round((pol.act_price || 0) * 100),
|
||||||
}).multiply(pol.quantity)
|
}).multiply(pol.quantity)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (pol.cm_received === null) {
|
||||||
|
return; // Skip this calculation for bills posted prior to the CNR change.
|
||||||
|
} else {
|
||||||
|
if (pol.cm_received === false) {
|
||||||
|
totalReturnsMarkedNotReceived = totalReturnsMarkedNotReceived.add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round((pol.act_price || 0) * 100),
|
||||||
|
}).multiply(pol.quantity)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
totalReturnsMarkedReceived = totalReturnsMarkedReceived.add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round((pol.act_price || 0) * 100),
|
||||||
|
}).multiply(pol.quantity)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -73,7 +93,7 @@ export default function JobBillsTotalComponent({
|
|||||||
const discrepWithLbrAdj = discrepancy.add(lbrAdjustments);
|
const discrepWithLbrAdj = discrepancy.add(lbrAdjustments);
|
||||||
|
|
||||||
const discrepWithCms = discrepWithLbrAdj.add(totalReturns);
|
const discrepWithCms = discrepWithLbrAdj.add(totalReturns);
|
||||||
const creditsNotReceived = totalReturns.subtract(billCms); //billCms is tracked as a negative number.
|
const calculatedCreditsNotReceived = totalReturns.subtract(billCms); //billCms is tracked as a negative number.
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
@@ -213,6 +233,32 @@ export default function JobBillsTotalComponent({
|
|||||||
value={totalReturns.toFormat()}
|
value={totalReturns.toFormat()}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<div
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: t(
|
||||||
|
"jobs.labels.plitooltips.calculatedcreditsnotreceived"
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Statistic
|
||||||
|
title={t("bills.labels.calculatedcreditsnotreceived")}
|
||||||
|
valueStyle={{
|
||||||
|
color:
|
||||||
|
calculatedCreditsNotReceived.getAmount() <= 0
|
||||||
|
? "green"
|
||||||
|
: "red",
|
||||||
|
}}
|
||||||
|
value={
|
||||||
|
calculatedCreditsNotReceived.getAmount() >= 0
|
||||||
|
? calculatedCreditsNotReceived.toFormat()
|
||||||
|
: Dinero().toFormat()
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={
|
title={
|
||||||
<div
|
<div
|
||||||
@@ -225,11 +271,14 @@ export default function JobBillsTotalComponent({
|
|||||||
<Statistic
|
<Statistic
|
||||||
title={t("bills.labels.creditsnotreceived")}
|
title={t("bills.labels.creditsnotreceived")}
|
||||||
valueStyle={{
|
valueStyle={{
|
||||||
color: creditsNotReceived.getAmount() <= 0 ? "green" : "red",
|
color:
|
||||||
|
totalReturnsMarkedNotReceived.getAmount() <= 0
|
||||||
|
? "green"
|
||||||
|
: "red",
|
||||||
}}
|
}}
|
||||||
value={
|
value={
|
||||||
creditsNotReceived.getAmount() >= 0
|
totalReturnsMarkedNotReceived.getAmount() >= 0
|
||||||
? creditsNotReceived.toFormat()
|
? totalReturnsMarkedNotReceived.toFormat()
|
||||||
: Dinero().toFormat()
|
: Dinero().toFormat()
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export function PartsOrderListTableComponent({
|
|||||||
});
|
});
|
||||||
const search = queryString.parse(useLocation().search);
|
const search = queryString.parse(useLocation().search);
|
||||||
const selectedpartsorder = search.partsorderid;
|
const selectedpartsorder = search.partsorderid;
|
||||||
|
const [searchText, setSearchText] = useState("");
|
||||||
|
|
||||||
const [deletePartsOrder] = useMutation(DELETE_PARTS_ORDER);
|
const [deletePartsOrder] = useMutation(DELETE_PARTS_ORDER);
|
||||||
|
|
||||||
@@ -421,6 +422,21 @@ export function PartsOrderListTableComponent({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const filteredPartsOrders = parts_orders
|
||||||
|
? searchText === ""
|
||||||
|
? parts_orders
|
||||||
|
: parts_orders.filter(
|
||||||
|
(b) =>
|
||||||
|
(b.order_number || "")
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(b.vendor.name || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase())
|
||||||
|
)
|
||||||
|
: [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
title={t("parts_orders.labels.parts_orders")}
|
title={t("parts_orders.labels.parts_orders")}
|
||||||
@@ -431,8 +447,10 @@ export function PartsOrderListTableComponent({
|
|||||||
</Button>
|
</Button>
|
||||||
<Input.Search
|
<Input.Search
|
||||||
placeholder={t("general.labels.search")}
|
placeholder={t("general.labels.search")}
|
||||||
|
value={searchText}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
setSearchText(e.target.value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
@@ -456,7 +474,7 @@ export function PartsOrderListTableComponent({
|
|||||||
}}
|
}}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
dataSource={parts_orders}
|
dataSource={filteredPartsOrders}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -174,7 +174,8 @@
|
|||||||
"bill_total": "Bill Total Amount",
|
"bill_total": "Bill Total Amount",
|
||||||
"billcmtotal": "Credit Memos",
|
"billcmtotal": "Credit Memos",
|
||||||
"bills": "Bills",
|
"bills": "Bills",
|
||||||
"creditsnotreceived": "Credits Not Received",
|
"calculatedcreditsnotreceived": "Calculated CNR",
|
||||||
|
"creditsnotreceived": "Credits Not Marked Received",
|
||||||
"creditsreceived": "Credits Received",
|
"creditsreceived": "Credits Received",
|
||||||
"dedfromlbr": "Labor Adjustments",
|
"dedfromlbr": "Labor Adjustments",
|
||||||
"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.",
|
||||||
@@ -1588,14 +1589,15 @@
|
|||||||
"partstotal": "Parts Total (ex. Taxes)",
|
"partstotal": "Parts Total (ex. Taxes)",
|
||||||
"plitooltips": {
|
"plitooltips": {
|
||||||
"billtotal": "The total amount of all bill lines that have been posted against this RO (not including credits, taxes, or labor adjustments).",
|
"billtotal": "The total amount of all bill lines that have been posted against this RO (not including credits, taxes, or labor adjustments).",
|
||||||
"creditmemos": "The total amount of all returns created. This amount does not reflect credit memos that have been posted.",
|
"calculatedcreditsnotreceived": "The calculated credits not received is derived by subtracting the amount of credit memos entered from the <b>retail</b> total of returns created. This does not take into account whether the credit was marked as received. You can find more information <a href=\"https://help.imex.online/en/article/credits-not-received-changes-1jy9snw\" target=\"_blank\">here</a>.",
|
||||||
"creditsnotreceived": "The total amount of returns created for this job that do not have a corresponding credit memo posted. An amount greater than $0 indicates that vendors have not provided requested credit memos.",
|
"creditmemos": "The total <b>retail</b> amount of all returns created. This amount does not reflect credit memos that have been posted.",
|
||||||
|
"creditsnotreceived": "This total reflects the total <b>retail</b> of parts returns lines that have not been explicitly marked as returned when posting a credit memo. You can learn more about this here <a href=\"https://help.imex.online/en/article/credits-not-received-changes-1jy9snw\" target=\"_blank\">here</a>. ",
|
||||||
"discrep1": "If the discrepancy is not $0, you may have one of the following: <br/><br/>\n\n<ul>\n<li>Too many bills/bill lines that have been posted against this RO. Check to make sure every bill posted on this RO is correctly posted and assigned.</li>\n<li>You do not have the latest supplement imported, or, a supplement must be submitted and then imported.</li>\n<li>You have posted a bill line to labor.</li>\n</ul>\n<br/>\n<i>There may be additional issues not listed above that prevent this job from reconciling.</i>",
|
"discrep1": "If the discrepancy is not $0, you may have one of the following: <br/><br/>\n\n<ul>\n<li>Too many bills/bill lines that have been posted against this RO. Check to make sure every bill posted on this RO is correctly posted and assigned.</li>\n<li>You do not have the latest supplement imported, or, a supplement must be submitted and then imported.</li>\n<li>You have posted a bill line to labor.</li>\n</ul>\n<br/>\n<i>There may be additional issues not listed above that prevent this job from reconciling.</i>",
|
||||||
"discrep2": "If the discrepancy is not $0, you may have one of the following: <br/><br/>\n\n<ul>\n<li>Used an incorrect rate when deducting from labor.</li>\n<li>An outstanding imbalance higher in the reconciliation process.</li>\n</ul>\n<br/>\n<i>There may be additional issues not listed above that prevent this job from reconciling.</i>",
|
"discrep2": "If the discrepancy is not $0, you may have one of the following: <br/><br/>\n\n<ul>\n<li>Used an incorrect rate when deducting from labor.</li>\n<li>An outstanding imbalance higher in the reconciliation process.</li>\n</ul>\n<br/>\n<i>There may be additional issues not listed above that prevent this job from reconciling.</i>",
|
||||||
"discrep3": "If the discrepancy is not $0, you may have one of the following: <br/><br/>\n\n<ul>\n<li>Credit memos that have not been received or posted.</li>\n<li>An outstanding imbalance higher in the reconciliation process.</li>\n</ul>\n<br/>\n<i>There may be additional issues not listed above that prevent this job from reconciling.</i>",
|
"discrep3": "If the discrepancy is not $0, you may have one of the following: <br/><br/>\n\n<ul>\n<li>A parts order return has not been created.</li>\n<li>An outstanding imbalance higher in the reconciliation process.</li>\n</ul>\n<br/>\n<i>There may be additional issues not listed above that prevent this job from reconciling.</i>",
|
||||||
"laboradj": "The sum of all bill lines that deducted from labor hours, rather than part prices.",
|
"laboradj": "The sum of all bill lines that deducted from labor hours, rather than part prices.",
|
||||||
"partstotal": "This is the total of all parts and sublet amounts on the vehicle (some of these may require an in-house invoice).<br/>\nItems such as shop and paint materials, labor online lines, etc. are not included in this total.",
|
"partstotal": "This is the total of all parts and sublet amounts on the vehicle (some of these may require an in-house invoice).<br/>\nItems such as shop and paint materials, labor online lines, etc. are not included in this total.",
|
||||||
"totalreturns": "The total amount of returns created for this job."
|
"totalreturns": "The total <b>retail</b> amount of returns created for this job."
|
||||||
},
|
},
|
||||||
"prt_dsmk_total": "Line Item Adjustment",
|
"prt_dsmk_total": "Line Item Adjustment",
|
||||||
"rates": "Rates",
|
"rates": "Rates",
|
||||||
|
|||||||
@@ -174,6 +174,7 @@
|
|||||||
"bill_total": "",
|
"bill_total": "",
|
||||||
"billcmtotal": "",
|
"billcmtotal": "",
|
||||||
"bills": "",
|
"bills": "",
|
||||||
|
"calculatedcreditsnotreceived": "",
|
||||||
"creditsnotreceived": "",
|
"creditsnotreceived": "",
|
||||||
"creditsreceived": "",
|
"creditsreceived": "",
|
||||||
"dedfromlbr": "",
|
"dedfromlbr": "",
|
||||||
@@ -1588,6 +1589,7 @@
|
|||||||
"partstotal": "",
|
"partstotal": "",
|
||||||
"plitooltips": {
|
"plitooltips": {
|
||||||
"billtotal": "",
|
"billtotal": "",
|
||||||
|
"calculatedcreditsnotreceived": "",
|
||||||
"creditmemos": "",
|
"creditmemos": "",
|
||||||
"creditsnotreceived": "",
|
"creditsnotreceived": "",
|
||||||
"discrep1": "",
|
"discrep1": "",
|
||||||
|
|||||||
@@ -174,6 +174,7 @@
|
|||||||
"bill_total": "",
|
"bill_total": "",
|
||||||
"billcmtotal": "",
|
"billcmtotal": "",
|
||||||
"bills": "",
|
"bills": "",
|
||||||
|
"calculatedcreditsnotreceived": "",
|
||||||
"creditsnotreceived": "",
|
"creditsnotreceived": "",
|
||||||
"creditsreceived": "",
|
"creditsreceived": "",
|
||||||
"dedfromlbr": "",
|
"dedfromlbr": "",
|
||||||
@@ -1588,6 +1589,7 @@
|
|||||||
"partstotal": "",
|
"partstotal": "",
|
||||||
"plitooltips": {
|
"plitooltips": {
|
||||||
"billtotal": "",
|
"billtotal": "",
|
||||||
|
"calculatedcreditsnotreceived": "",
|
||||||
"creditmemos": "",
|
"creditmemos": "",
|
||||||
"creditsnotreceived": "",
|
"creditsnotreceived": "",
|
||||||
"discrep1": "",
|
"discrep1": "",
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ export default async function RenderTemplate(
|
|||||||
marginBottom:
|
marginBottom:
|
||||||
bodyshop.logo_img_path &&
|
bodyshop.logo_img_path &&
|
||||||
bodyshop.logo_img_path.footerMargin &&
|
bodyshop.logo_img_path.footerMargin &&
|
||||||
bodyshop.logo_img_path.footerMargin > 36
|
bodyshop.logo_img_path.footerMargin > 50
|
||||||
? bodyshop.logo_img_path.footerMargin
|
? bodyshop.logo_img_path.footerMargin
|
||||||
: "36px",
|
: "50px",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
@@ -158,9 +158,9 @@ export async function RenderTemplates(
|
|||||||
marginBottom:
|
marginBottom:
|
||||||
bodyshop.logo_img_path &&
|
bodyshop.logo_img_path &&
|
||||||
bodyshop.logo_img_path.footerMargin &&
|
bodyshop.logo_img_path.footerMargin &&
|
||||||
bodyshop.logo_img_path.footerMargin > 36
|
bodyshop.logo_img_path.footerMargin > 50
|
||||||
? bodyshop.logo_img_path.footerMargin
|
? bodyshop.logo_img_path.footerMargin
|
||||||
: "36px",
|
: "50px",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pdfOperations: templateAndData.map((template) => {
|
pdfOperations: templateAndData.map((template) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user