IO-233 CDK Reformatting. First successful post.

This commit is contained in:
Patrick Fic
2021-09-10 14:58:09 -07:00
parent 22e30ae5cb
commit fe993cba73
14 changed files with 1101 additions and 382 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project version="1.2" be_version="2.7.1">
<babeledit_project be_version="2.7.1" version="1.2">
<!--
BabelEdit project file
@@ -17159,7 +17159,7 @@
</translations>
</concept_node>
<concept_node>
<name>getmakes</name>
<name>findmakemodelcode</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
@@ -17200,6 +17200,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>refetchmakesmodels</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>usegeneric</name>
<definition_loaded>false</definition_loaded>
@@ -18367,6 +18388,452 @@
</translation>
</translations>
</concept_node>
<folder_node>
<name>area_of_damage_impact</name>
<children>
<concept_node>
<name>01</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>02</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>03</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>04</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>05</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>06</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>07</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>08</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>09</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>10</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>11</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>12</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>13</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>14</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>15</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>16</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>25</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>26</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>27</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>28</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>34</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>
</folder_node>
<concept_node>
<name>ca_bc_pvrt</name>
<definition_loaded>false</definition_loaded>
@@ -23486,6 +23953,27 @@
<folder_node>
<name>dms</name>
<children>
<concept_node>
<name>defaultstory</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>kmoutnotgreaterthankmin</name>
<definition_loaded>false</definition_loaded>
@@ -23507,6 +23995,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>logs</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>notallocated</name>
<definition_loaded>false</definition_loaded>
@@ -23528,6 +24037,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>postingform</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>totalallocated</name>
<definition_loaded>false</definition_loaded>
@@ -37327,6 +37857,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>dms</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>export-logs</name>
<definition_loaded>false</definition_loaded>
@@ -38106,6 +38657,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>dms</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>export-logs</name>
<definition_loaded>false</definition_loaded>

View File

