diff --git a/client/src/components/job-detail-lines/job-lines.component.jsx b/client/src/components/job-detail-lines/job-lines.component.jsx
index 5097f668c..66dcc78d5 100644
--- a/client/src/components/job-detail-lines/job-lines.component.jsx
+++ b/client/src/components/job-detail-lines/job-lines.component.jsx
@@ -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,
diff --git a/client/src/components/shop-info/shop-info.component.jsx b/client/src/components/shop-info/shop-info.component.jsx
index df6410e6c..d166ae5f1 100644
--- a/client/src/components/shop-info/shop-info.component.jsx
+++ b/client/src/components/shop-info/shop-info.component.jsx
@@ -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 }) {
+
+
+
);
diff --git a/client/src/components/shop-info/shop-info.parts-scan.jsx b/client/src/components/shop-info/shop-info.parts-scan.jsx
new file mode 100644
index 000000000..317be28f2
--- /dev/null
+++ b/client/src/components/shop-info/shop-info.parts-scan.jsx
@@ -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 (
+
+ );
+}
diff --git a/client/src/graphql/bodyshop.queries.js b/client/src/graphql/bodyshop.queries.js
index f1e141434..5c718420a 100644
--- a/client/src/graphql/bodyshop.queries.js
+++ b/client/src/graphql/bodyshop.queries.js
@@ -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
diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js
index 028a7120e..dce7aff66 100644
--- a/client/src/graphql/jobs.queries.js
+++ b/client/src/graphql/jobs.queries.js
@@ -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
diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml
index b5fd3b656..9fa1b4c3d 100644
--- a/hasura/metadata/tables.yaml
+++ b/hasura/metadata/tables.yaml
@@ -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:
diff --git a/hasura/migrations/1678743865758_alter_table_public_bodyshops_add_column_md_parts_scan/down.sql b/hasura/migrations/1678743865758_alter_table_public_bodyshops_add_column_md_parts_scan/down.sql
new file mode 100644
index 000000000..67066918f
--- /dev/null
+++ b/hasura/migrations/1678743865758_alter_table_public_bodyshops_add_column_md_parts_scan/down.sql
@@ -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();
diff --git a/hasura/migrations/1678743865758_alter_table_public_bodyshops_add_column_md_parts_scan/up.sql b/hasura/migrations/1678743865758_alter_table_public_bodyshops_add_column_md_parts_scan/up.sql
new file mode 100644
index 000000000..3a6527e62
--- /dev/null
+++ b/hasura/migrations/1678743865758_alter_table_public_bodyshops_add_column_md_parts_scan/up.sql
@@ -0,0 +1,2 @@
+alter table "public"."bodyshops" add column "md_parts_scan" jsonb
+ not null default jsonb_build_array();
diff --git a/hasura/migrations/1678744973891_alter_table_public_joblines_add_column_critical/down.sql b/hasura/migrations/1678744973891_alter_table_public_joblines_add_column_critical/down.sql
new file mode 100644
index 000000000..5d1159047
--- /dev/null
+++ b/hasura/migrations/1678744973891_alter_table_public_joblines_add_column_critical/down.sql
@@ -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';
diff --git a/hasura/migrations/1678744973891_alter_table_public_joblines_add_column_critical/up.sql b/hasura/migrations/1678744973891_alter_table_public_joblines_add_column_critical/up.sql
new file mode 100644
index 000000000..0e7b53284
--- /dev/null
+++ b/hasura/migrations/1678744973891_alter_table_public_joblines_add_column_critical/up.sql
@@ -0,0 +1,2 @@
+alter table "public"."joblines" add column "critical" boolean
+ not null default 'false';
diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js
index de12f518e..e71bf2e4a 100644
--- a/server/graphql-client/queries.js
+++ b/server/graphql-client/queries.js
@@ -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
+ }
+}`;
diff --git a/server/parts-scan/parts-scan.js b/server/parts-scan/parts-scan.js
new file mode 100644
index 000000000..d3305f9c6
--- /dev/null
+++ b/server/parts-scan/parts-scan.js
@@ -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();
+ }
+};