IO-2215 Critical parts scanning
This commit is contained in:
@@ -103,7 +103,12 @@ export function JobLinesComponent({
|
||||
fixed: "left",
|
||||
key: "line_desc",
|
||||
sorter: (a, b) => alphaSort(a.line_desc, b.line_desc),
|
||||
onCell: (record) => ({ className: record.manual_line && "job-line-manual" }),
|
||||
onCell: (record) => ({
|
||||
className: record.manual_line && "job-line-manual",
|
||||
style: {
|
||||
...(record.critical ? { boxShadow: " -.5em 0 0 #FFC107" } : {}),
|
||||
},
|
||||
}),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order,
|
||||
ellipsis: true,
|
||||
|
||||
@@ -8,6 +8,7 @@ import ShopInfoGeneral from "./shop-info.general.component";
|
||||
import ShopInfoIntakeChecklistComponent from "./shop-info.intake.component";
|
||||
import ShopInfoLaborRates from "./shop-info.laborrates.component";
|
||||
import ShopInfoOrderStatusComponent from "./shop-info.orderstatus.component";
|
||||
import ShopInfoPartsScan from "./shop-info.parts-scan";
|
||||
import ShopInfoRbacComponent from "./shop-info.rbac.component";
|
||||
import ShopInfoResponsibilityCenterComponent from "./shop-info.responsibilitycenters.component";
|
||||
import ShopInfoROStatusComponent from "./shop-info.rostatus.component";
|
||||
@@ -71,6 +72,9 @@ export function ShopInfoComponent({ bodyshop, form, saveLoading }) {
|
||||
<Tabs.TabPane key="laborrates" tab={t("bodyshop.labels.laborrates")}>
|
||||
<ShopInfoLaborRates form={form} />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane key="partsscan" tab={t("bodyshop.labels.partsscan")}>
|
||||
<ShopInfoPartsScan form={form} />
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
);
|
||||
|
||||
81
client/src/components/shop-info/shop-info.parts-scan.jsx
Normal file
81
client/src/components/shop-info/shop-info.parts-scan.jsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { DeleteFilled } from "@ant-design/icons";
|
||||
import { Button, Form, Input, Space } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
|
||||
export default function ShopInfoPartsScan({ form }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<LayoutFormRow header={t("bodyshop.labels.md_parts_scan")}>
|
||||
<Form.List name={["md_parts_scan"]}>
|
||||
{(fields, { add, remove, move }) => {
|
||||
return (
|
||||
<div>
|
||||
{fields.map((field, index) => (
|
||||
<Form.Item key={field.key}>
|
||||
<LayoutFormRow noDivider>
|
||||
<Form.Item
|
||||
label={t("bodyshop.fields.md_parts_scan.expression")}
|
||||
key={`${index}expression`}
|
||||
name={[field.name, "expression"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("bodyshop.fields.md_parts_scan.flags")}
|
||||
key={`${index}flags`}
|
||||
name={[field.name, "flags"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
||||
<Space wrap>
|
||||
<DeleteFilled
|
||||
onClick={() => {
|
||||
remove(field.name);
|
||||
}}
|
||||
/>
|
||||
<FormListMoveArrows
|
||||
move={move}
|
||||
index={index}
|
||||
total={fields.length}
|
||||
/>
|
||||
</Space>
|
||||
</LayoutFormRow>
|
||||
</Form.Item>
|
||||
))}
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={() => {
|
||||
add();
|
||||
}}
|
||||
style={{ width: "100%" }}
|
||||
>
|
||||
{t("bodyshop.actions.addpartsrule")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Form.List>
|
||||
</LayoutFormRow>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -114,6 +114,7 @@ export const QUERY_BODYSHOP = gql`
|
||||
localmediatoken
|
||||
enforce_conversion_csr
|
||||
md_lost_sale_reasons
|
||||
md_parts_scan
|
||||
employees {
|
||||
user_email
|
||||
id
|
||||
@@ -225,6 +226,7 @@ export const UPDATE_SHOP = gql`
|
||||
localmediatoken
|
||||
enforce_conversion_csr
|
||||
md_lost_sale_reasons
|
||||
md_parts_scan
|
||||
employees {
|
||||
id
|
||||
first_name
|
||||
|
||||
@@ -722,6 +722,7 @@ export const GET_JOB_BY_PK = gql`
|
||||
ioucreated
|
||||
convertedtolbr
|
||||
ah_detail_line
|
||||
critical
|
||||
billlines(limit: 1, order_by: { bill: { date: desc } }) {
|
||||
id
|
||||
quantity
|
||||
|
||||
@@ -796,6 +796,13 @@
|
||||
table:
|
||||
name: owners
|
||||
schema: public
|
||||
- name: payment_responses
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: bodyshopid
|
||||
table:
|
||||
name: payment_response
|
||||
schema: public
|
||||
- name: phonebooks
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
@@ -889,6 +896,7 @@
|
||||
- md_order_statuses
|
||||
- md_parts_locations
|
||||
- md_parts_order_comment
|
||||
- md_parts_scan
|
||||
- md_payment_types
|
||||
- md_rbac
|
||||
- md_referral_sources
|
||||
@@ -982,6 +990,7 @@
|
||||
- md_order_statuses
|
||||
- md_parts_locations
|
||||
- md_parts_order_comment
|
||||
- md_parts_scan
|
||||
- md_payment_types
|
||||
- md_rbac
|
||||
- md_referral_sources
|
||||
@@ -2562,6 +2571,7 @@
|
||||
- convertedtolbr
|
||||
- convertedtolbr_data
|
||||
- created_at
|
||||
- critical
|
||||
- db_hrs
|
||||
- db_price
|
||||
- db_ref
|
||||
@@ -2639,6 +2649,7 @@
|
||||
- convertedtolbr
|
||||
- convertedtolbr_data
|
||||
- created_at
|
||||
- critical
|
||||
- db_hrs
|
||||
- db_price
|
||||
- db_ref
|
||||
@@ -2903,6 +2914,13 @@
|
||||
table:
|
||||
name: parts_orders
|
||||
schema: public
|
||||
- name: payment_responses
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: jobid
|
||||
table:
|
||||
name: payment_response
|
||||
schema: public
|
||||
- name: payments
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
@@ -4575,6 +4593,13 @@
|
||||
table:
|
||||
name: exportlog
|
||||
schema: public
|
||||
- name: payment_responses
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: paymentid
|
||||
table:
|
||||
name: payment_response
|
||||
schema: public
|
||||
insert_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
|
||||
@@ -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 "md_parts_scan" jsonb
|
||||
-- not null default jsonb_build_array();
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."bodyshops" add column "md_parts_scan" jsonb
|
||||
not null default jsonb_build_array();
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."joblines" add column "critical" boolean
|
||||
-- not null default 'false';
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."joblines" add column "critical" boolean
|
||||
not null default 'false';
|
||||
@@ -906,7 +906,7 @@ exports.UPDATE_JOB = `
|
||||
}
|
||||
`;
|
||||
|
||||
exports.GET_JOB_BY_PK = ` query GET_JOB_BY_PK($id: uuid!) {
|
||||
exports.GET_JOB_BY_PK = `query GET_JOB_BY_PK($id: uuid!) {
|
||||
jobs_by_pk(id: $id) {
|
||||
updated_at
|
||||
alt_transport
|
||||
@@ -1719,3 +1719,27 @@ query GET_PBS_AP_ALLOCATIONS($billids: [uuid!]) {
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
exports.QUERY_PARTS_SCAN = `query QUERY_PARTS_SCAN ($id: uuid!) {
|
||||
jobs_by_pk(id: $id) {
|
||||
bodyshop {
|
||||
id
|
||||
md_parts_scan
|
||||
}
|
||||
joblines(where: {removed: {_eq: false}}) {
|
||||
id
|
||||
line_desc
|
||||
critical
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
exports.UPDATE_PARTS_CRITICAL = `mutation UPDATE_PARTS_CRITICAL ($IdsToMarkCritical:[uuid!]!, $jobid: uuid!){
|
||||
critical: update_joblines(where:{id:{_in:$IdsToMarkCritical}}, _set:{critical: true}){
|
||||
affected_rows
|
||||
}
|
||||
notcritical: update_joblines(where:{id:{_nin:$IdsToMarkCritical}, jobid: {_eq: $jobid}}, _set:{critical: false}){
|
||||
affected_rows
|
||||
}
|
||||
}`;
|
||||
|
||||
59
server/parts-scan/parts-scan.js
Normal file
59
server/parts-scan/parts-scan.js
Normal file
@@ -0,0 +1,59 @@
|
||||
const Dinero = require("dinero.js");
|
||||
const queries = require("../graphql-client/queries");
|
||||
const { job } = require("../scheduling/scheduling-job");
|
||||
const GraphQLClient = require("graphql-request").GraphQLClient;
|
||||
const logger = require("../utils/logger");
|
||||
// Dinero.defaultCurrency = "USD";
|
||||
// Dinero.globalLocale = "en-CA";
|
||||
|
||||
exports.partsScan = async function (req, res) {
|
||||
const BearerToken = req.headers.authorization;
|
||||
const { jobid } = req.body;
|
||||
logger.log("job-parts-scan", "DEBUG", req.user?.email, jobid, null);
|
||||
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {
|
||||
headers: {
|
||||
Authorization: BearerToken,
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const data = await client
|
||||
.setHeaders({ Authorization: BearerToken })
|
||||
.request(queries.QUERY_PARTS_SCAN, {
|
||||
id: jobid,
|
||||
});
|
||||
|
||||
const IdsToMarkCritical = [];
|
||||
const RegExpressions = data.jobs_by_pk.bodyshop.md_parts_scan.map(
|
||||
(r) => new RegExp(r.expression, r.flags)
|
||||
);
|
||||
|
||||
data.jobs_by_pk.joblines.forEach((jobline) => {
|
||||
RegExpressions.forEach((rExp) => {
|
||||
if (jobline.line_desc.match(rExp)) {
|
||||
console.log("Critical Parts Match", jobline.line_desc, rExp);
|
||||
IdsToMarkCritical.push(jobline);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
console.log(IdsToMarkCritical);
|
||||
|
||||
//Mark off ids not critical and critical.
|
||||
|
||||
const result = await client
|
||||
.setHeaders({ Authorization: BearerToken })
|
||||
.request(queries.UPDATE_PARTS_CRITICAL, {
|
||||
IdsToMarkCritical: IdsToMarkCritical.map((i) => i.id),
|
||||
jobid: jobid,
|
||||
});
|
||||
|
||||
res.status(200).json(result);
|
||||
} catch (error) {
|
||||
logger.log("job-parts-scan-error", "ERROR", req.user.email, id, {
|
||||
jobid: id,
|
||||
error,
|
||||
});
|
||||
res.status(503).send();
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user