ES Schema changes & initial upload attempt.

This commit is contained in:
Patrick Fic
2025-07-09 16:01:38 -07:00
parent 661c562a48
commit a1dfcf4457
40 changed files with 289 additions and 77 deletions

View File

@@ -52,11 +52,18 @@ async function DecodeEstimate(filePath, includeFilePathInReturnJob = false, clos
...(await DecodeVehFile(extensionlessFilePath)), ...(await DecodeVehFile(extensionlessFilePath)),
...(await DecodeTtlFile(extensionlessFilePath)), ...(await DecodeTtlFile(extensionlessFilePath)),
...(await DecodeLinFile(extensionlessFilePath, close_date)), ...(await DecodeLinFile(extensionlessFilePath, close_date)),
...(await DecodePflFile(extensionlessFilePath,)),
...(await DecodePfmFile(extensionlessFilePath,)),
...(await DecodeStlFile(extensionlessFilePath,)),
...(includeFilePathInReturnJob ? { filePath } : {}) ...(includeFilePathInReturnJob ? { filePath } : {})
}; };
const ad2 = await DecodeAd2File(extensionlessFilePath); const ad2 = await DecodeAd2File(extensionlessFilePath);
job.rates = [...job.rates || [], ...job.mat_rates || []];
delete job.mat_rates
if (job.OWNR_FN === "" || !job.OWNR_FN) job.OWNR_FN = ad2.CLMT_FN; if (job.OWNR_FN === "" || !job.OWNR_FN) job.OWNR_FN = ad2.CLMT_FN;
if (job.OWNR_LN === "" || !job.OWNR_LN) job.OWNR_LN = ad2.CLMT_LN; if (job.OWNR_LN === "" || !job.OWNR_LN) job.OWNR_LN = ad2.CLMT_LN;
if (job.OWNR_CO_NM) job.OWNR_LN = `${job.OWNR_LN} ${job.OWNR_CO_NM}`; if (job.OWNR_CO_NM) job.OWNR_LN = `${job.OWNR_LN} ${job.OWNR_CO_NM}`;
@@ -124,7 +131,7 @@ async function DecodeAd1File(extensionlessFilePath) {
// "INS_EA", // "INS_EA",
// "POLICY_NO", // "POLICY_NO",
// "DED_AMT", "DED_AMT",
// "DED_STATUS", // "DED_STATUS",
// "ASGN_NO", // "ASGN_NO",
//"ASGN_DATE", //"ASGN_DATE",
@@ -177,7 +184,7 @@ async function DecodeAd1File(extensionlessFilePath) {
// "AGT_LIC_NO", // "AGT_LIC_NO",
"LOSS_DATE", "LOSS_DATE",
"LOSS_TYPE", "LOSS_TYPE",
// "LOSS_DESC", "LOSS_DESC",
// "THEFT_IND", // "THEFT_IND",
// "CAT_NO", // "CAT_NO",
// "TLOS_IND", // "TLOS_IND",
@@ -202,14 +209,14 @@ async function DecodeAd1File(extensionlessFilePath) {
"OWNR_LN", "OWNR_LN",
"OWNR_FN", "OWNR_FN",
// "OWNR_TITLE", // "OWNR_TITLE",
"OWNR_CO_NM" "OWNR_CO_NM",
// "OWNR_ADDR1", "OWNR_ADDR1",
// "OWNR_ADDR2", // "OWNR_ADDR2",
// "OWNR_CITY", "OWNR_CITY",
// "OWNR_ST", // "OWNR_ST",
// "OWNR_ZIP", // "OWNR_ZIP",
// "OWNR_CTRY", // "OWNR_CTRY",
// "OWNR_PH1", "OWNR_PH1",
// "OWNR_PH1X", // "OWNR_PH1X",
// "OWNR_PH2", // "OWNR_PH2",
// "OWNR_PH2X", // "OWNR_PH2X",
@@ -272,7 +279,7 @@ async function DecodeVehFile(extensionlessFilePath) {
"V_MAKEDESC", "V_MAKEDESC",
"V_MODEL", "V_MODEL",
"V_TYPE", "V_TYPE",
"V_MILEAGE" "V_MILEAGE",
// "V_BSTYLE", // "V_BSTYLE",
// "V_TRIMCODE", // "V_TRIMCODE",
// "TRIM_COLOR", // "TRIM_COLOR",
@@ -280,7 +287,7 @@ async function DecodeVehFile(extensionlessFilePath) {
// "V_ENGINE", // "V_ENGINE",
// "V_COLOR", // "V_COLOR",
// "V_TONE", // "V_TONE",
// "V_STAGE", "V_STAGE",
// "PAINT_CD1", // "PAINT_CD1",
// "PAINT_CD2", // "PAINT_CD2",
// "PAINT_CD3", // "PAINT_CD3",
@@ -290,7 +297,7 @@ async function DecodeVehFile(extensionlessFilePath) {
async function DecodeTtlFile(extensionlessFilePath) { async function DecodeTtlFile(extensionlessFilePath) {
let dbf = await DBFFile.open(`${extensionlessFilePath}.TTL`); let dbf = await DBFFile.open(`${extensionlessFilePath}.TTL`);
let records = await dbf.readRecords(1); let records = await dbf.readRecords(1);
return { clm_total: records[0]["G_TTL_AMT"] }; return { clm_total: records[0]["G_TTL_AMT"], supp_amt: records[0]["SUPP_AMT"], g_bett_amt: records[0]["G_BETT_AMT"] };
} }
async function DecodeLinFile(extensionlessFilePath, close_date) { async function DecodeLinFile(extensionlessFilePath, close_date) {
@@ -311,17 +318,17 @@ async function DecodeLinFile(extensionlessFilePath, close_date) {
// "PART_DESCJ", // "PART_DESCJ",
"PRT_DSMK_M", "PRT_DSMK_M",
"OEM_PARTNO", "OEM_PARTNO",
// "PRICE_INC", "PRICE_INC",
// "ALT_PART_I", // "ALT_PART_I",
// "TAX_PART", "TAX_PART",
"DB_PRICE", "DB_PRICE",
"ACT_PRICE", "ACT_PRICE",
"PART_QTY", "PART_QTY",
"PRICE_J", "PRICE_J",
"GLASS_FLAG", "GLASS_FLAG",
// "CERT_PART", "CERT_PART",
// "ALT_CO_ID", // "ALT_CO_ID",
// "ALT_PARTNO", "ALT_PARTNO",
// "ALT_OVERRD", // "ALT_OVERRD",
// "ALT_PARTM", // "ALT_PARTM",
"PRT_DSMK_P", "PRT_DSMK_P",
@@ -333,7 +340,7 @@ async function DecodeLinFile(extensionlessFilePath, close_date) {
"LBR_OP", "LBR_OP",
"LBR_HRS_J", "LBR_HRS_J",
// "LBR_TYP_J", // "LBR_TYP_J",
// "LBR_OP_J", "LBR_OP_J",
// "PAINT_STG", // "PAINT_STG",
// "PAINT_TONE", // "PAINT_TONE",
// "LBR_TAX", // "LBR_TAX",
@@ -389,6 +396,52 @@ async function DecodeLinFile(extensionlessFilePath, close_date) {
return { joblines: { data: joblines } }; return { joblines: { data: joblines } };
} }
async function DecodePflFile(extensionlessFilePath,) {
let dbf = await DBFFile.open(`${extensionlessFilePath}.PFL`);
let records = await dbf.readRecords();
let pflLines = records.map((record) => {
return _.transform(
_.pick(record, [
"LBR_TYPE", "LBR_DESC", "LBR_RATE"
])
);
});
//Check for discounts that need to be ignored after the fact.
return { rates: pflLines };
}
async function DecodeStlFile(extensionlessFilePath,) {
let dbf = await DBFFile.open(`${extensionlessFilePath}.STL`);
let records = await dbf.readRecords();
let pflLines = records.map((record) => {
return _.transform(
_.pick(record, [
"TTL_TYPECD", "T_AMT", 'T_HRS', "NT_HRS"
])
);
});
//Check for discounts that need to be ignored after the fact.
return { totals: pflLines };
}
async function DecodePfmFile(extensionlessFilePath,) {
let dbf = await DBFFile.open(`${extensionlessFilePath}.PFM`);
let records = await dbf.readRecords();
let pflLines = records.map((record) => {
return _.transform(
_.pick(record, [
"MAT_TYPE", "CAL_PRETHR"
])
);
});
//Check for discounts that need to be ignored after the fact.
return { mat_rates: pflLines };
}
exports.DecodeEstimate = DecodeEstimate; exports.DecodeEstimate = DecodeEstimate;
exports.ImportJob = ImportJob; exports.ImportJob = ImportJob;

View File

@@ -10,20 +10,34 @@ const { BrowserWindow } = require("electron");
async function ScrubEstimate({ job }) { async function ScrubEstimate({ job }) {
//These need to be removed. //TODO: Fetch these from ImEX Online API.
const basicAuthUser = "Imex"; const basicAuthUser = "Imex";
const basicAuthpassword = "Patrick"; const basicAuthpassword = "Patrick";
const estimateScrubberUrl = "https://insurtechtoolkit.com/api/sendems"; const estimateScrubberUrl = "https://insurtechtoolkit.com/api/sendems";
const sendingEntityId = '87330f61-412b-4251-baaa-d026565b23c5'
//Perform data manipulation on the job object
if (!job) {
console.error("No job provided to ScrubEstimate");
return;
}
//Set shop metrics
job.sending_entity_id = sendingEntityId;
job.sending_entity_accept_terms_of_use = true;
job.association_switch = "ATAM";
job.rf_ph1 = "R0G 1Z0";
job.rf_zip = "2043792253";
job.g_ttl_amt = job.clm_total;
const fileName = `RPSTest-${job.id}-${Date.now()}`;
console.log("*** ~ ScrubEstimate ~ job:", job); console.log("*** ~ ScrubEstimate ~ job:", job);
//Build the JSON Form Data //Build the JSON Form Data
const fileName = `RPSTest-${job.id}-${Date.now()}`;
const formData = new FormData(); const formData = new FormData();
const jsonString = JSON.stringify(job); const jsonString = JSON.stringify(job);
formData.append("file", new Blob([jsonString], { type: "application/json" }), `${fileName}.json`); formData.append("file", new Blob([jsonString], { type: "application/json" }), `${fileName}.json`);
console.log("*** ~ ScrubEstimate ~ formData.getHeaders();:", formData);
const result = await axios.post(estimateScrubberUrl, formData, { const result = await axios.post(estimateScrubberUrl, formData, {
auth: { auth: {
username: basicAuthUser, username: basicAuthUser,
@@ -33,7 +47,7 @@ async function ScrubEstimate({ job }) {
}); });
console.log("*** ~ handleScrub ~ result:", result.data); console.log("*** ~ handleScrub ~ result:", result.data);
const resultPDFUrl = `https://www.insurtechtoolkit.com/analysis/${fileName}.pdf`; const resultPDFUrl = result?.data?.[0] || `https://www.insurtechtoolkit.com/analysis/${fileName}.pdf`;
console.log("*** ~ handleScrub ~ resultPDFUrl:", resultPDFUrl); console.log("*** ~ handleScrub ~ resultPDFUrl:", resultPDFUrl);
const pdfWindow = new BrowserWindow({ const pdfWindow = new BrowserWindow({

View File

@@ -16,72 +16,82 @@ insert_permissions:
authid: authid:
_eq: X-Hasura-User-Id _eq: X-Hasura-User-Id
columns: columns:
- act_price - cert_part
- alerts
- created_at
- db_hrs
- db_price
- db_ref
- glass_flag - glass_flag
- id
- ignore - ignore
- jobid
- lbr_amt
- lbr_hrs_j - lbr_hrs_j
- lbr_inc - lbr_inc
- lbr_op - lbr_op_j
- line_desc - price_inc
- line_ind - price_j
- tax_part
- alerts
- act_price
- db_hrs
- db_price
- lbr_amt
- line_no - line_no
- line_ref - line_ref
- misc_amt - misc_amt
- mod_lb_hrs - mod_lb_hrs
- mod_lbr_ty
- oem_partno
- part_qty - part_qty
- part_type
- price_diff - price_diff
- price_diff_pc - price_diff_pc
- price_j
- prt_dsmk_m - prt_dsmk_m
- prt_dsmk_p - prt_dsmk_p
- alt_partno
- db_ref
- lbr_op
- line_desc
- line_ind
- mod_lbr_ty
- oem_partno
- part_type
- unq_seq - unq_seq
- created_at
- updated_at - updated_at
- id
- jobid
select_permissions: select_permissions:
- role: user - role: user
permission: permission:
columns: columns:
- act_price - cert_part
- alerts
- created_at
- db_hrs
- db_price
- db_ref
- glass_flag - glass_flag
- id
- ignore - ignore
- jobid
- lbr_amt
- lbr_hrs_j - lbr_hrs_j
- lbr_inc - lbr_inc
- lbr_op - lbr_op_j
- line_desc - price_inc
- line_ind - price_j
- tax_part
- alerts
- act_price
- db_hrs
- db_price
- lbr_amt
- line_no - line_no
- line_ref - line_ref
- misc_amt - misc_amt
- mod_lb_hrs - mod_lb_hrs
- mod_lbr_ty
- oem_partno
- part_qty - part_qty
- part_type
- price_diff - price_diff
- price_diff_pc - price_diff_pc
- price_j
- prt_dsmk_m - prt_dsmk_m
- prt_dsmk_p - prt_dsmk_p
- alt_partno
- db_ref
- lbr_op
- line_desc
- line_ind
- mod_lbr_ty
- oem_partno
- part_type
- unq_seq - unq_seq
- created_at
- updated_at - updated_at
- id
- jobid
filter: filter:
job: job:
bodyshop: bodyshop:
@@ -93,37 +103,42 @@ update_permissions:
- role: user - role: user
permission: permission:
columns: columns:
- act_price - cert_part
- alerts
- created_at
- db_hrs
- db_price
- db_ref
- glass_flag - glass_flag
- id
- ignore - ignore
- jobid
- lbr_amt
- lbr_hrs_j - lbr_hrs_j
- lbr_inc - lbr_inc
- lbr_op - lbr_op_j
- line_desc - price_inc
- line_ind - price_j
- tax_part
- alerts
- act_price
- db_hrs
- db_price
- lbr_amt
- line_no - line_no
- line_ref - line_ref
- misc_amt - misc_amt
- mod_lb_hrs - mod_lb_hrs
- mod_lbr_ty
- oem_partno
- part_qty - part_qty
- part_type
- price_diff - price_diff
- price_diff_pc - price_diff_pc
- price_j
- prt_dsmk_m - prt_dsmk_m
- prt_dsmk_p - prt_dsmk_p
- alt_partno
- db_ref
- lbr_op
- line_desc
- line_ind
- mod_lbr_ty
- oem_partno
- part_type
- unq_seq - unq_seq
- created_at
- updated_at - updated_at
- id
- jobid
filter: filter:
job: job:
bodyshop: bodyshop:

View File

@@ -28,21 +28,31 @@ insert_permissions:
- clm_total - clm_total
- close_date - close_date
- created_at - created_at
- ded_amt
- g_bett_amt
- supp_amt
- group - group
- group_verified - group_verified
- id - id
- ins_co_nm - ins_co_nm
- loss_date - loss_date
- loss_desc
- ownr_addr1
- ownr_city
- ownr_fn - ownr_fn
- ownr_ln - ownr_ln
- ownr_ph1
- rates
- requires_reimport - requires_reimport
- ro_number - ro_number
- totals
- updated_at - updated_at
- v_age - v_age
- v_makedesc - v_makedesc
- v_mileage - v_mileage
- v_model - v_model
- v_model_yr - v_model_yr
- v_stage
- v_type - v_type
- v_vin - v_vin
select_permissions: select_permissions:
@@ -54,21 +64,31 @@ select_permissions:
- clm_total - clm_total
- close_date - close_date
- created_at - created_at
- ded_amt
- g_bett_amt
- supp_amt
- group - group
- group_verified - group_verified
- id - id
- ins_co_nm - ins_co_nm
- loss_date - loss_date
- loss_desc
- ownr_addr1
- ownr_city
- ownr_fn - ownr_fn
- ownr_ln - ownr_ln
- ownr_ph1
- rates
- requires_reimport - requires_reimport
- ro_number - ro_number
- totals
- updated_at - updated_at
- v_age - v_age
- v_makedesc - v_makedesc
- v_mileage - v_mileage
- v_model - v_model
- v_model_yr - v_model_yr
- v_stage
- v_type - v_type
- v_vin - v_vin
filter: filter:
@@ -87,21 +107,31 @@ update_permissions:
- clm_total - clm_total
- close_date - close_date
- created_at - created_at
- ded_amt
- g_bett_amt
- supp_amt
- group - group
- group_verified - group_verified
- id - id
- ins_co_nm - ins_co_nm
- loss_date - loss_date
- loss_desc
- ownr_addr1
- ownr_city
- ownr_fn - ownr_fn
- ownr_ln - ownr_ln
- ownr_ph1
- rates
- requires_reimport - requires_reimport
- ro_number - ro_number
- totals
- updated_at - updated_at
- v_age - v_age
- v_makedesc - v_makedesc
- v_mileage - v_mileage
- v_model - v_model
- v_model_yr - v_model_yr
- v_stage
- v_type - v_type
- v_vin - v_vin
filter: filter:

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "ded_amt" numeric
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "ded_amt" numeric
null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "loss_desc" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "loss_desc" text
null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "ownr_addr1" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "ownr_addr1" text
null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "ownr_city" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "ownr_city" text
null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "ownr_ph1" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "ownr_ph1" text
null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "v_stage" numeric
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "v_stage" numeric
null;

View File

@@ -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 "price_inc" boolean
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."joblines" add column "price_inc" boolean
null;

View File

@@ -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 "tax_part" boolean
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."joblines" add column "tax_part" boolean
null;

View File

@@ -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 "cert_part" boolean
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."joblines" add column "cert_part" boolean
null;

View File

@@ -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 "alt_partno" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."joblines" add column "alt_partno" text
null;

View File

@@ -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 "lbr_op_j" boolean
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."joblines" add column "lbr_op_j" boolean
null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "rates" jsonb
-- null default jsonb_build_array();

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "rates" jsonb
null default jsonb_build_array();

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "totals" jsonb
-- null default jsonb_build_array();

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "totals" jsonb
null default jsonb_build_array();

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "g_supp_amt" numeric
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "g_supp_amt" numeric
null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "g_bett_amt" numeric
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "g_bett_amt" numeric
null;

View File

@@ -0,0 +1 @@
alter table "public"."jobs" rename column "supp_amt" to "g_supp_amt";

View File

@@ -0,0 +1 @@
alter table "public"."jobs" rename column "g_supp_amt" to "supp_amt";

View File

@@ -3,7 +3,7 @@
"productName": "ImEX RPS", "productName": "ImEX RPS",
"author": "ImEX Systems Inc. <support@thinkimex.com>", "author": "ImEX Systems Inc. <support@thinkimex.com>",
"description": "ImEX RPS", "description": "ImEX RPS",
"version": "1.4.1-alpha.1", "version": "1.4.2-alpha.1",
"main": "electron/main.js", "main": "electron/main.js",
"homepage": "./", "homepage": "./",
"dependencies": { "dependencies": {

View File

@@ -35,14 +35,7 @@ export function EstimateScrubberButton({ bodyshop, jobid }) {
}); });
const result = await ipcRenderer.invoke(ipcTypes.app.toMain.scrubEstimate, { const result = await ipcRenderer.invoke(ipcTypes.app.toMain.scrubEstimate, {
job: { job: jobData.data.jobs_by_pk
...jobData.data.jobs_by_pk,
sending_entity_id: "87330f61-412b-4251-baaa-d026565b23c5",
sending_entity_clientid: "",
sending_entity_accept_terms_of_use: true,
profileid: "",
association_switch: "ATAM"
}
}); });
} catch (error) { } catch (error) {
message.error("Error scrubbing estimate: " + error.message); message.error("Error scrubbing estimate: " + error.message);

View File

@@ -83,7 +83,7 @@ export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) {
<Card <Card
title="Estimate Lines" title="Estimate Lines"
// extra={[<EstimateScrubberButton key="es" jobid={data ? data.jobs_by_pk?.id : null} />]} extra={[<EstimateScrubberButton key="es" jobid={data ? data.jobs_by_pk?.id : null} />]}
> >
<JobsLinesTableMolecule loading={loading} job={data ? data.jobs_by_pk : {}} /> <JobsLinesTableMolecule loading={loading} job={data ? data.jobs_by_pk : {}} />
</Card> </Card>

View File

@@ -225,6 +225,16 @@ export const QUERY_JOB_ESTIMATE_SCRUBBER = gql`
requires_reimport requires_reimport
created_at created_at
v_mileage v_mileage
rates
totals
ded_amt
loss_desc
ownr_addr1
ownr_city
ownr_ph1
v_stage
supp_amt
g_bett_amt
joblines(order_by: {line_no: asc}) { joblines(order_by: {line_no: asc}) {
line_no line_no
line_ind line_ind
@@ -245,6 +255,11 @@ export const QUERY_JOB_ESTIMATE_SCRUBBER = gql`
lbr_hrs_j lbr_hrs_j
lbr_amt lbr_amt
misc_amt misc_amt
price_inc
tax_part
cert_part
alt_partno
lbr_op_j
} }
} }
} }