From 6b64499e24581850e69a08f7d8a6a4adccc71690 Mon Sep 17 00:00:00 2001
From: Patrick Fic <>
Date: Tue, 10 Aug 2021 14:30:08 -0700
Subject: [PATCH] IO-233 Resolv merge issues & move allocations to ws
---
bodyshop_translations.babel | 131 ++++++++++++++++++
.../dms-allocations-summary.component.jsx | 111 +++------------
client/src/pages/dms/dms.container.jsx | 33 +++--
client/src/translations/en_us/common.json | 8 ++
client/src/translations/es/common.json | 8 ++
client/src/translations/fr/common.json | 8 ++
server/cdk/cdk-calculate-allocations.js | 121 ++++++++++++++++
server/graphql-client/queries.js | 101 ++++++++++++++
server/web-sockets/web-socket.js | 14 ++
9 files changed, 431 insertions(+), 104 deletions(-)
create mode 100644 server/cdk/cdk-calculate-allocations.js
diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel
index f8b337366..2d2352892 100644
--- a/bodyshop_translations.babel
+++ b/bodyshop_translations.babel
@@ -18520,6 +18520,137 @@
+
+ dms
+
+
+ center
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ cost
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ cost_dms_acctnumber
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ dms_wip_acctnumber
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ sale
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ sale_dms_acctnumber
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
driveable
false
diff --git a/client/src/components/dms-allocations-summary/dms-allocations-summary.component.jsx b/client/src/components/dms-allocations-summary/dms-allocations-summary.component.jsx
index 4bd0050e2..65b9434b6 100644
--- a/client/src/components/dms-allocations-summary/dms-allocations-summary.component.jsx
+++ b/client/src/components/dms-allocations-summary/dms-allocations-summary.component.jsx
@@ -1,11 +1,9 @@
-import { Table } from "antd";
-import React, { useMemo } from "react";
+import { Button, Table } from "antd";
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
-import Dinero from "dinero.js";
-import { useTranslation } from "react-i18next";
-import _ from "lodash";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
@@ -18,117 +16,41 @@ export default connect(
mapDispatchToProps
)(DmsAllocationsSummary);
-export function DmsAllocationsSummary({ bodyshop, job }) {
+export function DmsAllocationsSummary({ socket, bodyshop, jobId }) {
const { t } = useTranslation();
-
- const allocationsSummary = useMemo(() => {
- const profitCenterHash = job.joblines.reduce((acc, val) => {
- //Check the Parts Assignment
- if (val.profitcenter_part) {
- if (!acc[val.profitcenter_part]) acc[val.profitcenter_part] = Dinero();
-
- acc[val.profitcenter_part] = acc[val.profitcenter_part].add(
- Dinero({ amount: Math.round((val.act_price || 0) * 100) }).multiply(
- val.part_qty || 0
- )
- );
- }
- if (val.profitcenter_labor) {
- //Check the Labor Assignment.
-
- if (!acc[val.profitcenter_labor])
- acc[val.profitcenter_labor] = Dinero();
-
- acc[val.profitcenter_labor] = acc[val.profitcenter_labor].add(
- Dinero({
- amount: Math.round(
- job[`rate_${val.mod_lbr_ty.toLowerCase()}`] * 100
- ),
- }).multiply(val.mod_lb_hrs)
- );
- }
- return acc;
- }, {});
-
- const costCenterHash = job.bills.reduce((bill_acc, bill_val) => {
- bill_val.billlines.map((line_val) => {
- 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(
- Dinero({
- 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;
- }, {});
- console.log(
- "🚀 ~ file: dms-allocations-summary.component.jsx ~ line 69 ~ costCenterHash",
- costCenterHash
- );
-
- return _.union(
- Object.keys(profitCenterHash),
- Object.keys(costCenterHash)
- ).map((key) => {
- console.log("Key", key);
- const profitCenter = bodyshop.md_responsibility_centers.profits.find(
- (c) => c.name === key
- );
- const costCenter = bodyshop.md_responsibility_centers.costs.find(
- (c) => c.name === key
- );
-
- return {
- center: key,
- sale: profitCenterHash[key]
- ? profitCenterHash[key].toFormat()
- : Dinero().toFormat(),
- cost: costCenterHash[key]
- ? costCenterHash[key].toFormat()
- : Dinero().toFormat(),
- profitCenter,
- costCenter,
- };
- });
- }, [job, bodyshop.md_responsibility_centers]);
-
+ const [allocationsSummary, setAllocationsSummary] = useState([]);
const columns = [
{
- title: t("job.fields.dms.center"),
+ title: t("jobs.fields.dms.center"),
dataIndex: "center",
key: "center",
},
{
- title: t("job.fields.dms.sale"),
+ title: t("jobs.fields.dms.sale"),
dataIndex: "sale",
key: "sale",
},
{
- title: t("job.fields.dms.cost"),
+ title: t("jobs.fields.dms.cost"),
dataIndex: "cost",
key: "cost",
},
{
- title: t("job.fields.dms.sale_dms_acctnumber"),
+ title: t("jobs.fields.dms.sale_dms_acctnumber"),
dataIndex: "sale_dms_acctnumber",
key: "sale_dms_acctnumber",
render: (text, record) =>
record.profitCenter && record.profitCenter.dms_acctnumber,
},
{
- title: t("job.fields.dms.cost_dms_acctnumber"),
+ title: t("jobs.fields.dms.cost_dms_acctnumber"),
dataIndex: "cost_dms_acctnumber",
key: "cost_dms_acctnumber",
render: (text, record) =>
record.costCenter && record.costCenter.dms_acctnumber,
},
{
- title: t("job.fields.dms.dms_wip_acctnumber"),
+ title: t("jobs.fields.dms.dms_wip_acctnumber"),
dataIndex: "dms_wip_acctnumber",
key: "dms_wip_acctnumber",
render: (text, record) =>
@@ -138,6 +60,17 @@ export function DmsAllocationsSummary({ bodyshop, job }) {
return (
(
+
+ )}
pagination={{ position: "top", defaultPageSize: 50 }}
columns={columns}
rowKey="center"
diff --git a/client/src/pages/dms/dms.container.jsx b/client/src/pages/dms/dms.container.jsx
index ebc5100be..37c67fda9 100644
--- a/client/src/pages/dms/dms.container.jsx
+++ b/client/src/pages/dms/dms.container.jsx
@@ -1,5 +1,5 @@
import { useQuery } from "@apollo/client";
-import { Button, Result, Select, Space } from "antd";
+import { Button, Col, Result, Row, Select, Space } from "antd";
import queryString from "query-string";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -46,14 +46,14 @@ export const socket = SocketIO(
export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
const { t } = useTranslation();
- const [logLevel, setLogLevel] = useState("DEBUG");
+ const [logLevel, setLogLevel] = useState("TRACE");
const [logs, setLogs] = useState([]);
const search = queryString.parse(useLocation().search);
const { jobId } = search;
const { loading, error, data } = useQuery(QUERY_JOB_EXPORT_DMS, {
variables: { id: jobId },
- skip: !jobId,
+ skip: true, //!jobId,
});
useEffect(() => {
@@ -129,21 +129,24 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
socket.emit("set-log-level", value);
}}
>
- TRACE
- DEBUG
- INFO
- WARNING
- ERROR
+ TRACE
+ DEBUG
+ INFO
+ WARNING
+ ERROR
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 8f02fb73a..5d160c0d7 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -1140,6 +1140,14 @@
"ded_amt": "Deductible",
"ded_status": "Deductible Status",
"depreciation_taxes": "Depreciation/Taxes",
+ "dms": {
+ "center": "Center",
+ "cost": "Cost",
+ "cost_dms_acctnumber": "Cost DMS Acct #",
+ "dms_wip_acctnumber": "Cost WIP DMS Acct #",
+ "sale": "Sale",
+ "sale_dms_acctnumber": "Sale DMS Acct #"
+ },
"driveable": "Driveable",
"employee_body": "Body",
"employee_csr": "Customer Service Rep.",
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 841470e69..b66911cad 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -1140,6 +1140,14 @@
"ded_amt": "Deducible",
"ded_status": "Estado deducible",
"depreciation_taxes": "Depreciación / Impuestos",
+ "dms": {
+ "center": "",
+ "cost": "",
+ "cost_dms_acctnumber": "",
+ "dms_wip_acctnumber": "",
+ "sale": "",
+ "sale_dms_acctnumber": ""
+ },
"driveable": "",
"employee_body": "",
"employee_csr": "Representante de servicio al cliente.",
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index 0dd6abcba..435a10e71 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -1140,6 +1140,14 @@
"ded_amt": "Déductible",
"ded_status": "Statut de franchise",
"depreciation_taxes": "Amortissement / taxes",
+ "dms": {
+ "center": "",
+ "cost": "",
+ "cost_dms_acctnumber": "",
+ "dms_wip_acctnumber": "",
+ "sale": "",
+ "sale_dms_acctnumber": ""
+ },
"driveable": "",
"employee_body": "",
"employee_csr": "représentant du service à la clientèle",
diff --git a/server/cdk/cdk-calculate-allocations.js b/server/cdk/cdk-calculate-allocations.js
new file mode 100644
index 000000000..f17682876
--- /dev/null
+++ b/server/cdk/cdk-calculate-allocations.js
@@ -0,0 +1,121 @@
+const path = require("path");
+require("dotenv").config({
+ path: path.resolve(
+ process.cwd(),
+ `.env.${process.env.NODE_ENV || "development"}`
+ ),
+});
+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");
+
+exports.default = async function (socket, jobid) {
+ try {
+ CdkBase.createLogEvent(
+ socket,
+ "DEBUG",
+ `Received request to calculate allocations for ${jobid}`
+ );
+ const job = await QueryJobData(socket, jobid);
+ const { bodyshop } = job;
+
+ const profitCenterHash = job.joblines.reduce((acc, val) => {
+ //Check the Parts Assignment
+ if (val.profitcenter_part) {
+ if (!acc[val.profitcenter_part]) acc[val.profitcenter_part] = Dinero();
+
+ acc[val.profitcenter_part] = acc[val.profitcenter_part].add(
+ Dinero({
+ amount: Math.round((val.act_price || 0) * 100),
+ }).multiply(val.part_qty || 0)
+ );
+ }
+ if (val.profitcenter_labor) {
+ //Check the Labor Assignment.
+
+ if (!acc[val.profitcenter_labor])
+ acc[val.profitcenter_labor] = Dinero();
+
+ acc[val.profitcenter_labor] = acc[val.profitcenter_labor].add(
+ Dinero({
+ amount: Math.round(
+ job[`rate_${val.mod_lbr_ty.toLowerCase()}`] * 100
+ ),
+ }).multiply(val.mod_lb_hrs)
+ );
+ }
+ return acc;
+ }, {});
+
+ const costCenterHash = job.bills.reduce((bill_acc, bill_val) => {
+ bill_val.billlines.map((line_val) => {
+ 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(
+ Dinero({
+ 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;
+ }, {});
+ console.log(
+ "🚀 ~ file: dms-allocations-summary.component.jsx ~ line 69 ~ costCenterHash",
+ costCenterHash
+ );
+
+ return _.union(
+ Object.keys(profitCenterHash),
+ Object.keys(costCenterHash)
+ ).map((key) => {
+ console.log("Key", key);
+ const profitCenter = bodyshop.md_responsibility_centers.profits.find(
+ (c) => c.name === key
+ );
+ const costCenter = bodyshop.md_responsibility_centers.costs.find(
+ (c) => c.name === key
+ );
+
+ return {
+ center: key,
+ sale: profitCenterHash[key]
+ ? profitCenterHash[key].toFormat()
+ : Dinero().toFormat(),
+ cost: costCenterHash[key]
+ ? costCenterHash[key].toFormat()
+ : Dinero().toFormat(),
+ profitCenter,
+ costCenter,
+ };
+ });
+ } catch (error) {
+ CdkBase.createLogEvent(
+ socket,
+ "ERROR",
+ `Error encountered in CdkCalculateAllocations. ${error}`
+ );
+ }
+};
+
+async function QueryJobData(socket, jobid) {
+ CdkBase.createLogEvent(socket, "DEBUG", `Querying job data for id ${jobid}`);
+ const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
+ const result = await client
+ .setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
+ .request(queries.GET_CDK_ALLOCATIONS, { id: jobid });
+ CdkBase.createLogEvent(
+ socket,
+ "TRACE",
+ `Job data query result ${JSON.stringify(result, null, 2)}`
+ );
+ return result.jobs_by_pk;
+}
diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js
index d9d66aeca..40ec9d851 100644
--- a/server/graphql-client/queries.js
+++ b/server/graphql-client/queries.js
@@ -928,3 +928,104 @@ exports.GET_AUTOHOUSE_SHOPS = `query GET_AUTOHOUSE_SHOPS {
}
}
`;
+
+exports.GET_CDK_ALLOCATIONS = `
+ query QUERY_JOB_CLOSE_DETAILS($id: uuid!) {
+ jobs_by_pk(id: $id) {
+ bodyshop{
+ id
+ md_responsibility_centers
+ }
+ ro_number
+ invoice_allocation
+ ins_co_id
+ id
+ ded_amt
+ ded_status
+ depreciation_taxes
+ other_amount_payable
+ towing_payable
+ storage_payable
+ adjustment_bottom_line
+ federal_tax_rate
+ state_tax_rate
+ local_tax_rate
+ tax_tow_rt
+ tax_str_rt
+ tax_paint_mat_rt
+ tax_sub_rt
+ tax_lbr_rt
+ tax_levies_rt
+ parts_tax_rates
+ job_totals
+ rate_la1
+ rate_la2
+ rate_la3
+ rate_la4
+ rate_laa
+ rate_lab
+ rate_lad
+ rate_lae
+ rate_laf
+ rate_lag
+ rate_lam
+ rate_lar
+ rate_las
+ rate_lau
+ rate_ma2s
+ rate_ma2t
+ rate_ma3s
+ rate_mabl
+ rate_macs
+ rate_mahw
+ rate_mapa
+ rate_mash
+ rate_matd
+ status
+ date_exported
+ date_invoiced
+ voided
+ scheduled_completion
+ actual_completion
+ scheduled_delivery
+ actual_delivery
+ scheduled_in
+ actual_in
+ bills {
+ id
+ federal_tax_rate
+ local_tax_rate
+ state_tax_rate
+ is_credit_memo
+ billlines {
+ actual_cost
+ cost_center
+ id
+ quantity
+ }
+ }
+ joblines(where: { removed: { _eq: false } }) {
+ id
+ removed
+ tax_part
+ line_desc
+ prt_dsmk_p
+ prt_dsmk_m
+ part_type
+ oem_partno
+ db_price
+ act_price
+ part_qty
+ mod_lbr_ty
+ db_hrs
+ mod_lb_hrs
+ lbr_op
+ lbr_amt
+ op_code_desc
+ profitcenter_labor
+ profitcenter_part
+ prt_dsmk_p
+ }
+ }
+ }
+`;
diff --git a/server/web-sockets/web-socket.js b/server/web-sockets/web-socket.js
index 724fd7c73..61ef31557 100644
--- a/server/web-sockets/web-socket.js
+++ b/server/web-sockets/web-socket.js
@@ -9,6 +9,8 @@ require("dotenv").config({
const { io } = require("../../server");
const { admin } = require("../firebase/firebase-handler");
const CdkJobExport = require("../cdk/cdk-job-export").default;
+const CdkCalculateAllocations =
+ require("../cdk/cdk-calculate-allocations").default;
const { isArray } = require("lodash");
const logger = require("../utils/logger");
@@ -60,6 +62,18 @@ io.on("connection", (socket) => {
//CdkJobExport(socket, jobid);
});
+ socket.on("cdk-calculate-allocations", async (jobid, callback) => {
+ const allocations = await CdkCalculateAllocations(socket, jobid);
+ createLogEvent(socket, "DEBUG", `Allocations calculated.`);
+ createLogEvent(
+ socket,
+ "TRACE",
+ `Allocations calculated. ${JSON.stringify(allocations, null, 2)}`
+ );
+
+ callback(allocations);
+ });
+
socket.on("disconnect", () => {
createLogEvent(socket, "DEBUG", `User disconnected.`);
});