@@ -1,4 +1,4 @@
import { Button, Table, Typography } from "antd";
import { Button, Card, Table, Typography } from "antd";
import React, { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -21,7 +21,7 @@ export default connect(
mapDispatchToProps
)(DmsAllocationsSummary);
export function DmsAllocationsSummary({ socket, bodyshop, jobId }) {
export function DmsAllocationsSummary({ socket, bodyshop, jobId, ro_number }) {
const { t } = useTranslation();
const [allocationsSummary, setAllocationsSummary] = useState([]);
@@ -76,8 +76,9 @@ export function DmsAllocationsSummary({ socket, bodyshop, jobId }) {
];
return (
<Table
title={() => (
<Card
title={ro_number}
extra={
<Button
onClick={() => {
socket.emit("cdk-calculate-allocations", jobId, (ack) =>
@@ -87,43 +88,46 @@ export function DmsAllocationsSummary({ socket, bodyshop, jobId }) {
>
<SyncOutlined />
</Button>
)}
pagination={{ position: "top", defaultPageSize: 50 }}
columns={columns}
rowKey="center"
dataSource={allocationsSummary}
summary={() => {
const totals = allocationsSummary.reduce(
(acc, val) => {
return {
totalSale: acc.totalSale.add(Dinero(val.sale)),
totalCost: acc.totalCost.add(Dinero(val.cost)),
};
},
{
totalSale: Dinero(),
totalCost: Dinero(),
}
);
}
>
<Table
pagination={{ position: "top", defaultPageSize: 50 }}
columns={columns}
rowKey="center"
dataSource={allocationsSummary}
summary={() => {
const totals = allocationsSummary.reduce(
(acc, val) => {
return {
totalSale: acc.totalSale.add(Dinero(val.sale)),
totalCost: acc.totalCost.add(Dinero(val.cost)),
};
},
{
totalSale: Dinero(),
totalCost: Dinero(),
}
);
return (
<Table.Summary.Row>
<Table.Summary.Cell>
<Typography.Title level={4}>
{t("general.labels.totals")}
</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell>
{totals.totalSale.toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell>
{totals.totalCost.toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell>
</Table.Summary.Row>
);
}}
/>
return (
<Table.Summary.Row>
<Table.Summary.Cell>
<Typography.Title level={4}>
{t("general.labels.totals")}
</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell>
{totals.totalSale.toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell>
{totals.totalCost.toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell>
</Table.Summary.Row>
);
}}
/>
</Card>
);
}

View File

@@ -1,11 +1,11 @@
import { useLazyQuery } from "@apollo/client";
import { Button, Input, Modal, Table } from "antd";
import React, { useState } from "react";
import { Modal, Button, Table, Input } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { useTranslation } from "react-i18next";
import { useLazyQuery } from "@apollo/client";
import { SEARCH_DMS_VEHICLES } from "../../graphql/dms.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component";
const mapStateToProps = createStructuredSelector({
@@ -102,7 +102,7 @@ export function DmsCdkVehicles({ bodyshop, form, socket, job }) {
});
}}
>
{t("jobs.actions.dms.getmakes")}
{t("jobs.actions.dms.findmakemodelcode")}
</Button>
</div>
);

View File

@@ -4,6 +4,7 @@ import React, { useState } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { useTranslation } from "react-i18next";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
@@ -15,6 +16,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(DmsCdkMakesRefetch);
export function DmsCdkMakesRefetch({ bodyshop, form, socket }) {
const [loading, setLoading] = useState(false);
const { t } = useTranslation();
const handleRefetch = async () => {
setLoading(true);
const response = await axios.post("/cdk/getvehicles", {
@@ -26,7 +28,7 @@ export function DmsCdkMakesRefetch({ bodyshop, form, socket }) {
};
return (
<Button loading={loading} onClick={handleRefetch}>
Refetch Models
{t("jobs.actions.dms.refetchmakesmodels")}
</Button>
);
}

View File

@@ -1,4 +1,4 @@
import { Button, Table } from "antd";
import { Button, Table, Col } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -69,40 +69,42 @@ export function DmsCustomerSelector({ bodyshop }) {
if (!visible) return <></>;
return (
<Table
title={() => (
<div>
<Button onClick={onUseSelected} disabled={!selectedCustomer}>
{t("jobs.actions.dms.useselected")}
</Button>
<Button
onClick={onUseGeneric}
disabled={
!(
bodyshop.cdk_configuration &&
bodyshop.cdk_configuration.generic_customer_number
)
}
>
{t("jobs.actions.dms.usegeneric")}
</Button>
<Button onClick={onCreateNew}>
{t("jobs.actions.dms.createnewcustomer")}
</Button>
</div>
)}
pagination={{ position: "top" }}
columns={columns}
rowKey={(record) => record.id.value}
dataSource={customerList}
//onChange={handleTableChange}
rowSelection={{
onSelect: (props) => {
setSelectedCustomer(props.id.value);
},
type: "radio",
selectedRowKeys: [selectedCustomer],
}}
/>
<Col span={24}>
<Table
title={() => (
<div>
<Button onClick={onUseSelected} disabled={!selectedCustomer}>
{t("jobs.actions.dms.useselected")}
</Button>
<Button
onClick={onUseGeneric}
disabled={
!(
bodyshop.cdk_configuration &&
bodyshop.cdk_configuration.generic_customer_number
)
}
>
{t("jobs.actions.dms.usegeneric")}
</Button>
<Button onClick={onCreateNew}>
{t("jobs.actions.dms.createnewcustomer")}
</Button>
</div>
)}
pagination={{ position: "top" }}
columns={columns}
rowKey={(record) => record.id.value}
dataSource={customerList}
//onChange={handleTableChange}
rowSelection={{
onSelect: (props) => {
setSelectedCustomer(props.id.value);
},
type: "radio",
selectedRowKeys: [selectedCustomer],
}}
/>
</Col>
);
}

View File

@@ -1,24 +1,26 @@
import { DeleteFilled } from "@ant-design/icons";
import {
Button,
Card,
Divider,
Form,
Input,
InputNumber,
Select,
Space,
Statistic,
Typography,
} from "antd";
import Dinero from "dinero.js";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { determineDmsType } from "../../pages/dms/dms.container";
import { selectBodyshop } from "../../redux/user/user.selectors";
import DmsCdkMakes from "../dms-cdk-makes/dms-cdk-makes.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import Dinero from "dinero.js";
import { determineDmsType } from "../../pages/dms/dms.container";
import DmsCdkMakesRefetch from "../dms-cdk-makes/dms-cdk-makes.refetch.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
@@ -58,24 +60,90 @@ export function DmsPostForm({ bodyshop, socket, job }) {
};
return (
<Form form={form} layout="vertical" onFinish={handleFinish}>
<LayoutFormRow>
<Form.Item
name="journal"
label={t("jobs.fields.dms.journal")}
initialValue={
bodyshop.cdk_configuration &&
bodyshop.cdk_configuration.default_journal
}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Card title={t("jobs.labels.dms.postingform")}>
<Form
form={form}
layout="vertical"
onFinish={handleFinish}
initialValues={{
story: t("jobs.labels.dms.defaultstory", {
ro_number: job.ro_number,
area_of_damage: job.area_of_damage && job.area_of_damage.impact1,
}).substr(0, 249),
}}
>
<LayoutFormRow grow>
<Form.Item
name="journal"
label={t("jobs.fields.dms.journal")}
initialValue={
bodyshop.cdk_configuration &&
bodyshop.cdk_configuration.default_journal
}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="kmin"
label={t("jobs.fields.kmin")}
initialValue={job && job.kmin}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<InputNumber disabled />
</Form.Item>
<Form.Item
name="kmout"
label={t("jobs.fields.kmout")}
initialValue={job && job.kmout}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<InputNumber disabled />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow style={{ justifyContent: "center" }} grow>
<Form.Item
name="dms_make"
label={t("jobs.fields.dms.dms_make")}
rules={[
{
required: true,
},
]}
>
<Input disabled />
</Form.Item>
<Form.Item
name="dms_model"
label={t("jobs.fields.dms.dms_model")}
rules={[
{
required: true,
},
]}
>
<Input disabled />
</Form.Item>
<DmsCdkMakes form={form} socket={socket} job={job} />
{/* <DmsCdkMakesRefetch /> */}
</LayoutFormRow>
<Form.Item
name="story"
label={t("jobs.fields.dms.story")}
@@ -85,237 +153,186 @@ export function DmsPostForm({ bodyshop, socket, job }) {
},
]}
>
<Input.TextArea />
<Input.TextArea maxLength={250} />
</Form.Item>
<Form.Item
name="kmin"
label={t("jobs.fields.kmin")}
initialValue={job && job.kmin}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<InputNumber disabled />
</Form.Item>
<Form.Item
name="kmout"
label={t("jobs.fields.kmout")}
initialValue={job && job.kmout}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<InputNumber disabled />
</Form.Item>
<Form.Item
name="dms_make"
label={t("jobs.fields.dms.dms_make")}
rules={[
{
required: true,
},
]}
>
<Input disabled />
</Form.Item>
<Form.Item
name="dms_model"
label={t("jobs.fields.dms.dms_model")}
rules={[
{
required: true,
},
]}
>
<Input disabled />
</Form.Item>
<DmsCdkMakes form={form} socket={socket} job={job} />
<DmsCdkMakesRefetch />
</LayoutFormRow>
<Form.List name={["payers"]}>
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<LayoutFormRow>
<Form.Item
label={t("jobs.fields.dms.payer.name")}
key={`${index}name`}
name={[field.name, "name"]}
rules={[
{
required: true,
},
]}
>
<Select
onSelect={(value) => handlePayerSelect(value, index)}
<Divider />
<Form.List name={["payers"]}>
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<Space wrap>
<Form.Item
label={t("jobs.fields.dms.payer.name")}
key={`${index}name`}
name={[field.name, "name"]}
rules={[
{
required: true,
},
]}
>
{bodyshop.cdk_configuration &&
bodyshop.cdk_configuration.payers &&
bodyshop.cdk_configuration.payers.map((payer) => (
<Select.Option key={payer.name}>
{payer.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Select
style={{ minWidth: "15rem" }}
onSelect={(value) => handlePayerSelect(value, index)}
>
{bodyshop.cdk_configuration &&
bodyshop.cdk_configuration.payers &&
bodyshop.cdk_configuration.payers.map((payer) => (
<Select.Option key={payer.name}>
{payer.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
label={t("jobs.fields.dms.payer.dms_acctnumber")}
key={`${index}dms_acctnumber`}
name={[field.name, "dms_acctnumber"]}
rules={[
{
required: true,
},
]}
>
<Input disabled />
</Form.Item>
<Form.Item
label={t("jobs.fields.dms.payer.dms_acctnumber")}
key={`${index}dms_acctnumber`}
name={[field.name, "dms_acctnumber"]}
rules={[
{
required: true,
},
]}
>
<Input disabled />
</Form.Item>
<Form.Item
label={t("jobs.fields.dms.payer.amount")}
key={`${index}amount`}
name={[field.name, "amount"]}
rules={[
{
required: true,
},
]}
>
<CurrencyInput min={0} />
</Form.Item>
<Form.Item
label={t("jobs.fields.dms.payer.amount")}
key={`${index}amount`}
name={[field.name, "amount"]}
rules={[
{
required: true,
},
]}
>
<CurrencyInput min={0} />
</Form.Item>
<Form.Item
label={t("jobs.fields.dms.payer.controlnumber")}
key={`${index}controlnumber`}
name={[field.name, "controlnumber"]}
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("jobs.fields.dms.payer.controlnumber")}
key={`${index}controlnumber`}
name={[field.name, "controlnumber"]}
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item shouldUpdate>
{() => {
const payers = form.getFieldValue("payers");
<Form.Item shouldUpdate>
{() => {
const payers = form.getFieldValue("payers");
const row = payers && payers[index];
const row = payers && payers[index];
const cdkPayer =
bodyshop.cdk_configuration.payers &&
bodyshop.cdk_configuration.payers.find(
(i) => i && row && i.name === row.name
const cdkPayer =
bodyshop.cdk_configuration.payers &&
bodyshop.cdk_configuration.payers.find(
(i) => i && row && i.name === row.name
);
return (
<div>
{cdkPayer &&
t(`jobs.fields.${cdkPayer.control_type}`)}
</div>
);
}}
</Form.Item>
return (
<div>
{cdkPayer &&
t(`jobs.fields.${cdkPayer.control_type}`)}
</div>
);
}}
</Form.Item>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
</LayoutFormRow>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
</Space>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
disabled={!(fields.length < 3)}
onClick={() => {
if (fields.length < 3) add();
}}
style={{ width: "100%" }}
>
{t("jobs.actions.dms.addpayer")}
</Button>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
disabled={!(fields.length < 3)}
onClick={() => {
if (fields.length < 3) add();
}}
style={{ width: "100%" }}
>
{t("jobs.actions.dms.addpayer")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
<Form.Item shouldUpdate>
{() => {
//Perform Calculation to determine discrepancy.
let totalAllocated = Dinero();
const payers = form.getFieldValue("payers");
payers &&
payers.forEach((payer) => {
totalAllocated = totalAllocated.add(
Dinero({ amount: Math.round((payer?.amount || 0) * 100) })
);
});
const totals =
socket.allocationsSummary &&
socket.allocationsSummary.reduce(
(acc, val) => {
return {
totalSale: acc.totalSale.add(Dinero(val.sale)),
totalCost: acc.totalCost.add(Dinero(val.cost)),
};
},
{
totalSale: Dinero(),
totalCost: Dinero(),
}
</div>
);
const discrep = totals
? totals.totalSale.subtract(totalAllocated)
: Dinero();
return (
<Space>
<Statistic
title={t("jobs.labels.dms.totalallocated")}
value={totalAllocated.toFormat()}
/>
<Statistic
title={t("jobs.labels.subtotal")}
value={(totals ? totals.totalSale : Dinero()).toFormat()}
/>
<Statistic
title={t("jobs.labels.dms.notallocated")}
valueStyle={{
color: discrep.getAmount() === 0 ? "green" : "red",
}}
value={discrep.toFormat()}
/>
<Button disabled={discrep.getAmount() !== 0} htmlType="submit">
{t("jobs.actions.dms.post")}
</Button>
<Button
onClick={() => {
socket.emit(`${determineDmsType(bodyshop)}-export-job`, {
jobid: job.id,
});
}}
>
Bypass
</Button>
</Space>
);
}}
</Form.Item>
</Form>
}}
</Form.List>
<Form.Item shouldUpdate>
{() => {
//Perform Calculation to determine discrepancy.
let totalAllocated = Dinero();
const payers = form.getFieldValue("payers");
payers &&
payers.forEach((payer) => {
totalAllocated = totalAllocated.add(
Dinero({ amount: Math.round((payer?.amount || 0) * 100) })
);
});
const totals =
socket.allocationsSummary &&
socket.allocationsSummary.reduce(
(acc, val) => {
return {
totalSale: acc.totalSale.add(Dinero(val.sale)),
totalCost: acc.totalCost.add(Dinero(val.cost)),
};
},
{
totalSale: Dinero(),
totalCost: Dinero(),
}
);
const discrep = totals
? totals.totalSale.subtract(totalAllocated)
: Dinero();
return (
<Space size="large" wrap align="center">
<Statistic
title={t("jobs.labels.subtotal")}
value={(totals ? totals.totalSale : Dinero()).toFormat()}
/>
<Typography.Title>-</Typography.Title>
<Statistic
title={t("jobs.labels.dms.totalallocated")}
value={totalAllocated.toFormat()}
/>
<Typography.Title>=</Typography.Title>
<Statistic
title={t("jobs.labels.dms.notallocated")}
valueStyle={{
color: discrep.getAmount() === 0 ? "green" : "red",
}}
value={discrep.toFormat()}
/>
<Button
disabled={
!socket.allocationsSummary || discrep.getAmount() !== 0
}
htmlType="submit"
>
{t("jobs.actions.dms.post")}
</Button>
</Space>
);
}}
</Form.Item>
</Form>
</Card>
);
}

View File

@@ -13,6 +13,7 @@ import {
} from "../../redux/user/user.selectors";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
import { useHistory } from "react-router-dom";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -26,11 +27,17 @@ export function JobsCloseExportButton({
disabled,
setSelectedJobs,
}) {
const history = useHistory();
const { t } = useTranslation();
const [updateJob] = useMutation(UPDATE_JOB);
const [insertExportLog] = useMutation(INSERT_EXPORT_LOG);
const [loading, setLoading] = useState(false);
const handleQbxml = async () => {
if (bodyshop.cdk_dealerid) {
history.push(`/manage/dms?jobId=${jobId}`);
return;
}
logImEXEvent("jobs_close_export");
setLoading(true);
@@ -159,12 +166,7 @@ export function JobsCloseExportButton({
};
return (
<Button
onClick={handleQbxml}
loading={loading}
disabled={disabled}
type="dashed"
>
<Button onClick={handleQbxml} loading={loading} disabled={disabled}>
{t("jobs.actions.export")}
</Button>
);

View File

@@ -1890,6 +1890,7 @@ export const QUERY_JOB_EXPORT_DMS = gql`
kmin
kmout
v_model_desc
area_of_damage
}
}
`;

View File

@@ -1,10 +1,19 @@
import { useQuery } from "@apollo/client";
import { Button, Col, Result, Row, Select, Space } from "antd";
import {
Button,
Card,
Col,
notification,
Result,
Row,
Select,
Space,
} from "antd";
import queryString from "query-string";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation } from "react-router-dom";
import { useLocation, useHistory } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import SocketIO from "socket.io-client";
import AlertComponent from "../../components/alert/alert.component";
@@ -48,6 +57,7 @@ export const socket = SocketIO(
export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
const { t } = useTranslation();
const [logLevel, setLogLevel] = useState("DEBUG");
const history = useHistory();
const [logs, setLogs] = useState([]);
const search = queryString.parse(useLocation().search);
const { jobId } = search;
@@ -88,6 +98,12 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
return [...logs, payload];
});
});
socket.on("export-success", (payload) => {
notification.success({
message: t("jobs.successes.exported"),
});
history.push("/manage/accounting/receivables");
});
return () => {
socket.removeAllListeners();
socket.disconnect();
@@ -95,49 +111,68 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
if (!jobId || !bodyshop.cdk_dealerid || !(data && data.jobs_by_pk))
return <Result status="404" />;
if (loading) return <LoadingSpinner />;
if (error) return <AlertComponent message={error.message} type="error" />;
if (!jobId || !bodyshop.cdk_dealerid || !(data && data.jobs_by_pk))
return <Result status="404" />;
return (
<div>
<Row gutter={32}>
<Col span={18}>
{data && data.jobs_by_pk && data.jobs_by_pk.ro_number}
<DmsAllocationsSummary socket={socket} jobId={jobId} />
<Row gutter={[16, 16]}>
<Col span={10}>
<DmsAllocationsSummary
ro_number={data && data.jobs_by_pk && data.jobs_by_pk.ro_number}
socket={socket}
jobId={jobId}
/>
</Col>
<Col span={14}>
<DmsPostForm
socket={socket}
jobId={jobId}
job={data && data.jobs_by_pk}
/>
</Col>
<Col span={6}>
<Space>
<Select
placeholder="Log Level"
value={logLevel}
onChange={(value) => {
setLogLevel(value);
socket.emit("set-log-level", value);
}}
>
<Select.Option key="TRACE">TRACE</Select.Option>
<Select.Option key="DEBUG">DEBUG</Select.Option>
<Select.Option key="INFO">INFO</Select.Option>
<Select.Option key="WARNING">WARNING</Select.Option>
<Select.Option key="ERROR">ERROR</Select.Option>
</Select>
<Button onClick={() => setLogs([])}>Clear Logs</Button>
</Space>
<div style={{ maxHeight: "500px", overflowY: "auto" }}>
<DmsCustomerSelector />
<Col span={24}>
<Card
title={t("jobs.labels.dms.logs")}
extra={
<Space wrap>
<Select
placeholder="Log Level"
value={logLevel}
onChange={(value) => {
setLogLevel(value);
socket.emit("set-log-level", value);
}}
>
<Select.Option key="TRACE">TRACE</Select.Option>
<Select.Option key="DEBUG">DEBUG</Select.Option>
<Select.Option key="INFO">INFO</Select.Option>
<Select.Option key="WARNING">WARNING</Select.Option>
<Select.Option key="ERROR">ERROR</Select.Option>
</Select>
<Button onClick={() => setLogs([])}>Clear Logs</Button>
<Button
onClick={() => {
setLogs([]);
socket.disconnect();
socket.connect();
}}
>
Reconnect
</Button>
</Space>
}
>
<DmsLogEvents socket={socket} logs={logs} />
</div>
</Card>
</Col>
</Row>
<DmsCustomerSelector />
</div>
);
}

View File

@@ -1076,8 +1076,9 @@
"dms": {
"addpayer": "Add Payer",
"createnewcustomer": "Create New Customer",
"getmakes": "Get Makes",
"findmakemodelcode": "Find Make/Model Code",
"post": "Post",
"refetchmakesmodels": "Refetch Make and Model Codes",
"usegeneric": "Use Generic Customer",
"useselected": "Use Selected Customer"
},
@@ -1138,6 +1139,29 @@
"adjustment_bottom_line": "Adjustments",
"adjustmenthours": "Adjustment Hours",
"alt_transport": "Alt. Trans.",
"area_of_damage_impact": {
"10": "Left Front Side",
"11": "Left Front Corner",
"12": "Front",
"13": "Rollover",
"14": "Unknown",
"15": "Total Loss",
"16": "Non-collision",
"25": "Hood",
"26": "Deck-lid",
"27": "Roof",
"28": "Undercarriage",
"34": "All Over",
"01": "Right Front Corner",
"02": "Right Front Side",
"03": "Right Side",
"04": "Right Rear Side",
"05": "Right Rear Corner",
"06": "Rear",
"07": "Left Rear Corner",
"08": "Left Rear Side",
"09": "Left Side"
},
"ca_bc_pvrt": "PVRT",
"ca_customer_gst": "Customer Portion of GST",
"ca_gst_registrant": "GST Registrant",
@@ -1402,8 +1426,11 @@
"difference": "Difference",
"diskscan": "Scan Disk for Estimates",
"dms": {
"defaultstory": "Bodyshop RO {{ro_number}}. Damage to $t(jobs.fields.area_of_damage_impact.{{area_of_damage}}).",
"kmoutnotgreaterthankmin": "Mileage out must be greater than mileage in.",
"logs": "Logs",
"notallocated": "Not Allocated",
"postingform": "Posting Form",
"totalallocated": "Total Amount Allocated"
},
"documents": "Documents",
@@ -2247,6 +2274,7 @@
"courtesycars-detail": "Courtesy Car {{number}}",
"courtesycars-new": "New Courtesy Car",
"dashboard": "Dashboard",
"dms": "DMS Export",
"export-logs": "Export Logs",
"jobs": "Jobs",
"jobs-active": "Active Jobs",
@@ -2285,6 +2313,7 @@
"courtesycars-create": "New Courtesy Car | $t(titles.app)",
"courtesycars-detail": "Courtesy Car {{id}} | $t(titles.app)",
"dashboard": "Dashboard | $t(titles.app)",
"dms": "DMS Export | $t(titles.app)",
"export-logs": "Export Logs | $t(titles.app)",
"jobs": "Active Jobs | $t(titles.app)",
"jobs-admin": "Job {{ro_number}} - Admin | $t(titles.app)",

View File

@@ -1076,8 +1076,9 @@
"dms": {
"addpayer": "",
"createnewcustomer": "",
"getmakes": "",
"findmakemodelcode": "",
"post": "",
"refetchmakesmodels": "",
"usegeneric": "",
"useselected": ""
},
@@ -1138,6 +1139,29 @@
"adjustment_bottom_line": "Ajustes",
"adjustmenthours": "",
"alt_transport": "",
"area_of_damage_impact": {
"10": "",
"11": "",
"12": "",
"13": "",
"14": "",
"15": "",
"16": "",
"25": "",
"26": "",
"27": "",
"28": "",
"34": "",
"01": "",
"02": "",
"03": "",
"04": "",
"05": "",
"06": "",
"07": "",
"08": "",
"09": ""
},
"ca_bc_pvrt": "",
"ca_customer_gst": "",
"ca_gst_registrant": "",
@@ -1402,8 +1426,11 @@
"difference": "",
"diskscan": "",
"dms": {
"defaultstory": "",
"kmoutnotgreaterthankmin": "",
"logs": "",
"notallocated": "",
"postingform": "",
"totalallocated": ""
},
"documents": "documentos",
@@ -2247,6 +2274,7 @@
"courtesycars-detail": "",
"courtesycars-new": "",
"dashboard": "",
"dms": "",
"export-logs": "",
"jobs": "",
"jobs-active": "",
@@ -2285,6 +2313,7 @@
"courtesycars-create": "",
"courtesycars-detail": "",
"dashboard": "",
"dms": "",
"export-logs": "",
"jobs": "Todos los trabajos | $t(titles.app)",
"jobs-admin": "",

View File

@@ -1076,8 +1076,9 @@
"dms": {
"addpayer": "",
"createnewcustomer": "",
"getmakes": "",
"findmakemodelcode": "",
"post": "",
"refetchmakesmodels": "",
"usegeneric": "",
"useselected": ""
},
@@ -1138,6 +1139,29 @@
"adjustment_bottom_line": "Ajustements",
"adjustmenthours": "",
"alt_transport": "",
"area_of_damage_impact": {
"10": "",
"11": "",
"12": "",
"13": "",
"14": "",
"15": "",
"16": "",
"25": "",
"26": "",
"27": "",
"28": "",
"34": "",
"01": "",
"02": "",
"03": "",
"04": "",
"05": "",
"06": "",
"07": "",
"08": "",
"09": ""
},
"ca_bc_pvrt": "",
"ca_customer_gst": "",
"ca_gst_registrant": "",
@@ -1402,8 +1426,11 @@
"difference": "",
"diskscan": "",
"dms": {
"defaultstory": "",
"kmoutnotgreaterthankmin": "",
"logs": "",
"notallocated": "",
"postingform": "",
"totalallocated": ""
},
"documents": "Les documents",
@@ -2247,6 +2274,7 @@
"courtesycars-detail": "",
"courtesycars-new": "",
"dashboard": "",
"dms": "",
"export-logs": "",
"jobs": "",
"jobs-active": "",
@@ -2285,6 +2313,7 @@
"courtesycars-create": "",
"courtesycars-detail": "",
"dashboard": "",
"dms": "",
"export-logs": "",
"jobs": "Tous les emplois | $t(titles.app)",
"jobs-admin": "",

View File

@@ -8,14 +8,11 @@ require("dotenv").config({
const GraphQLClient = require("graphql-request").GraphQLClient;
const soap = require("soap");
const queries = require("../graphql-client/queries");
const CdkBase = require("../web-sockets/web-socket");
const CdkWsdl = require("./cdk-wsdl").default;
const logger = require("../utils/logger");
const Dinero = require("dinero.js");
const _ = require("lodash");
const { CDK_CREDENTIALS, CheckCdkResponseForError } = require("./cdk-wsdl");
const { performance } = require("perf_hooks");
const apiGqlClient = require("../graphql-client/graphql-client").client;
// exports.default = async function (socket, cdk_dealerid) {
// try {
@@ -87,6 +84,7 @@ exports.default = async function ReloadCdkMakes(req, res) {
count: newList.length,
}
);
res.sendStatus(200);
} catch (error) {
logger.log(
"cdk-replace-makes-models-error",
@@ -98,6 +96,7 @@ exports.default = async function ReloadCdkMakes(req, res) {
error,
}
);
res.status(500).json(error);
}
};
@@ -108,7 +107,7 @@ async function GetCdkMakes(req, cdk_dealerid) {
try {
const soapClientVehicleInsert = await soap.createClientAsync(
CdkWsdl.VehicleInsert
CdkWsdl.VehicleInsertUpdate
);
const soapResponseVehicleSearch =

View File

@@ -84,14 +84,6 @@ exports.default = async function (socket, { txEnvelope, jobid }) {
"ERROR",
`Error encountered in CdkJobExport. ${error}`
);
} finally {
//Ensure we always insert logEvents
//GQL to insert logevents.
CdkBase.createLogEvent(
socket,
"DEBUG",
`Capturing log events to database.`
);
}
};
@@ -183,6 +175,8 @@ async function CdkSelectedCustomer(socket, selectedCustomerId) {
);
await MarkJobExported(socket, socket.JobData.id);
socket.emit("export-success", socket.JobData.id);
} else {
//Get the error code
CdkBase.createLogEvent(
@@ -209,7 +203,7 @@ async function CdkSelectedCustomer(socket, selectedCustomerId) {
CdkBase.createLogEvent(
socket,
"ERROR",
`Error(s) encountered in posting transaction. ${e}`
r`Error(s) encountered in posting transaction. ${e}`
)
);
}
@@ -1224,7 +1218,11 @@ async function DeleteDmsWip(socket) {
}
async function MarkJobExported(socket, jobid) {
CdkBase.createLogEvent(socket, "DEBUG", `Querying job data for id ${jobid}`);
CdkBase.createLogEvent(
socket,
"DEBUG",
`Marking job as exported for id ${jobid}`
);
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
const result = await client
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })