681 lines
19 KiB
JavaScript
681 lines
19 KiB
JavaScript
const { DBFFile } = require("dbffile");
|
||
const path = require("path");
|
||
const _ = require("lodash");
|
||
const log = require("electron-log");
|
||
const { store } = require("../electron-store");
|
||
const { BrowserWindow } = require("electron");
|
||
const ipcTypes = require("../../src/ipc.types.commonjs");
|
||
const { NewNotification } = require("../notification-wrapper/notification-wrapper");
|
||
const { WhichRulesetToApply } = require("./constants");
|
||
const { claimsClerk } = require("../claims-clerk/claims-clerk");
|
||
//const Nucleus = require("nucleus-nodejs");
|
||
|
||
async function ImportJob(filepath) {
|
||
const parsedFilePath = path.parse(filepath);
|
||
let extensionlessFilePath = path.join(parsedFilePath.dir, parsedFilePath.name);
|
||
|
||
const decodedJob = await DecodeAd1File(extensionlessFilePath);
|
||
const b = BrowserWindow.getAllWindows()[0];
|
||
b.webContents.send(ipcTypes.default.estimate.toRenderer.getCloseDate, {
|
||
filepath,
|
||
clm_no: decodedJob.CLM_NO
|
||
});
|
||
}
|
||
|
||
async function ImportJobWithCloseDate(filepath, close_date) {
|
||
const newJob = await DecodeEstimate(filepath, false, close_date);
|
||
const b = BrowserWindow.getAllWindows()[0];
|
||
if (newJob && !newJob.ERROR) {
|
||
b.webContents.send(ipcTypes.default.estimate.toRenderer.estimateDecodeSuccess, newJob);
|
||
log.info(`Sent job for upload. ${newJob.clm_no}`);
|
||
NewNotification({
|
||
title: "Job Uploaded",
|
||
body: "A new job has been uploaded."
|
||
});
|
||
} else {
|
||
log.info(`Ignored job. ${newJob.ERROR}`);
|
||
// Nucleus.track("IGNORE_JOB", { reason: newJob.ERROR });
|
||
NewNotification({
|
||
title: "Job Ignored",
|
||
body: newJob.ERROR
|
||
});
|
||
}
|
||
}
|
||
|
||
exports.ImportJobWithCloseDate = ImportJobWithCloseDate;
|
||
|
||
async function DecodeEstimate(filePath, includeFilePathInReturnJob = false, close_date = null) {
|
||
const parsedFilePath = path.parse(filePath);
|
||
let extensionlessFilePath = path.join(parsedFilePath.dir, parsedFilePath.name);
|
||
const job = {
|
||
...(await DecodeAd1File(extensionlessFilePath)),
|
||
...(await DecodeVehFile(extensionlessFilePath)),
|
||
...(await DecodeTtlFile(extensionlessFilePath)),
|
||
...(await DecodeLinFile(extensionlessFilePath, close_date)),
|
||
...(await DecodePflFile(extensionlessFilePath)),
|
||
...(await DecodePfmFile(extensionlessFilePath)),
|
||
...(await DecodePfhFile(extensionlessFilePath)),
|
||
...(await DecodeStlFile(extensionlessFilePath)),
|
||
...(includeFilePathInReturnJob ? { filePath } : {})
|
||
};
|
||
|
||
const ad2 = await DecodeAd2File(extensionlessFilePath);
|
||
|
||
job.rates = [...(job.rates || []), ...(job.mat_rates || [])];
|
||
delete job.mat_rates;
|
||
job.insp_date = ad2.INSP_DATE;
|
||
|
||
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_CO_NM) job.OWNR_LN = `${job.OWNR_LN} ${job.OWNR_CO_NM}`;
|
||
delete job.OWNR_CO_NM;
|
||
const accepted_ins_co = store.get("accepted_ins_co");
|
||
|
||
let returnValue;
|
||
//Removed as a part of RPS-40.
|
||
// if (job.V_MILEAGE <= 20000) {
|
||
// returnValue = { ERROR: "Vehicle mileage is less than 20,000kms." };
|
||
// } else
|
||
|
||
const ins_rule_set = store.get("ins_rule_set");
|
||
|
||
if (!accepted_ins_co.includes(job.INS_CO_NM)) {
|
||
returnValue = {
|
||
ERROR: `Insurance Company Name is not valid for RPS. (${job.INS_CO_NM || "No name set"})`
|
||
};
|
||
} else if (!job.CLM_NO) {
|
||
log.info("Job ignored. No claim #. ");
|
||
returnValue = {
|
||
ERROR: `An unique claim number must be set for all jobs sent to RPS.`
|
||
};
|
||
} else if (ins_rule_set === "MPI" && !(job.CLM_NO.match("-01$") || job.CLM_NO.match("-99$"))) {
|
||
// 2024-05-10 Only -01 and -99 apply. Refactor logic.
|
||
log.info("Job ignored. This is not a -01 or -99 claim. Claim #. " + job.CLM_NO);
|
||
returnValue = {
|
||
ERROR: "Job ignored. This is not a -01 or -99 claim. Claim #. " + job.CLM_NO
|
||
};
|
||
}
|
||
// else if (job.LOSS_TYPE.toLowerCase() === "h") {
|
||
// log.info("Job ignored. This is a hail damage claim. " + job.CLM_NO);
|
||
// returnValue = {
|
||
// ERROR: "Job ignored. This is a hail damage claim. " + job.CLM_NO,
|
||
// };
|
||
// }
|
||
else {
|
||
delete job.LOSS_TYPE;
|
||
returnValue = _.transform(job, function (result, val, key) {
|
||
result[key.toLowerCase()] = val;
|
||
});
|
||
}
|
||
|
||
return returnValue;
|
||
}
|
||
|
||
async function DecodeAd1File(extensionlessFilePath) {
|
||
let dbf;
|
||
try {
|
||
dbf = await DBFFile.open(`${extensionlessFilePath}A.AD1`);
|
||
} catch (error) {
|
||
log.error("Error opening AD1 File.", error);
|
||
dbf = await DBFFile.open(`${extensionlessFilePath}.AD1`);
|
||
dbf && log.log("Found AD1 file using regular CIECA Id.");
|
||
} finally {
|
||
if (!dbf) return {};
|
||
let records = await dbf.readRecords(1);
|
||
return _.pick(records[0], [
|
||
// "INS_CO_ID",
|
||
"INS_CO_NM",
|
||
// "INS_ADDR1",
|
||
// "INS_ADDR2",
|
||
// "INS_CITY",
|
||
// "INS_ST",
|
||
// "INS_ZIP",
|
||
// "INS_CTRY",
|
||
|
||
// "INS_EA",
|
||
// "POLICY_NO",
|
||
"DED_AMT",
|
||
// "DED_STATUS",
|
||
// "ASGN_NO",
|
||
//"ASGN_DATE",
|
||
// "ASGN_TYPE",
|
||
"CLM_NO",
|
||
// "CLM_OFC_ID",
|
||
// "CLM_OFC_NM",
|
||
// "CLM_ADDR1",
|
||
// "CLM_ADDR2",
|
||
// "CLM_CITY",
|
||
// "CLM_ST",
|
||
// "CLM_ZIP",
|
||
// "CLM_CTRY",
|
||
// "CLM_PH1",
|
||
// "CLM_PH1X",
|
||
// "CLM_PH2",
|
||
// "CLM_PH2X",
|
||
// "CLM_FAX",
|
||
// "CLM_FAXX",
|
||
// "CLM_CT_LN",
|
||
// "CLM_CT_FN",
|
||
// "CLM_TITLE",
|
||
// "CLM_CT_PH",
|
||
// "CLM_CT_PHX",
|
||
// "CLM_EA",
|
||
// "PAYEE_NMS",
|
||
// "PAY_TYPE",
|
||
// "PAY_DATE",
|
||
// "PAY_CHKNM",
|
||
// "PAY_AMT",
|
||
// "AGT_CO_ID",
|
||
// "AGT_CO_NM",
|
||
// "AGT_ADDR1",
|
||
// "AGT_ADDR2",
|
||
// "AGT_CITY",
|
||
// "AGT_ST",
|
||
// "AGT_ZIP",
|
||
// "AGT_CTRY",
|
||
// "AGT_PH1",
|
||
// "AGT_PH1X",
|
||
// "AGT_PH2",
|
||
// "AGT_PH2X",
|
||
// "AGT_FAX",
|
||
// "AGT_FAXX",
|
||
// "AGT_CT_LN",
|
||
// "AGT_CT_FN",
|
||
// "AGT_CT_PH",
|
||
// "AGT_CT_PHX",
|
||
// "AGT_EA",
|
||
// "AGT_LIC_NO",
|
||
"LOSS_DATE",
|
||
"LOSS_TYPE",
|
||
"LOSS_DESC",
|
||
"THEFT_IND",
|
||
// "CAT_NO",
|
||
"TLOS_IND",
|
||
// "CUST_PR",
|
||
// "INSD_LN",
|
||
// "INSD_FN",
|
||
// "INSD_TITLE",
|
||
// "INSD_CO_NM",
|
||
// "INSD_ADDR1",
|
||
// "INSD_ADDR2",
|
||
// "INSD_CITY",
|
||
// "INSD_ST",
|
||
// "INSD_ZIP",
|
||
// "INSD_CTRY",
|
||
// "INSD_PH1",
|
||
// "INSD_PH1X",
|
||
// "INSD_PH2",
|
||
// "INSD_PH2X",
|
||
// "INSD_FAX",
|
||
// "INSD_FAXX",
|
||
// "INSD_EA",
|
||
"OWNR_LN",
|
||
"OWNR_FN",
|
||
// "OWNR_TITLE",
|
||
"OWNR_CO_NM",
|
||
"OWNR_ADDR1",
|
||
// "OWNR_ADDR2",
|
||
"OWNR_CITY",
|
||
// "OWNR_ST",
|
||
// "OWNR_ZIP",
|
||
// "OWNR_CTRY",
|
||
"OWNR_PH1"
|
||
// "OWNR_PH1X",
|
||
// "OWNR_PH2",
|
||
// "OWNR_PH2X",
|
||
// "OWNR_FAX",
|
||
// "OWNR_FAXX",
|
||
// "OWNR_EA",
|
||
// "INS_PH1",
|
||
// "INS_PH1X",
|
||
// "INS_PH2",
|
||
// "INS_PH2X",
|
||
// "INS_FAX",
|
||
// "INS_FAXX",
|
||
// "INS_CT_LN",
|
||
// "INS_CT_FN",
|
||
// "INS_TITLE",
|
||
// "INS_CT_PH",
|
||
// "INS_CT_PHX",
|
||
// "LOSS_CAT",
|
||
]);
|
||
}
|
||
}
|
||
|
||
async function DecodeAd2File(extensionlessFilePath) {
|
||
let dbf;
|
||
try {
|
||
dbf = await DBFFile.open(`${extensionlessFilePath}B.AD2`);
|
||
} catch (error) {
|
||
log.error("Error opening AD2 File.", error);
|
||
dbf = await DBFFile.open(`${extensionlessFilePath}.AD2`);
|
||
dbf && log.log("Found AD2 file using regular CIECA Id.");
|
||
} finally {
|
||
if (!dbf) return {};
|
||
let records = await dbf.readRecords(1);
|
||
return _.pick(records[0], ["CLMT_LN", "CLMT_FN", "INSP_DATE"]);
|
||
}
|
||
}
|
||
|
||
async function DecodePfhFile(extensionlessFilePath) {
|
||
let dbf;
|
||
try {
|
||
dbf = await DBFFile.open(`${extensionlessFilePath}.PFH`);
|
||
} catch (error) {
|
||
log.error("Error opening PFH File.", error);
|
||
} finally {
|
||
if (!dbf) return {};
|
||
let records = await dbf.readRecords(1);
|
||
return _.pick(records[0], ["ID_PRO_NAM"]);
|
||
}
|
||
}
|
||
|
||
async function DecodeVehFile(extensionlessFilePath) {
|
||
let dbf;
|
||
try {
|
||
dbf = await DBFFile.open(`${extensionlessFilePath}V.VEH`);
|
||
} catch (error) {
|
||
log.error("Error opening VEH File.", error);
|
||
dbf = await DBFFile.open(`${extensionlessFilePath}.VEH`);
|
||
dbf && log.log("Found VEH file using regular CIECA Id.");
|
||
} finally {
|
||
if (!dbf) return {};
|
||
let records = await dbf.readRecords(1);
|
||
return _.pick(records[0], [
|
||
"IMPACT_1",
|
||
"IMPACT_2",
|
||
// "DB_V_CODE",
|
||
// "PLATE_NO",
|
||
// "PLATE_ST",
|
||
"V_VIN",
|
||
// "V_COND",
|
||
// "V_PROD_DT",
|
||
"V_MODEL_YR",
|
||
// "V_MAKECODE",
|
||
"V_MAKEDESC",
|
||
"V_MODEL",
|
||
"V_TYPE",
|
||
"V_MILEAGE",
|
||
// "V_BSTYLE",
|
||
// "V_TRIMCODE",
|
||
// "TRIM_COLOR",
|
||
// "V_MLDGCODE",
|
||
// "V_ENGINE",
|
||
// "V_COLOR",
|
||
// "V_TONE",
|
||
"V_STAGE"
|
||
// "PAINT_CD1",
|
||
// "PAINT_CD2",
|
||
// "PAINT_CD3",
|
||
]);
|
||
}
|
||
}
|
||
async function DecodeTtlFile(extensionlessFilePath) {
|
||
let dbf = await DBFFile.open(`${extensionlessFilePath}.TTL`);
|
||
let records = await dbf.readRecords(1);
|
||
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) {
|
||
let dbf = await DBFFile.open(`${extensionlessFilePath}.LIN`);
|
||
let records = await dbf.readRecords();
|
||
let joblines = records.map((record) => {
|
||
return _.transform(
|
||
_.pick(record, [
|
||
"LINE_NO",
|
||
"LINE_IND",
|
||
"LINE_REF",
|
||
// "TRAN_CODE",
|
||
"DB_REF",
|
||
"UNQ_SEQ",
|
||
// "WHO_PAYS",
|
||
"LINE_DESC",
|
||
"PART_TYPE",
|
||
// "PART_DESCJ",
|
||
"PRT_DSMK_M",
|
||
"OEM_PARTNO",
|
||
"PRICE_INC",
|
||
// "ALT_PART_I",
|
||
"TAX_PART",
|
||
"DB_PRICE",
|
||
"ACT_PRICE",
|
||
"PART_QTY",
|
||
"PRICE_J",
|
||
"GLASS_FLAG",
|
||
"CERT_PART",
|
||
// "ALT_CO_ID",
|
||
"ALT_PARTNO",
|
||
// "ALT_OVERRD",
|
||
// "ALT_PARTM",
|
||
"PRT_DSMK_P",
|
||
|
||
"MOD_LBR_TY",
|
||
"DB_HRS",
|
||
"MOD_LB_HRS",
|
||
"LBR_INC",
|
||
"LBR_OP",
|
||
"LBR_HRS_J",
|
||
// "LBR_TYP_J",
|
||
"LBR_OP_J",
|
||
// "PAINT_STG",
|
||
// "PAINT_TONE",
|
||
// "LBR_TAX",
|
||
"LBR_AMT",
|
||
"MISC_AMT"
|
||
// "MISC_SUBLT",
|
||
// "MISC_TAX",
|
||
// "BETT_TYPE",
|
||
// "BETT_PCTG",
|
||
// "BETT_AMT",
|
||
// "BETT_TAX",
|
||
]),
|
||
function (result, val, key) {
|
||
//Required because unq_seq gets pulled as a numeric instaed of a string.
|
||
|
||
if (key === "UNQ_SEQ") {
|
||
result[key.toLowerCase()] = val.toString();
|
||
return;
|
||
}
|
||
result[key.toLowerCase()] = val;
|
||
return;
|
||
}
|
||
);
|
||
});
|
||
|
||
//Apply ruleset.
|
||
const ins_rule_set = store.get("ins_rule_set");
|
||
|
||
joblines.map((jobline) => {
|
||
jobline.ignore = false;
|
||
switch (ins_rule_set) {
|
||
case "MPI":
|
||
case "SGI":
|
||
const rulesetToApply = WhichRulesetToApply(close_date);
|
||
|
||
switch (rulesetToApply) {
|
||
case "V1":
|
||
jobline = V1Ruleset(jobline, joblines);
|
||
break;
|
||
case "V2":
|
||
jobline = V2Ruleset(jobline, joblines);
|
||
break;
|
||
case "V3":
|
||
jobline = V3Ruleset(jobline, joblines);
|
||
break;
|
||
default:
|
||
jobline = V3Ruleset(jobline, joblines);
|
||
break;
|
||
}
|
||
break;
|
||
// case "SGI":
|
||
// log.info("Using SGI ruleset. Line will be automatically counted until rules are added.");
|
||
|
||
// break;
|
||
default:
|
||
log.info("Using default ruleset (MPI).");
|
||
break;
|
||
}
|
||
|
||
//2025-05-27 Commenting out to prepare release without claims clerk.
|
||
// jobline.alerts = claimsClerk({ jobline, joblines });
|
||
|
||
return jobline;
|
||
});
|
||
|
||
//Check for discounts that need to be ignored after the fact.
|
||
|
||
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 _.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 _.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 _.pick(record, ["MATL_TYPE", "CAL_PRETHR"]);
|
||
});
|
||
|
||
//Check for discounts that need to be ignored after the fact.
|
||
|
||
return { mat_rates: pflLines };
|
||
}
|
||
|
||
exports.DecodeEstimate = DecodeEstimate;
|
||
exports.ImportJob = ImportJob;
|
||
|
||
function V1Ruleset(jobline, joblines) {
|
||
//These set of MPI rules are valid until April 1, 2023.
|
||
|
||
//Wheel Repair Pricing PRS-82
|
||
//Verified on 08/24/21
|
||
if (
|
||
jobline.part_type === "PAN" &&
|
||
jobline.line_desc.toLowerCase().includes("wheel") &&
|
||
Math.abs(jobline.prt_dsmk_m) === Math.round((jobline.act_price / 2) * 100) / 100
|
||
) {
|
||
log.info(`Jobline '${jobline.line_desc}' ignored due to wheel repair.`);
|
||
jobline.ignore = true;
|
||
}
|
||
|
||
//RPS-39 - OEM ON OEM SAVINGS
|
||
//Verified on 08/24/21
|
||
if (jobline.part_type === "PAN" && jobline.db_price !== jobline.act_price && jobline.db_price !== 0) {
|
||
jobline.db_price = jobline.act_price;
|
||
}
|
||
|
||
//Remove all $0DB line items 02/17/2022.
|
||
if (
|
||
(jobline.part_type === "PAA" || jobline.part_type === "PAL" || jobline.part_type === "PAN") &&
|
||
jobline.db_price === 0
|
||
) {
|
||
jobline.ignore = true;
|
||
}
|
||
|
||
//05/20
|
||
//We’ll have to apply a rule that will not count any A/M, Reman or new part price that is manually changed to $0.00.
|
||
//Only recycled parts that are changed to $0.00 can be counted towards RPS.
|
||
// This is separate from $0.00 DB prices that need to be updated to the manually entered price.
|
||
//Verified on 08/24/21
|
||
if (jobline.part_type !== "PAL" && jobline.act_price === 0 && jobline.price_j) {
|
||
log.info(`Jobline '${jobline.line_desc}' ignored because it was manually changed to 0..`);
|
||
jobline.ignore = true;
|
||
}
|
||
|
||
//09/2021 Detect NAGS lines using RegEx for the Part Number
|
||
if (jobline.line_desc.toLowerCase().includes("glass") && jobline.oem_partno.match(`[A-Z]{2}[0-9]{5,6}[A-Z]{3}`)) {
|
||
console.log(jobline.line_desc, "NAGS Line ignored");
|
||
jobline.ignore = true;
|
||
}
|
||
|
||
//Logic Based Exclusions.
|
||
//Verified on 08/24/21
|
||
if (
|
||
!jobline.part_type ||
|
||
jobline.db_ref.startsWith("900") ||
|
||
jobline.line_desc.toLowerCase().startsWith("urethane") ||
|
||
jobline.line_desc.toLowerCase().startsWith("w/shield adhesive") ||
|
||
//jobline.line_desc.toLowerCase().includes("wheel") || Removed as a part of RPS-41
|
||
(jobline.line_desc.toLowerCase().includes("tire") &&
|
||
!jobline.line_desc.toLowerCase().includes("sensor") &&
|
||
!jobline.line_desc.toLowerCase().includes("label")) ||
|
||
jobline.line_desc.toLowerCase().startsWith("hazardous") ||
|
||
jobline.line_desc.toLowerCase().startsWith("detail") ||
|
||
jobline.line_desc.toLowerCase().startsWith("clean") ||
|
||
// jobline.part_type.toUpperCase() === "PAG" ||Removed for RPS-43.
|
||
jobline.part_type.toUpperCase() === "PAS" ||
|
||
jobline.part_type.toUpperCase() === "PASL" ||
|
||
jobline.part_type.toUpperCase() === "PAE"
|
||
//jobline.glass_flag === true //Removed for RPS-43.
|
||
) {
|
||
jobline.ignore = true;
|
||
}
|
||
|
||
//Check to see if this is a discount line i.e. a 900511
|
||
if (jobline.db_ref === "900511" && jobline.prt_dsmk_p !== 50) {
|
||
jobline.ignore = false;
|
||
//Calculate the discount to be added as a negative.
|
||
jobline.act_price = jobline.prt_dsmk_m;
|
||
//Check to see if the parent line has a discount.
|
||
const parentLine = joblines.find((r) => parseInt(r.unq_seq) === jobline.line_ref);
|
||
if (parentLine && parentLine.ignore) {
|
||
jobline.ignore = true;
|
||
}
|
||
}
|
||
|
||
//RPS-42 Dynamic Inclusion or Exclusion of Lines based on RPS-EXCLUDE or RPS.
|
||
if (jobline.oem_partno.toLowerCase().includes("/rps-exclude")) {
|
||
jobline.ignore = true;
|
||
} else if (jobline.oem_partno.toLowerCase().includes("/rps")) {
|
||
jobline.ignore = false;
|
||
}
|
||
|
||
return jobline;
|
||
}
|
||
|
||
function V2Ruleset(jobline, joblines) {
|
||
//This is the rules psot 04/01/2023. They are a further restrictive set, and therefore
|
||
//V1 rules are called first, and then run through this filter as well.
|
||
|
||
V1Ruleset(jobline, joblines);
|
||
|
||
//Remove any glass related items.
|
||
if (jobline.mod_lbr_ty?.toUpperCase() === "LAG") {
|
||
jobline.ignore = true;
|
||
}
|
||
|
||
//ADAS Part Line
|
||
if (
|
||
AdasDescriptions.some((d) => {
|
||
const ret = jobline.line_desc.toLowerCase().includes(d);
|
||
return ret;
|
||
})
|
||
) {
|
||
jobline.ignore = true;
|
||
}
|
||
//Additional glass line exclusions
|
||
if (v2GlassLines.some((d) => jobline.line_desc.toLowerCase().includes(d))) {
|
||
jobline.ignore = true;
|
||
}
|
||
|
||
return jobline;
|
||
}
|
||
function V3Ruleset(jobline, joblines) {
|
||
//This is the rules psot 09/01/2023. They appear to be a copy of V2 rules. They have been duplicated for structural sake.
|
||
V2Ruleset(jobline, joblines);
|
||
return jobline;
|
||
}
|
||
|
||
const AdasDescriptions = [
|
||
"seat belt",
|
||
"air bag bolt",
|
||
"air bag cable reel",
|
||
"air bag center sensor",
|
||
"air bag clock",
|
||
"air bag coil",
|
||
"air bag control",
|
||
"air bag diagnostic",
|
||
"air bag driver",
|
||
"air bag ecs",
|
||
"air bag harness",
|
||
"air bag impact",
|
||
"air bag label",
|
||
"air bag module",
|
||
"air bag nut",
|
||
"air bag rollover",
|
||
"air bag rotary coupler",
|
||
"air bag safing sensor",
|
||
"air bag satellite sensor",
|
||
"air bag screw",
|
||
"air bag seat",
|
||
"air bag warning",
|
||
"air bag ocs",
|
||
"air bag opds",
|
||
"air bag sensor",
|
||
"air bag occupant",
|
||
"air bag pass",
|
||
"air bag system air bag terminal",
|
||
"air bag side",
|
||
"side air bag",
|
||
"air bag weight",
|
||
"air bag steering",
|
||
"air bag decal",
|
||
"air bag switch",
|
||
"air bag pressure",
|
||
"air bag pig",
|
||
"air bag whiplash",
|
||
"air bag spiral",
|
||
"air bag restraint",
|
||
"air bag wire harness",
|
||
"drivers knee air bag",
|
||
"drivers seat air bag",
|
||
"inform label air bag",
|
||
"pass air bag wire",
|
||
"air bag extension",
|
||
"air bag caution",
|
||
"connector air bag",
|
||
"curtain air bag",
|
||
"air bag sdm",
|
||
"air bag cover",
|
||
"air bag srs",
|
||
"air bag light sensor",
|
||
"knee air bag",
|
||
"air bag contact",
|
||
"air bag crash",
|
||
"air bag lwr",
|
||
"air bag pad",
|
||
"air bag suspension",
|
||
"air bag spacer",
|
||
"back air bag",
|
||
"air bag reel",
|
||
"air bag discriminating",
|
||
"air bag curtain",
|
||
"air bag initiator",
|
||
"air bag positive",
|
||
"engine wiring harness for air bag",
|
||
"air bag wiring",
|
||
"air bag combination",
|
||
"air bag connector",
|
||
"air bag plug",
|
||
"rear air bag",
|
||
"air bag clip",
|
||
"air bag gas",
|
||
"air bag bracket",
|
||
"suspension air bag",
|
||
"passenger air bag"
|
||
];
|
||
|
||
const v2GlassLines = [
|
||
"frt sunroof assembly",
|
||
"frt sunroof glass assembly",
|
||
"frt sunroof glass panel",
|
||
"frt sunroof panel",
|
||
"frt sunroof sliding panel",
|
||
"rear sunroof glass assembly",
|
||
"rear sunroof glass panel",
|
||
"sunroof assembly",
|
||
"sunroof glass assembly",
|
||
"sunroof glass panel",
|
||
"sunroof sliding panel"
|
||
];
|