@@ -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
|
||||||
@@ -25120,6 +25120,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>cost_Additional</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>cost_labor</name>
|
<name>cost_labor</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -27014,6 +27035,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>sale_additional</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>sale_labor</name>
|
<name>sale_labor</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -32085,6 +32127,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>part_type</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>quantity</name>
|
<name>quantity</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -207,6 +207,8 @@ export function BillDetailEditcontainer({
|
|||||||
cost: i.actual_cost,
|
cost: i.actual_cost,
|
||||||
quantity: i.quantity,
|
quantity: i.quantity,
|
||||||
joblineid: i.joblineid,
|
joblineid: i.joblineid,
|
||||||
|
oem_partno: i.jobline && i.jobline.oem_partno,
|
||||||
|
part_type: i.jobline && i.jobline.part_type,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
isReturn: true,
|
isReturn: true,
|
||||||
|
|||||||
@@ -216,7 +216,11 @@ function BillEnterModalContainer({
|
|||||||
|
|
||||||
if (enterAgain) {
|
if (enterAgain) {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
form.setFieldsValue({ ...form.getFieldsValue(), billlines: [] });
|
form.resetFields();
|
||||||
|
form.setFieldsValue({
|
||||||
|
...formValues,
|
||||||
|
billlines: [],
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
toggleModalVisible();
|
toggleModalVisible();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ export function BillsListTableComponent({
|
|||||||
quantity: i.quantity,
|
quantity: i.quantity,
|
||||||
joblineid: i.joblineid,
|
joblineid: i.joblineid,
|
||||||
oem_partno: i.jobline && i.jobline.oem_partno,
|
oem_partno: i.jobline && i.jobline.oem_partno,
|
||||||
|
part_type: i.jobline && i.jobline.part_type,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
isReturn: true,
|
isReturn: true,
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ export function JobCostingModalContainer({
|
|||||||
const { visible, context } = jobCostingModal;
|
const { visible, context } = jobCostingModal;
|
||||||
const { jobId } = context;
|
const { jobId } = context;
|
||||||
|
|
||||||
// const { loading, error, data } = useQuery(QUERY_JOB_COSTING_DETAILS, {
|
|
||||||
// variables: { id: jobId },
|
|
||||||
// skip: !jobId,
|
|
||||||
// });
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getData() {
|
async function getData() {
|
||||||
if (jobId && visible) {
|
if (jobId && visible) {
|
||||||
@@ -46,8 +41,14 @@ export function JobCostingModalContainer({
|
|||||||
<Modal
|
<Modal
|
||||||
visible={visible}
|
visible={visible}
|
||||||
title={t("jobs.labels.jobcosting")}
|
title={t("jobs.labels.jobcosting")}
|
||||||
onOk={() => toggleModalVisible()}
|
onOk={() => {
|
||||||
onCancel={() => toggleModalVisible()}
|
toggleModalVisible();
|
||||||
|
setCostingData(null);
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
toggleModalVisible();
|
||||||
|
setCostingData(null);
|
||||||
|
}}
|
||||||
cancelButtonProps={{ style: { display: "none" } }}
|
cancelButtonProps={{ style: { display: "none" } }}
|
||||||
width="90%"
|
width="90%"
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ export default function JobCostingStatistics({ summaryData }) {
|
|||||||
value={Dinero(summaryData.totalPartsSales).toFormat()}
|
value={Dinero(summaryData.totalPartsSales).toFormat()}
|
||||||
title={t("jobs.labels.sale_parts")}
|
title={t("jobs.labels.sale_parts")}
|
||||||
/>
|
/>
|
||||||
|
<Statistic
|
||||||
|
value={Dinero(summaryData.totalAdditionalSales).toFormat()}
|
||||||
|
title={t("jobs.labels.sale_additional")}
|
||||||
|
/>
|
||||||
<Statistic
|
<Statistic
|
||||||
value={Dinero(summaryData.totalSales).toFormat()}
|
value={Dinero(summaryData.totalSales).toFormat()}
|
||||||
title={t("jobs.labels.total_sales")}
|
title={t("jobs.labels.total_sales")}
|
||||||
@@ -28,6 +32,10 @@ export default function JobCostingStatistics({ summaryData }) {
|
|||||||
value={Dinero(summaryData.totalPartsCost).toFormat()}
|
value={Dinero(summaryData.totalPartsCost).toFormat()}
|
||||||
title={t("jobs.labels.cost_parts")}
|
title={t("jobs.labels.cost_parts")}
|
||||||
/>
|
/>
|
||||||
|
<Statistic
|
||||||
|
value={Dinero(summaryData.totalAdditionalCost).toFormat()}
|
||||||
|
title={t("jobs.labels.cost_Additional")}
|
||||||
|
/>
|
||||||
<Statistic
|
<Statistic
|
||||||
value={Dinero(summaryData.totalCost).toFormat()}
|
value={Dinero(summaryData.totalCost).toFormat()}
|
||||||
title={t("jobs.labels.total_cost")}
|
title={t("jobs.labels.total_cost")}
|
||||||
|
|||||||
@@ -319,6 +319,15 @@ export function PartsOrderListTableComponent({
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
{
|
||||||
|
title: t("parts_orders.fields.part_type"),
|
||||||
|
dataIndex: "part_type",
|
||||||
|
key: "part_type",
|
||||||
|
render: (text, record) =>
|
||||||
|
record.part_type
|
||||||
|
? t(`joblines.fields.part_types.${record.part_type}`)
|
||||||
|
: null,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t("parts_orders.fields.oem_partno"),
|
title: t("parts_orders.fields.oem_partno"),
|
||||||
dataIndex: "oem_partno",
|
dataIndex: "oem_partno",
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
import { DeleteFilled, WarningFilled } from "@ant-design/icons";
|
import { DeleteFilled, WarningFilled } from "@ant-design/icons";
|
||||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Divider, Form, Input, InputNumber, Radio, Space, Tag } from "antd";
|
import {
|
||||||
|
Divider,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
InputNumber,
|
||||||
|
Radio,
|
||||||
|
Space,
|
||||||
|
Tag,
|
||||||
|
Select,
|
||||||
|
} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -114,6 +123,45 @@ export function PartsOrderModalComponent({
|
|||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("parts_orders.fields.part_type")}
|
||||||
|
key={`${index}part_type`}
|
||||||
|
name={[field.name, "part_type"]}
|
||||||
|
>
|
||||||
|
<Select>
|
||||||
|
<Select.Option value="PAA">
|
||||||
|
{t("joblines.fields.part_types.PAA")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value="PAC">
|
||||||
|
{t("joblines.fields.part_types.PAC")}
|
||||||
|
</Select.Option>
|
||||||
|
|
||||||
|
<Select.Option value="PAL">
|
||||||
|
{t("joblines.fields.part_types.PAL")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value="PAG">
|
||||||
|
{t("joblines.fields.part_types.PAG")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value="PAM">
|
||||||
|
{t("joblines.fields.part_types.PAM")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value="PAP">
|
||||||
|
{t("joblines.fields.part_types.PAP")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value="PAN">
|
||||||
|
{t("joblines.fields.part_types.PAN")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value="PAO">
|
||||||
|
{t("joblines.fields.part_types.PAO")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value="PAR">
|
||||||
|
{t("joblines.fields.part_types.PAR")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value="PAS">
|
||||||
|
{t("joblines.fields.part_types.PAS")}
|
||||||
|
</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("parts_orders.fields.oem_partno")}
|
label={t("parts_orders.fields.oem_partno")}
|
||||||
key={`${index}oem_partno`}
|
key={`${index}oem_partno`}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export function PartsOrderModalContainer({
|
|||||||
|
|
||||||
const { refetch } = actions;
|
const { refetch } = actions;
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const [saving, setSaving] = useState(false);
|
||||||
const sendTypeState = useState("e");
|
const sendTypeState = useState("e");
|
||||||
const sendType = sendTypeState[0];
|
const sendType = sendTypeState[0];
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ export function PartsOrderModalContainer({
|
|||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
logImEXEvent("parts_order_insert");
|
logImEXEvent("parts_order_insert");
|
||||||
|
setSaving(true);
|
||||||
const insertResult = await insertPartOrder({
|
const insertResult = await insertPartOrder({
|
||||||
variables: {
|
variables: {
|
||||||
po: [
|
po: [
|
||||||
@@ -247,8 +247,6 @@ export function PartsOrderModalContainer({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(partsOrder.data.parts_orders_by_pk);
|
|
||||||
|
|
||||||
const oecResponse = await axios.post(
|
const oecResponse = await axios.post(
|
||||||
"http://localhost:1337/oec/",
|
"http://localhost:1337/oec/",
|
||||||
|
|
||||||
@@ -275,11 +273,11 @@ export function PartsOrderModalContainer({
|
|||||||
error: JSON.stringify(error.message),
|
error: JSON.stringify(error.message),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
setSaving(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setSaving(false);
|
||||||
toggleModalVisible();
|
toggleModalVisible();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -301,6 +299,7 @@ export function PartsOrderModalContainer({
|
|||||||
cost: value.cost,
|
cost: value.cost,
|
||||||
quantity: value.part_qty,
|
quantity: value.part_qty,
|
||||||
job_line_id: isReturn ? value.joblineid : value.id,
|
job_line_id: isReturn ? value.joblineid : value.id,
|
||||||
|
part_type: value.part_type,
|
||||||
});
|
});
|
||||||
return acc;
|
return acc;
|
||||||
}, [])
|
}, [])
|
||||||
@@ -324,6 +323,8 @@ export function PartsOrderModalContainer({
|
|||||||
}
|
}
|
||||||
onCancel={() => toggleModalVisible()}
|
onCancel={() => toggleModalVisible()}
|
||||||
onOk={() => form.submit()}
|
onOk={() => form.submit()}
|
||||||
|
okButtonProps={{ loading: saving }}
|
||||||
|
cancelButtonProps={{ loading: saving }}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
width="75%"
|
width="75%"
|
||||||
forceRender
|
forceRender
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ export const QUERY_BILLS_BY_JOBID = gql`
|
|||||||
line_remarks
|
line_remarks
|
||||||
quantity
|
quantity
|
||||||
job_line_id
|
job_line_id
|
||||||
|
part_type
|
||||||
cost
|
cost
|
||||||
jobline {
|
jobline {
|
||||||
id
|
id
|
||||||
@@ -123,6 +124,10 @@ export const QUERY_BILLS_BY_JOBID = gql`
|
|||||||
applicable_taxes
|
applicable_taxes
|
||||||
deductedfromlbr
|
deductedfromlbr
|
||||||
lbr_adjustment
|
lbr_adjustment
|
||||||
|
jobline{
|
||||||
|
oem_partno
|
||||||
|
part_type
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,6 +164,10 @@ export const QUERY_BILL_BY_PK = gql`
|
|||||||
cost_center
|
cost_center
|
||||||
quantity
|
quantity
|
||||||
joblineid
|
joblineid
|
||||||
|
jobline{
|
||||||
|
oem_partno
|
||||||
|
part_type
|
||||||
|
}
|
||||||
applicable_taxes
|
applicable_taxes
|
||||||
deductedfromlbr
|
deductedfromlbr
|
||||||
lbr_adjustment
|
lbr_adjustment
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export const QUERY_PARTS_ORDER_OEC = gql`
|
|||||||
db_price
|
db_price
|
||||||
line_desc
|
line_desc
|
||||||
quantity
|
quantity
|
||||||
|
part_type
|
||||||
}
|
}
|
||||||
job {
|
job {
|
||||||
bodyshop{
|
bodyshop{
|
||||||
|
|||||||
@@ -1486,6 +1486,7 @@
|
|||||||
"closejob": "Close Job {{ro_number}}",
|
"closejob": "Close Job {{ro_number}}",
|
||||||
"contracts": "CC Contracts",
|
"contracts": "CC Contracts",
|
||||||
"cost": "Cost",
|
"cost": "Cost",
|
||||||
|
"cost_Additional": "Cost - Additional",
|
||||||
"cost_labor": "Cost - Labor",
|
"cost_labor": "Cost - Labor",
|
||||||
"cost_parts": "Cost - Parts",
|
"cost_parts": "Cost - Parts",
|
||||||
"costs": "Costs",
|
"costs": "Costs",
|
||||||
@@ -1585,6 +1586,7 @@
|
|||||||
"relatedros": "Related ROs",
|
"relatedros": "Related ROs",
|
||||||
"returntotals": "Return Totals",
|
"returntotals": "Return Totals",
|
||||||
"rosaletotal": "RO Parts Total",
|
"rosaletotal": "RO Parts Total",
|
||||||
|
"sale_additional": "Sales - Additional",
|
||||||
"sale_labor": "Sales - Labor",
|
"sale_labor": "Sales - Labor",
|
||||||
"sale_parts": "Sales - Parts & Sublet",
|
"sale_parts": "Sales - Parts & Sublet",
|
||||||
"sales": "Sales",
|
"sales": "Sales",
|
||||||
@@ -1904,6 +1906,7 @@
|
|||||||
"order_date": "Order Date",
|
"order_date": "Order Date",
|
||||||
"order_number": "Order Number",
|
"order_number": "Order Number",
|
||||||
"orderedby": "Ordered By",
|
"orderedby": "Ordered By",
|
||||||
|
"part_type": "Type",
|
||||||
"quantity": "Qty.",
|
"quantity": "Qty.",
|
||||||
"return": "Return",
|
"return": "Return",
|
||||||
"status": "Status"
|
"status": "Status"
|
||||||
|
|||||||
@@ -1486,6 +1486,7 @@
|
|||||||
"closejob": "",
|
"closejob": "",
|
||||||
"contracts": "",
|
"contracts": "",
|
||||||
"cost": "",
|
"cost": "",
|
||||||
|
"cost_Additional": "",
|
||||||
"cost_labor": "",
|
"cost_labor": "",
|
||||||
"cost_parts": "",
|
"cost_parts": "",
|
||||||
"costs": "",
|
"costs": "",
|
||||||
@@ -1585,6 +1586,7 @@
|
|||||||
"relatedros": "",
|
"relatedros": "",
|
||||||
"returntotals": "",
|
"returntotals": "",
|
||||||
"rosaletotal": "",
|
"rosaletotal": "",
|
||||||
|
"sale_additional": "",
|
||||||
"sale_labor": "",
|
"sale_labor": "",
|
||||||
"sale_parts": "",
|
"sale_parts": "",
|
||||||
"sales": "",
|
"sales": "",
|
||||||
@@ -1904,6 +1906,7 @@
|
|||||||
"order_date": "",
|
"order_date": "",
|
||||||
"order_number": "",
|
"order_number": "",
|
||||||
"orderedby": "",
|
"orderedby": "",
|
||||||
|
"part_type": "",
|
||||||
"quantity": "",
|
"quantity": "",
|
||||||
"return": "",
|
"return": "",
|
||||||
"status": ""
|
"status": ""
|
||||||
|
|||||||
@@ -1486,6 +1486,7 @@
|
|||||||
"closejob": "",
|
"closejob": "",
|
||||||
"contracts": "",
|
"contracts": "",
|
||||||
"cost": "",
|
"cost": "",
|
||||||
|
"cost_Additional": "",
|
||||||
"cost_labor": "",
|
"cost_labor": "",
|
||||||
"cost_parts": "",
|
"cost_parts": "",
|
||||||
"costs": "",
|
"costs": "",
|
||||||
@@ -1585,6 +1586,7 @@
|
|||||||
"relatedros": "",
|
"relatedros": "",
|
||||||
"returntotals": "",
|
"returntotals": "",
|
||||||
"rosaletotal": "",
|
"rosaletotal": "",
|
||||||
|
"sale_additional": "",
|
||||||
"sale_labor": "",
|
"sale_labor": "",
|
||||||
"sale_parts": "",
|
"sale_parts": "",
|
||||||
"sales": "",
|
"sales": "",
|
||||||
@@ -1904,6 +1906,7 @@
|
|||||||
"order_date": "",
|
"order_date": "",
|
||||||
"order_number": "",
|
"order_number": "",
|
||||||
"orderedby": "",
|
"orderedby": "",
|
||||||
|
"part_type": "",
|
||||||
"quantity": "",
|
"quantity": "",
|
||||||
"return": "",
|
"return": "",
|
||||||
"status": ""
|
"status": ""
|
||||||
|
|||||||
@@ -815,6 +815,7 @@
|
|||||||
- email
|
- email
|
||||||
- enforce_class
|
- enforce_class
|
||||||
- enforce_referral
|
- enforce_referral
|
||||||
|
- entegral_configuration
|
||||||
- entegral_id
|
- entegral_id
|
||||||
- features
|
- features
|
||||||
- federal_tax_id
|
- federal_tax_id
|
||||||
|
|||||||
@@ -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 "entegral_configuration" jsonb
|
||||||
|
-- null default jsonb_build_array();
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."bodyshops" add column "entegral_configuration" jsonb
|
||||||
|
null default jsonb_build_array();
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."bodyshops" alter column "entegral_configuration" set default jsonb_build_array();
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."bodyshops" alter column "entegral_configuration" set default jsonb_build_object();
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "public"."bodyshops" ALTER COLUMN "timezone" drop default;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."bodyshops" alter column "timezone" set default 'America/Vancouver';
|
||||||
@@ -123,12 +123,12 @@ exports.default = async (req, res) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (const xmlObj of allxmlsToUpload) {
|
for (const xmlObj of allxmlsToUpload) {
|
||||||
// fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml);
|
fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// res.json(allxmlsToUpload);
|
res.json(allxmlsToUpload);
|
||||||
// return;
|
return;
|
||||||
|
|
||||||
let sftp = new Client();
|
let sftp = new Client();
|
||||||
sftp.on("error", (errors) =>
|
sftp.on("error", (errors) =>
|
||||||
@@ -227,7 +227,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
InsuredorClaimantFlag: null,
|
InsuredorClaimantFlag: null,
|
||||||
},
|
},
|
||||||
VehicleInformation: {
|
VehicleInformation: {
|
||||||
Year: job.v_model_yr || "",
|
Year: parseInt(job.v_model_yr.match(/\d/g).join(""), 10) || "",
|
||||||
Make: job.v_make_desc || "",
|
Make: job.v_make_desc || "",
|
||||||
Model: job.v_model_desc || "",
|
Model: job.v_model_desc || "",
|
||||||
VIN: job.v_vin || "",
|
VIN: job.v_vin || "",
|
||||||
@@ -575,10 +575,12 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
.add(Dinero(job.job_totals.totals.federal_tax))
|
.add(Dinero(job.job_totals.totals.federal_tax))
|
||||||
.toFormat(AHDineroFormat),
|
.toFormat(AHDineroFormat),
|
||||||
SalesTaxTotalCost: 0,
|
SalesTaxTotalCost: 0,
|
||||||
GrossTotal: Dinero(job.job_totals.totals.net_repairs).toFormat(
|
GrossTotal: Dinero(job.job_totals.totals.total_repairs).toFormat(
|
||||||
AHDineroFormat
|
AHDineroFormat
|
||||||
),
|
),
|
||||||
DeductibleTotal: job.ded_amt || 0,
|
DeductibleTotal: Dinero({
|
||||||
|
amount: Math.round((job.ded_amt || 0) * 100),
|
||||||
|
}).toFormat(AHDineroFormat),
|
||||||
DepreciationTotal: Dinero(
|
DepreciationTotal: Dinero(
|
||||||
job.job_totals.totals.custPayable.dep_taxes
|
job.job_totals.totals.custPayable.dep_taxes
|
||||||
).toFormat(AHDineroFormat),
|
).toFormat(AHDineroFormat),
|
||||||
@@ -588,7 +590,9 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
CustomerPay: Dinero(job.job_totals.totals.custPayable.total).toFormat(
|
CustomerPay: Dinero(job.job_totals.totals.custPayable.total).toFormat(
|
||||||
AHDineroFormat
|
AHDineroFormat
|
||||||
),
|
),
|
||||||
InsurancePay: 0,
|
InsurancePay: Dinero(job.job_totals.totals.total_repairs)
|
||||||
|
.subtract(Dinero(job.job_totals.totals.custPayable))
|
||||||
|
.toFormat(AHDineroFormat),
|
||||||
Deposit: 0,
|
Deposit: 0,
|
||||||
AmountDue: 0,
|
AmountDue: 0,
|
||||||
},
|
},
|
||||||
@@ -634,7 +638,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
DetailLine:
|
DetailLine:
|
||||||
job.joblines.length > 0
|
job.joblines.length > 0
|
||||||
? job.joblines.map((jl) =>
|
? job.joblines.map((jl) =>
|
||||||
GenerateDetailLines(jl, job.bodyshop.md_order_statuses)
|
GenerateDetailLines(job, jl, job.bodyshop.md_order_statuses)
|
||||||
)
|
)
|
||||||
: [generateNullDetailLine()],
|
: [generateNullDetailLine()],
|
||||||
},
|
},
|
||||||
@@ -718,7 +722,10 @@ const CreateCosts = (job) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
PartsTotalCost: Object.keys(billTotalsByCostCenters).reduce((acc, key) => {
|
PartsTotalCost: Object.keys(billTotalsByCostCenters).reduce((acc, key) => {
|
||||||
return acc.add(billTotalsByCostCenters[key]);
|
if (key !== defaultCosts.PAS && key !== defaultCosts.PASL)
|
||||||
|
return acc.add(billTotalsByCostCenters[key]);
|
||||||
|
|
||||||
|
return acc;
|
||||||
}, Dinero()),
|
}, Dinero()),
|
||||||
PartsOemCost: (billTotalsByCostCenters[defaultCosts.PAN] || Dinero()).add(
|
PartsOemCost: (billTotalsByCostCenters[defaultCosts.PAN] || Dinero()).add(
|
||||||
billTotalsByCostCenters[defaultCosts.PAP] || Dinero()
|
billTotalsByCostCenters[defaultCosts.PAP] || Dinero()
|
||||||
@@ -728,7 +735,9 @@ const CreateCosts = (job) => {
|
|||||||
billTotalsByCostCenters[defaultCosts.PAM] || Dinero(),
|
billTotalsByCostCenters[defaultCosts.PAM] || Dinero(),
|
||||||
PartsRecycledCost: billTotalsByCostCenters[defaultCosts.PAL] || Dinero(),
|
PartsRecycledCost: billTotalsByCostCenters[defaultCosts.PAL] || Dinero(),
|
||||||
PartsOtherCost: billTotalsByCostCenters[defaultCosts.PAO] || Dinero(),
|
PartsOtherCost: billTotalsByCostCenters[defaultCosts.PAO] || Dinero(),
|
||||||
SubletTotalCost: billTotalsByCostCenters[defaultCosts.PAS] || Dinero(),
|
SubletTotalCost:
|
||||||
|
billTotalsByCostCenters[defaultCosts.PAS] ||
|
||||||
|
Dinero(billTotalsByCostCenters[defaultCosts.PASL] || Dinero()),
|
||||||
BodyLaborTotalCost: ticketTotalsByCostCenter[defaultCosts.LAB] || Dinero(),
|
BodyLaborTotalCost: ticketTotalsByCostCenter[defaultCosts.LAB] || Dinero(),
|
||||||
RefinishLaborTotalCost:
|
RefinishLaborTotalCost:
|
||||||
ticketTotalsByCostCenter[defaultCosts.LAR] || Dinero(),
|
ticketTotalsByCostCenter[defaultCosts.LAR] || Dinero(),
|
||||||
@@ -781,10 +790,15 @@ const StatusMapping = (status, md_ro_statuses) => {
|
|||||||
// default: return "UNDEFINED"
|
// default: return "UNDEFINED"
|
||||||
};
|
};
|
||||||
|
|
||||||
const GenerateDetailLines = (line, statuses) => {
|
const GenerateDetailLines = (job, line, statuses) => {
|
||||||
const ret = {
|
const ret = {
|
||||||
BackOrdered: line.status === statuses.default_bo ? "1" : "0",
|
BackOrdered: line.status === statuses.default_bo ? "1" : "0",
|
||||||
Cost: (line.billlines[0] && line.billlines[0].actual_cost.toFixed(2)) || 0,
|
Cost:
|
||||||
|
(line.billlines[0] &&
|
||||||
|
(line.billlines[0].actual_cost * line.billlines[0].quantity).toFixed(
|
||||||
|
2
|
||||||
|
)) ||
|
||||||
|
0,
|
||||||
//Critical: null,
|
//Critical: null,
|
||||||
Description: line.line_desc || "",
|
Description: line.line_desc || "",
|
||||||
DiscountMarkup: line.prt_dsmk_m || 0,
|
DiscountMarkup: line.prt_dsmk_m || 0,
|
||||||
@@ -811,11 +825,7 @@ const GenerateDetailLines = (line, statuses) => {
|
|||||||
Vendor: (line.billlines[0] && line.billlines[0].bill.vendor.name) || "",
|
Vendor: (line.billlines[0] && line.billlines[0].bill.vendor.name) || "",
|
||||||
VendorPaid: null,
|
VendorPaid: null,
|
||||||
VendorPrice:
|
VendorPrice:
|
||||||
(line.billlines[0] &&
|
(line.billlines[0] && line.billlines[0].actual_price.toFixed(2)) || 0,
|
||||||
(line.billlines[0].actual_price * line.billlines[0].quantity).toFixed(
|
|
||||||
2
|
|
||||||
)) ||
|
|
||||||
0,
|
|
||||||
Deleted: null,
|
Deleted: null,
|
||||||
ExpectedOn: null,
|
ExpectedOn: null,
|
||||||
ReceivedOn:
|
ReceivedOn:
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ exports.AUTOHOUSE_QUERY = `query AUTOHOUSE_EXPORT($start: timestamptz, $bodyshop
|
|||||||
job_totals
|
job_totals
|
||||||
driveable
|
driveable
|
||||||
parts_tax_rates
|
parts_tax_rates
|
||||||
|
ded_amt
|
||||||
joblines(where: {removed: {_eq: false}}) {
|
joblines(where: {removed: {_eq: false}}) {
|
||||||
id
|
id
|
||||||
line_no
|
line_no
|
||||||
|
|||||||
@@ -62,9 +62,11 @@ async function JobCostingMulti(req, res) {
|
|||||||
summaryData: {
|
summaryData: {
|
||||||
totalLaborSales: Dinero({ amount: 0 }),
|
totalLaborSales: Dinero({ amount: 0 }),
|
||||||
totalPartsSales: Dinero({ amount: 0 }),
|
totalPartsSales: Dinero({ amount: 0 }),
|
||||||
|
totalAdditionalSales: Dinero({ amount: 0 }),
|
||||||
totalSales: Dinero({ amount: 0 }),
|
totalSales: Dinero({ amount: 0 }),
|
||||||
totalLaborCost: Dinero({ amount: 0 }),
|
totalLaborCost: Dinero({ amount: 0 }),
|
||||||
totalPartsCost: Dinero({ amount: 0 }),
|
totalPartsCost: Dinero({ amount: 0 }),
|
||||||
|
totalAdditionalCost: Dinero({ amount: 0 }),
|
||||||
totalCost: Dinero({ amount: 0 }),
|
totalCost: Dinero({ amount: 0 }),
|
||||||
gpdollars: Dinero({ amount: 0 }),
|
gpdollars: Dinero({ amount: 0 }),
|
||||||
gppercent: null,
|
gppercent: null,
|
||||||
@@ -102,12 +104,18 @@ async function JobCostingMulti(req, res) {
|
|||||||
sale_parts_dinero: multiSummary.costCenterData[
|
sale_parts_dinero: multiSummary.costCenterData[
|
||||||
CostCenterIndex
|
CostCenterIndex
|
||||||
].sale_parts_dinero.add(c.sale_parts_dinero),
|
].sale_parts_dinero.add(c.sale_parts_dinero),
|
||||||
|
sale_additional_dinero: multiSummary.costCenterData[
|
||||||
|
CostCenterIndex
|
||||||
|
].sale_additional_dinero.add(c.sale_additional_dinero),
|
||||||
cost_labor_dinero: multiSummary.costCenterData[
|
cost_labor_dinero: multiSummary.costCenterData[
|
||||||
CostCenterIndex
|
CostCenterIndex
|
||||||
].cost_labor_dinero.add(c.cost_labor_dinero),
|
].cost_labor_dinero.add(c.cost_labor_dinero),
|
||||||
cost_parts_dinero: multiSummary.costCenterData[
|
cost_parts_dinero: multiSummary.costCenterData[
|
||||||
CostCenterIndex
|
CostCenterIndex
|
||||||
].cost_parts_dinero.add(c.cost_parts_dinero),
|
].cost_parts_dinero.add(c.cost_parts_dinero),
|
||||||
|
cost_additional_dinero: multiSummary.costCenterData[
|
||||||
|
CostCenterIndex
|
||||||
|
].cost_additional_dinero.add(c.cost_additional_dinero),
|
||||||
gpdollars_dinero: multiSummary.costCenterData[
|
gpdollars_dinero: multiSummary.costCenterData[
|
||||||
CostCenterIndex
|
CostCenterIndex
|
||||||
].gpdollars_dinero.add(c.gpdollars_dinero),
|
].gpdollars_dinero.add(c.gpdollars_dinero),
|
||||||
@@ -129,6 +137,10 @@ async function JobCostingMulti(req, res) {
|
|||||||
multiSummary.summaryData.totalPartsSales.add(
|
multiSummary.summaryData.totalPartsSales.add(
|
||||||
costingData.summaryData.totalPartsSales
|
costingData.summaryData.totalPartsSales
|
||||||
);
|
);
|
||||||
|
multiSummary.summaryData.totalAdditionalSales =
|
||||||
|
multiSummary.summaryData.totalAdditionalSales.add(
|
||||||
|
costingData.summaryData.totalAdditionalSales
|
||||||
|
);
|
||||||
multiSummary.summaryData.totalSales =
|
multiSummary.summaryData.totalSales =
|
||||||
multiSummary.summaryData.totalSales.add(
|
multiSummary.summaryData.totalSales.add(
|
||||||
costingData.summaryData.totalSales
|
costingData.summaryData.totalSales
|
||||||
@@ -145,6 +157,10 @@ async function JobCostingMulti(req, res) {
|
|||||||
multiSummary.summaryData.totalPartsCost.add(
|
multiSummary.summaryData.totalPartsCost.add(
|
||||||
costingData.summaryData.totalPartsCost
|
costingData.summaryData.totalPartsCost
|
||||||
);
|
);
|
||||||
|
multiSummary.summaryData.totalAdditionalCost =
|
||||||
|
multiSummary.summaryData.totalAdditionalCost.add(
|
||||||
|
costingData.summaryData.totalAdditionalCost
|
||||||
|
);
|
||||||
multiSummary.summaryData.totalCost =
|
multiSummary.summaryData.totalCost =
|
||||||
multiSummary.summaryData.totalCost.add(
|
multiSummary.summaryData.totalCost.add(
|
||||||
costingData.summaryData.totalCost
|
costingData.summaryData.totalCost
|
||||||
@@ -201,10 +217,14 @@ async function JobCostingMulti(req, res) {
|
|||||||
...c,
|
...c,
|
||||||
sale_labor: c.sale_labor_dinero && c.sale_labor_dinero.toFormat(),
|
sale_labor: c.sale_labor_dinero && c.sale_labor_dinero.toFormat(),
|
||||||
sale_parts: c.sale_parts_dinero && c.sale_parts_dinero.toFormat(),
|
sale_parts: c.sale_parts_dinero && c.sale_parts_dinero.toFormat(),
|
||||||
sales: c.sale_labor_dinero.add(c.sale_parts_dinero).toFormat(),
|
sale_additional:
|
||||||
|
c.sale_additional_dinero && c.sale_additional_dinero.toFormat(),
|
||||||
|
sales: c.sales_dinero.toFormat(),
|
||||||
cost_parts: c.cost_parts_dinero && c.cost_parts_dinero.toFormat(),
|
cost_parts: c.cost_parts_dinero && c.cost_parts_dinero.toFormat(),
|
||||||
cost_labor: c.cost_labor_dinero && c.cost_labor_dinero.toFormat(),
|
cost_labor: c.cost_labor_dinero && c.cost_labor_dinero.toFormat(),
|
||||||
costs: c.cost_parts_dinero.add(c.cost_labor_dinero).toFormat(),
|
cost_additional:
|
||||||
|
c.cost_additional_dinero && c.cost_additional_dinero.toFormat(),
|
||||||
|
costs: c.costs_dinero.toFormat(),
|
||||||
gpdollars: c.gpdollars_dinero.toFormat(),
|
gpdollars: c.gpdollars_dinero.toFormat(),
|
||||||
gppercent: formatGpPercent(
|
gppercent: formatGpPercent(
|
||||||
(
|
(
|
||||||
@@ -340,33 +360,33 @@ function GenerateCostingData(job) {
|
|||||||
.multiply(val.prt_dsmk_p > 0 ? 1 : -1)
|
.multiply(val.prt_dsmk_p > 0 ? 1 : -1)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!acc.parts[partsProfitCenter])
|
if (!acc.additional[partsProfitCenter])
|
||||||
acc.parts[partsProfitCenter] = Dinero();
|
acc.additional[partsProfitCenter] = Dinero();
|
||||||
acc.parts[partsProfitCenter] =
|
acc.additional[partsProfitCenter] =
|
||||||
acc.parts[partsProfitCenter].add(partsAmount);
|
acc.additional[partsProfitCenter].add(partsAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{ parts: {}, labor: {} }
|
{ parts: {}, labor: {}, additional: {} }
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasMapaLine) {
|
if (!hasMapaLine) {
|
||||||
if (!jobLineTotalsByProfitCenter.parts[defaultProfits["MAPA"]])
|
if (!jobLineTotalsByProfitCenter.additional[defaultProfits["MAPA"]])
|
||||||
jobLineTotalsByProfitCenter.parts[defaultProfits["MAPA"]] = Dinero();
|
jobLineTotalsByProfitCenter.additional[defaultProfits["MAPA"]] = Dinero();
|
||||||
jobLineTotalsByProfitCenter.parts[defaultProfits["MAPA"]] =
|
jobLineTotalsByProfitCenter.additional[defaultProfits["MAPA"]] =
|
||||||
jobLineTotalsByProfitCenter.parts[defaultProfits["MAPA"]].add(
|
jobLineTotalsByProfitCenter.additional[defaultProfits["MAPA"]].add(
|
||||||
Dinero({
|
Dinero({
|
||||||
amount: Math.round((job.rate_mapa || 0) * 100),
|
amount: Math.round((job.rate_mapa || 0) * 100),
|
||||||
}).multiply(materialsHours.mapaHrs || 0)
|
}).multiply(materialsHours.mapaHrs || 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!hasMashLine) {
|
if (!hasMashLine) {
|
||||||
if (!jobLineTotalsByProfitCenter.parts[defaultProfits["MASH"]])
|
if (!jobLineTotalsByProfitCenter.additional[defaultProfits["MASH"]])
|
||||||
jobLineTotalsByProfitCenter.parts[defaultProfits["MASH"]] = Dinero();
|
jobLineTotalsByProfitCenter.additional[defaultProfits["MASH"]] = Dinero();
|
||||||
jobLineTotalsByProfitCenter.parts[defaultProfits["MASH"]] =
|
jobLineTotalsByProfitCenter.additional[defaultProfits["MASH"]] =
|
||||||
jobLineTotalsByProfitCenter.parts[defaultProfits["MASH"]].add(
|
jobLineTotalsByProfitCenter.additional[defaultProfits["MASH"]].add(
|
||||||
Dinero({
|
Dinero({
|
||||||
amount: Math.round((job.rate_mash || 0) * 100),
|
amount: Math.round((job.rate_mash || 0) * 100),
|
||||||
}).multiply(materialsHours.mashHrs || 0)
|
}).multiply(materialsHours.mashHrs || 0)
|
||||||
@@ -381,54 +401,88 @@ function GenerateCostingData(job) {
|
|||||||
)) ||
|
)) ||
|
||||||
job.bodyshop.md_responsibility_centers.defaults;
|
job.bodyshop.md_responsibility_centers.defaults;
|
||||||
|
|
||||||
const billTotalsByCostCenters = job.bills.reduce((bill_acc, bill_val) => {
|
const billTotalsByCostCenters = job.bills.reduce(
|
||||||
//At the bill level.
|
(bill_acc, bill_val) => {
|
||||||
bill_val.billlines.map((line_val) => {
|
//At the bill level.
|
||||||
//At the bill line level.
|
bill_val.billlines.map((line_val) => {
|
||||||
if (job.bodyshop.pbs_serialnumber || job.bodyshop.cdk_dealerid) {
|
//At the bill line level.
|
||||||
if (!bill_acc[selectedDmsAllocationConfig.costs[line_val.cost_center]])
|
if (job.bodyshop.pbs_serialnumber || job.bodyshop.cdk_dealerid) {
|
||||||
|
if (
|
||||||
|
!bill_acc[selectedDmsAllocationConfig.costs[line_val.cost_center]]
|
||||||
|
)
|
||||||
|
bill_acc[selectedDmsAllocationConfig.costs[line_val.cost_center]] =
|
||||||
|
Dinero();
|
||||||
|
|
||||||
bill_acc[selectedDmsAllocationConfig.costs[line_val.cost_center]] =
|
bill_acc[selectedDmsAllocationConfig.costs[line_val.cost_center]] =
|
||||||
Dinero();
|
bill_acc[
|
||||||
|
selectedDmsAllocationConfig.costs[line_val.cost_center]
|
||||||
|
].add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round((line_val.actual_cost || 0) * 100),
|
||||||
|
})
|
||||||
|
.multiply(line_val.quantity)
|
||||||
|
.multiply(bill_val.is_credit_memo ? -1 : 1)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const isAdditionalCostCenter =
|
||||||
|
// line_val.cost_center ===
|
||||||
|
// job.bodyshop.md_responsibility_centers.defaults.costs.PAS ||
|
||||||
|
// line_val.cost_center ===
|
||||||
|
// job.bodyshop.md_responsibility_centers.defaults.costs.PASL ||
|
||||||
|
line_val.cost_center ===
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.TOW ||
|
||||||
|
line_val.cost_center ===
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA ||
|
||||||
|
line_val.cost_center ===
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH;
|
||||||
|
|
||||||
bill_acc[selectedDmsAllocationConfig.costs[line_val.cost_center]] =
|
if (isAdditionalCostCenter) {
|
||||||
bill_acc[selectedDmsAllocationConfig.costs[line_val.cost_center]].add(
|
if (!bill_acc.additionalCosts[line_val.cost_center])
|
||||||
Dinero({
|
bill_acc.additionalCosts[line_val.cost_center] = Dinero();
|
||||||
amount: Math.round((line_val.actual_cost || 0) * 100),
|
|
||||||
})
|
|
||||||
.multiply(line_val.quantity)
|
|
||||||
.multiply(bill_val.is_credit_memo ? -1 : 1)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if (!bill_acc[line_val.cost_center])
|
|
||||||
bill_acc[line_val.cost_center] = Dinero();
|
|
||||||
|
|
||||||
bill_acc[line_val.cost_center] = bill_acc[line_val.cost_center].add(
|
bill_acc.additionalCosts[line_val.cost_center] =
|
||||||
Dinero({
|
bill_acc.additionalCosts[line_val.cost_center].add(
|
||||||
amount: Math.round((line_val.actual_cost || 0) * 100),
|
Dinero({
|
||||||
})
|
amount: Math.round((line_val.actual_cost || 0) * 100),
|
||||||
.multiply(line_val.quantity)
|
})
|
||||||
.multiply(bill_val.is_credit_memo ? -1 : 1)
|
.multiply(line_val.quantity)
|
||||||
);
|
.multiply(bill_val.is_credit_memo ? -1 : 1)
|
||||||
}
|
);
|
||||||
|
} else {
|
||||||
|
if (!bill_acc[line_val.cost_center])
|
||||||
|
bill_acc[line_val.cost_center] = Dinero();
|
||||||
|
|
||||||
return null;
|
bill_acc[line_val.cost_center] = bill_acc[line_val.cost_center].add(
|
||||||
});
|
Dinero({
|
||||||
return bill_acc;
|
amount: Math.round((line_val.actual_cost || 0) * 100),
|
||||||
}, {});
|
})
|
||||||
|
.multiply(line_val.quantity)
|
||||||
|
.multiply(bill_val.is_credit_memo ? -1 : 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return bill_acc;
|
||||||
|
},
|
||||||
|
{ additionalCosts: {} }
|
||||||
|
);
|
||||||
|
|
||||||
//If the hourly rates for job costing are set, add them in.
|
//If the hourly rates for job costing are set, add them in.
|
||||||
|
|
||||||
if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mapa) {
|
if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mapa) {
|
||||||
if (
|
if (
|
||||||
!billTotalsByCostCenters[
|
!billTotalsByCostCenters.additionalCosts[
|
||||||
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
billTotalsByCostCenters[
|
billTotalsByCostCenters.additionalCosts[
|
||||||
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
] = Dinero();
|
] = Dinero();
|
||||||
billTotalsByCostCenters[
|
billTotalsByCostCenters.additionalCosts[
|
||||||
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
] = billTotalsByCostCenters[
|
] = billTotalsByCostCenters.additionalCosts[
|
||||||
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
].add(
|
].add(
|
||||||
Dinero({
|
Dinero({
|
||||||
@@ -442,16 +496,16 @@ function GenerateCostingData(job) {
|
|||||||
|
|
||||||
if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mash) {
|
if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mash) {
|
||||||
if (
|
if (
|
||||||
!billTotalsByCostCenters[
|
!billTotalsByCostCenters.additionalCosts[
|
||||||
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
billTotalsByCostCenters[
|
billTotalsByCostCenters.additionalCosts[
|
||||||
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
||||||
] = Dinero();
|
] = Dinero();
|
||||||
billTotalsByCostCenters[
|
billTotalsByCostCenters.additionalCosts[
|
||||||
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
||||||
] = billTotalsByCostCenters[
|
] = billTotalsByCostCenters.additionalCosts[
|
||||||
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
||||||
].add(
|
].add(
|
||||||
Dinero({
|
Dinero({
|
||||||
@@ -511,9 +565,11 @@ function GenerateCostingData(job) {
|
|||||||
const summaryData = {
|
const summaryData = {
|
||||||
totalLaborSales: Dinero({ amount: 0 }),
|
totalLaborSales: Dinero({ amount: 0 }),
|
||||||
totalPartsSales: Dinero({ amount: 0 }),
|
totalPartsSales: Dinero({ amount: 0 }),
|
||||||
|
totalAdditionalSales: Dinero({ amount: 0 }),
|
||||||
totalSales: Dinero({ amount: 0 }),
|
totalSales: Dinero({ amount: 0 }),
|
||||||
totalLaborCost: Dinero({ amount: 0 }),
|
totalLaborCost: Dinero({ amount: 0 }),
|
||||||
totalPartsCost: Dinero({ amount: 0 }),
|
totalPartsCost: Dinero({ amount: 0 }),
|
||||||
|
totalAdditionalCost: Dinero({ amount: 0 }),
|
||||||
totalCost: Dinero({ amount: 0 }),
|
totalCost: Dinero({ amount: 0 }),
|
||||||
totalLaborGp: Dinero({ amount: 0 }),
|
totalLaborGp: Dinero({ amount: 0 }),
|
||||||
totalPartsGp: Dinero({ amount: 0 }),
|
totalPartsGp: Dinero({ amount: 0 }),
|
||||||
@@ -533,14 +589,16 @@ function GenerateCostingData(job) {
|
|||||||
jobLineTotalsByProfitCenter.labor[ccVal] || Dinero({ amount: 0 });
|
jobLineTotalsByProfitCenter.labor[ccVal] || Dinero({ amount: 0 });
|
||||||
const sale_parts =
|
const sale_parts =
|
||||||
jobLineTotalsByProfitCenter.parts[ccVal] || Dinero({ amount: 0 });
|
jobLineTotalsByProfitCenter.parts[ccVal] || Dinero({ amount: 0 });
|
||||||
|
const sale_additional =
|
||||||
|
jobLineTotalsByProfitCenter.additional[ccVal] || Dinero({ amount: 0 });
|
||||||
|
|
||||||
const cost_labor = ticketTotalsByCostCenter[ccVal] || Dinero({ amount: 0 });
|
const cost_labor = ticketTotalsByCostCenter[ccVal] || Dinero({ amount: 0 });
|
||||||
const cost_parts = billTotalsByCostCenters[ccVal] || Dinero({ amount: 0 });
|
const cost_parts = billTotalsByCostCenters[ccVal] || Dinero({ amount: 0 });
|
||||||
|
const cost_additional =
|
||||||
|
billTotalsByCostCenters.additionalCosts[ccVal] || Dinero({ amount: 0 });
|
||||||
|
|
||||||
const costs = (billTotalsByCostCenters[ccVal] || Dinero({ amount: 0 })).add(
|
const costs = cost_labor.add(cost_parts).add(cost_additional);
|
||||||
ticketTotalsByCostCenter[ccVal] || Dinero({ amount: 0 })
|
const totalSales = sale_labor.add(sale_parts).add(sale_additional);
|
||||||
);
|
|
||||||
const totalSales = sale_labor.add(sale_parts);
|
|
||||||
const gpdollars = totalSales.subtract(costs);
|
const gpdollars = totalSales.subtract(costs);
|
||||||
const gppercent = (
|
const gppercent = (
|
||||||
(gpdollars.getAmount() / totalSales.getAmount()) *
|
(gpdollars.getAmount() / totalSales.getAmount()) *
|
||||||
@@ -550,11 +608,13 @@ function GenerateCostingData(job) {
|
|||||||
//Push summary data to avoid extra loop.
|
//Push summary data to avoid extra loop.
|
||||||
summaryData.totalLaborSales = summaryData.totalLaborSales.add(sale_labor);
|
summaryData.totalLaborSales = summaryData.totalLaborSales.add(sale_labor);
|
||||||
summaryData.totalPartsSales = summaryData.totalPartsSales.add(sale_parts);
|
summaryData.totalPartsSales = summaryData.totalPartsSales.add(sale_parts);
|
||||||
summaryData.totalSales = summaryData.totalSales
|
summaryData.totalAdditionalSales =
|
||||||
.add(sale_labor)
|
summaryData.totalAdditionalSales.add(sale_additional);
|
||||||
.add(sale_parts);
|
summaryData.totalSales = summaryData.totalSales.add(totalSales);
|
||||||
summaryData.totalLaborCost = summaryData.totalLaborCost.add(cost_labor);
|
summaryData.totalLaborCost = summaryData.totalLaborCost.add(cost_labor);
|
||||||
summaryData.totalPartsCost = summaryData.totalPartsCost.add(cost_parts);
|
summaryData.totalPartsCost = summaryData.totalPartsCost.add(cost_parts);
|
||||||
|
summaryData.totalAdditionalCost =
|
||||||
|
summaryData.totalAdditionalCost.add(cost_additional);
|
||||||
summaryData.totalCost = summaryData.totalCost.add(costs);
|
summaryData.totalCost = summaryData.totalCost.add(costs);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -564,14 +624,18 @@ function GenerateCostingData(job) {
|
|||||||
sale_labor_dinero: sale_labor,
|
sale_labor_dinero: sale_labor,
|
||||||
sale_parts: sale_parts && sale_parts.toFormat(),
|
sale_parts: sale_parts && sale_parts.toFormat(),
|
||||||
sale_parts_dinero: sale_parts,
|
sale_parts_dinero: sale_parts,
|
||||||
sales: sale_labor.add(sale_parts).toFormat(),
|
sale_additional: sale_additional && sale_additional.toFormat(),
|
||||||
sales_dinero: sale_labor.add(sale_parts),
|
sale_additional_dinero: sale_additional,
|
||||||
|
sales: totalSales.toFormat(),
|
||||||
|
sales_dinero: totalSales,
|
||||||
cost_parts: cost_parts && cost_parts.toFormat(),
|
cost_parts: cost_parts && cost_parts.toFormat(),
|
||||||
cost_parts_dinero: cost_parts,
|
cost_parts_dinero: cost_parts,
|
||||||
cost_labor: cost_labor && cost_labor.toFormat(),
|
cost_labor: cost_labor && cost_labor.toFormat(),
|
||||||
cost_labor_dinero: cost_labor,
|
cost_labor_dinero: cost_labor,
|
||||||
costs: cost_parts.add(cost_labor).toFormat(),
|
cost_additional: cost_additional && cost_additional.toFormat(),
|
||||||
costs_dinero: cost_parts.add(cost_labor),
|
cost_additional_dinero: cost_additional,
|
||||||
|
costs: costs.toFormat(),
|
||||||
|
costs_dinero: costs,
|
||||||
gpdollars_dinero: gpdollars,
|
gpdollars_dinero: gpdollars,
|
||||||
gpdollars: gpdollars.toFormat(),
|
gpdollars: gpdollars.toFormat(),
|
||||||
gppercent: formatGpPercent(gppercent),
|
gppercent: formatGpPercent(gppercent),
|
||||||
@@ -675,6 +739,8 @@ const getAdditionalCostCenter = (jl, profitCenters) => {
|
|||||||
return profitCenters["MAPA"];
|
return profitCenters["MAPA"];
|
||||||
} else if (lineDesc.includes("ats amount")) {
|
} else if (lineDesc.includes("ats amount")) {
|
||||||
return profitCenters["ATS"];
|
return profitCenters["ATS"];
|
||||||
|
} else if (lineDesc.includes("towing")) {
|
||||||
|
return profitCenters["TOW"];
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user