Improve EMS interfaces and add LIN decoding.
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
export interface ParsedAD1 {
|
import { UUID } from "crypto";
|
||||||
|
|
||||||
|
export interface DecodedAd1 {
|
||||||
// Insurance company information
|
// Insurance company information
|
||||||
ins_co_id?: string;
|
ins_co_id?: string;
|
||||||
ins_co_nm?: string;
|
ins_co_nm?: string;
|
||||||
@@ -130,18 +132,18 @@ export interface ParsedAD1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface OwnerRecordInterface {
|
export interface OwnerRecordInterface {
|
||||||
ownr_ln: string;
|
ownr_ln?: string;
|
||||||
ownr_fn: string;
|
ownr_fn?: string;
|
||||||
ownr_title: string;
|
ownr_title?: string;
|
||||||
ownr_co_nm: string;
|
ownr_co_nm?: string;
|
||||||
ownr_addr1: string;
|
ownr_addr1?: string;
|
||||||
ownr_addr2: string;
|
ownr_addr2?: string;
|
||||||
ownr_city: string;
|
ownr_city?: string;
|
||||||
ownr_st: string;
|
ownr_st?: string;
|
||||||
ownr_zip: string;
|
ownr_zip?: string;
|
||||||
ownr_ctry: string;
|
ownr_ctry?: string;
|
||||||
ownr_ph1: string;
|
ownr_ph1?: string;
|
||||||
ownr_ph2: string;
|
ownr_ph2?: string;
|
||||||
ownr_ea: string;
|
ownr_ea?: string;
|
||||||
shopid: string;
|
shopid: UUID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,24 @@ import { DBFFile } from "dbffile";
|
|||||||
import log from "electron-log/main";
|
import log from "electron-log/main";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import { OwnerRecordInterface, ParsedAD1 } from "./decode-ad1.interface";
|
import { OwnerRecordInterface, DecodedAd1 } from "./decode-ad1.interface";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
|
||||||
const DecodeAD1 = async (extensionlessFilePath: string): Promise<ParsedAD1> => {
|
const DecodeAD1 = async (
|
||||||
let dbf;
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedAd1> => {
|
||||||
|
let dbf: DBFFile;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}A.AD1`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}A.AD1`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Error opening AD1 File.", error);
|
log.error("Error opening AD1 File.", errorTypeCheck(error));
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}.AD1`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}.AD1`);
|
||||||
log.log("Found AD1 file using regular CIECA Id.");
|
log.log("Found AD1 file using regular CIECA Id.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbf) {
|
if (!dbf) {
|
||||||
log.error(`Could not find any AD1 files at ${extensionlessFilePath}`);
|
log.error(`Could not find any AD1 files at ${extensionlessFilePath}`);
|
||||||
return null;
|
throw new Error(`Could not find any AD1 files at ${extensionlessFilePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawDBFRecord = await dbf.readRecords(1);
|
const rawDBFRecord = await dbf.readRecords(1);
|
||||||
@@ -24,7 +27,7 @@ const DecodeAD1 = async (extensionlessFilePath: string): Promise<ParsedAD1> => {
|
|||||||
//AD1 will always have only 1 row.
|
//AD1 will always have only 1 row.
|
||||||
//Commented lines have been cross referenced with existing partner fields.
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
const rawAd1Data = deepLowerCaseKeys(
|
const rawAd1Data: DecodedAd1 = deepLowerCaseKeys(
|
||||||
_.pick(rawDBFRecord[0], [
|
_.pick(rawDBFRecord[0], [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
"INS_CO_ID",
|
"INS_CO_ID",
|
||||||
@@ -192,7 +195,7 @@ const DecodeAD1 = async (extensionlessFilePath: string): Promise<ParsedAD1> => {
|
|||||||
ownr_ph1: rawAd1Data.ownr_ph1,
|
ownr_ph1: rawAd1Data.ownr_ph1,
|
||||||
ownr_ph2: rawAd1Data.ownr_ph2,
|
ownr_ph2: rawAd1Data.ownr_ph2,
|
||||||
ownr_ea: rawAd1Data.ownr_ea,
|
ownr_ea: rawAd1Data.ownr_ea,
|
||||||
shopid: "UUID",
|
shopid: "UUID", //TODO: Need to add the shop uuid to this set of functions.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export interface ParsedAD2 {
|
export interface DecodedAD2 {
|
||||||
clmt_ln?: string;
|
clmt_ln?: string;
|
||||||
clmt_fn?: string;
|
clmt_fn?: string;
|
||||||
clmt_title?: string;
|
clmt_title?: string;
|
||||||
|
|||||||
@@ -2,23 +2,24 @@ import { DBFFile } from "dbffile";
|
|||||||
import log from "electron-log/main";
|
import log from "electron-log/main";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import { ParsedAD2 } from "./decode-ad2.interface";
|
import { DecodedAD2 } from "./decode-ad2.interface";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
|
||||||
const DecodeAD2 = async (extensionlessFilePath: string): Promise<ParsedAD2> => {
|
const DecodeAD2 = async (
|
||||||
let dbf;
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedAD2> => {
|
||||||
|
let dbf: DBFFile;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}B.AD2`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}B.AD2`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Error opening AD2 File.", error);
|
log.error("Error opening AD2 File.", errorTypeCheck(error));
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}.AD2`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}.AD2`);
|
||||||
log.log("Found AD2 file using regular CIECA Id.");
|
log.log("Found AD2 file using regular CIECA Id.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbf) {
|
if (!dbf) {
|
||||||
log.error(`Could not find any AD2 files at ${extensionlessFilePath}`);
|
log.error(`Could not find any AD2 files at ${extensionlessFilePath}`);
|
||||||
return {
|
throw new Error(`Could not find any AD2 files at ${extensionlessFilePath}`);
|
||||||
id: 0,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawDBFRecord = await dbf.readRecords(1);
|
const rawDBFRecord = await dbf.readRecords(1);
|
||||||
@@ -65,75 +66,75 @@ const DecodeAD2 = async (extensionlessFilePath: string): Promise<ParsedAD2> => {
|
|||||||
"EST_EA",
|
"EST_EA",
|
||||||
//"EST_LIC_NO",
|
//"EST_LIC_NO",
|
||||||
//"EST_FILENO",
|
//"EST_FILENO",
|
||||||
// "INSP_CT_LN",
|
//"INSP_CT_LN",
|
||||||
// "INSP_CT_FN",
|
//"INSP_CT_FN",
|
||||||
// "INSP_ADDR1",
|
//"INSP_ADDR1",
|
||||||
// "INSP_ADDR2",
|
//"INSP_ADDR2",
|
||||||
// "INSP_CITY",
|
//"INSP_CITY",
|
||||||
// "INSP_ST",
|
//"INSP_ST",
|
||||||
// "INSP_ZIP",
|
//"INSP_ZIP",
|
||||||
// "INSP_CTRY",
|
//"INSP_CTRY",
|
||||||
// "INSP_PH1",
|
//"INSP_PH1",
|
||||||
// "INSP_PH1X",
|
//"INSP_PH1X",
|
||||||
// "INSP_PH2",
|
//"INSP_PH2",
|
||||||
// "INSP_PH2X",
|
//"INSP_PH2X",
|
||||||
// "INSP_FAX",
|
//"INSP_FAX",
|
||||||
// "INSP_FAXX",
|
//"INSP_FAXX",
|
||||||
// "INSP_EA",
|
//"INSP_EA",
|
||||||
// "INSP_CODE",
|
//"INSP_CODE",
|
||||||
// "INSP_DESC",
|
//"INSP_DESC",
|
||||||
"INSP_DATE", //RENAME TO date_estimated
|
"INSP_DATE", //RENAME TO date_estimated
|
||||||
// "INSP_TIME",
|
//"INSP_TIME",
|
||||||
// "RF_CO_ID",
|
//"RF_CO_ID",
|
||||||
// "RF_CO_NM",
|
//"RF_CO_NM",
|
||||||
// "RF_ADDR1",
|
//"RF_ADDR1",
|
||||||
// "RF_ADDR2",
|
//"RF_ADDR2",
|
||||||
// "RF_CITY",
|
//"RF_CITY",
|
||||||
// "RF_ST",
|
//"RF_ST",
|
||||||
// "RF_ZIP",
|
//"RF_ZIP",
|
||||||
// "RF_CTRY",
|
//"RF_CTRY",
|
||||||
// "RF_PH1",
|
//"RF_PH1",
|
||||||
// "RF_PH1X",
|
//"RF_PH1X",
|
||||||
// "RF_PH2",
|
//"RF_PH2",
|
||||||
// "RF_PH2X",
|
//"RF_PH2X",
|
||||||
// "RF_FAX",
|
//"RF_FAX",
|
||||||
// "RF_FAXX",
|
//"RF_FAXX",
|
||||||
// "RF_CT_LN",
|
//"RF_CT_LN",
|
||||||
// "RF_CT_FN",
|
//"RF_CT_FN",
|
||||||
// "RF_EA",
|
//"RF_EA",
|
||||||
// "RF_TAX_ID",
|
//"RF_TAX_ID",
|
||||||
// "RF_LIC_NO",
|
//"RF_LIC_NO",
|
||||||
// "RF_BAR_NO",
|
//"RF_BAR_NO",
|
||||||
// "RO_IN_DATE",
|
//"RO_IN_DATE",
|
||||||
// "RO_IN_TIME",
|
//"RO_IN_TIME",
|
||||||
// "TAR_DATE",
|
//"TAR_DATE",
|
||||||
// "TAR_TIME",
|
//"TAR_TIME",
|
||||||
// "RO_CMPDATE",
|
//"RO_CMPDATE",
|
||||||
// "RO_CMPTIME",
|
//"RO_CMPTIME",
|
||||||
// "DATE_OUT",
|
//"DATE_OUT",
|
||||||
// "TIME_OUT",
|
//"TIME_OUT",
|
||||||
// "RF_ESTIMTR",
|
//"RF_ESTIMTR",
|
||||||
// "MKTG_TYPE",
|
//"MKTG_TYPE",
|
||||||
// "MKTG_SRC",
|
//"MKTG_SRC",
|
||||||
// "LOC_NM",
|
//"LOC_NM",
|
||||||
// "LOC_ADDR1",
|
//"LOC_ADDR1",
|
||||||
// "LOC_ADDR2",
|
//"LOC_ADDR2",
|
||||||
// "LOC_CITY",
|
//"LOC_CITY",
|
||||||
// "LOC_ST",
|
//"LOC_ST",
|
||||||
// "LOC_ZIP",
|
//"LOC_ZIP",
|
||||||
// "LOC_CTRY",
|
//"LOC_CTRY",
|
||||||
// "LOC_PH1",
|
//"LOC_PH1",
|
||||||
// "LOC_PH1X",
|
//"LOC_PH1X",
|
||||||
// "LOC_PH2",
|
//"LOC_PH2",
|
||||||
// "LOC_PH2X",
|
//"LOC_PH2X",
|
||||||
// "LOC_FAX",
|
//"LOC_FAX",
|
||||||
// "LOC_FAXX",
|
//"LOC_FAXX",
|
||||||
// "LOC_CT_LN",
|
//"LOC_CT_LN",
|
||||||
// "LOC_CT_FN",
|
//"LOC_CT_FN",
|
||||||
// "LOC_TITLE",
|
//"LOC_TITLE",
|
||||||
// "LOC_PH",
|
//"LOC_PH",
|
||||||
// "LOC_PHX",
|
//"LOC_PHX",
|
||||||
// "LOC_EA",
|
//"LOC_EA",
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -142,6 +143,6 @@ const DecodeAD2 = async (extensionlessFilePath: string): Promise<ParsedAD2> => {
|
|||||||
rawAd2Data.date_estimated = rawAd2Data.insp_date;
|
rawAd2Data.date_estimated = rawAd2Data.insp_date;
|
||||||
delete rawAd2Data.insp_date;
|
delete rawAd2Data.insp_date;
|
||||||
|
|
||||||
return null;
|
return rawAd2Data;
|
||||||
};
|
};
|
||||||
export default DecodeAD2;
|
export default DecodeAD2;
|
||||||
|
|||||||
48
src/main/decoder/decode-lin.interface.ts
Normal file
48
src/main/decoder/decode-lin.interface.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
export interface DecodedLin {
|
||||||
|
line_no?: string;
|
||||||
|
line_ind?: string;
|
||||||
|
line_ref?: string;
|
||||||
|
tran_code?: string;
|
||||||
|
db_ref?: string;
|
||||||
|
unq_seq?: string;
|
||||||
|
//who_pays?: string;
|
||||||
|
line_desc?: string;
|
||||||
|
part_type?: string;
|
||||||
|
//part_desc_j?: boolean;
|
||||||
|
glass_flag?: boolean;
|
||||||
|
oem_partno?: string;
|
||||||
|
price_inc?: boolean;
|
||||||
|
alt_part_i?: boolean;
|
||||||
|
tax_part?: boolean;
|
||||||
|
db_price?: number;
|
||||||
|
act_price?: number;
|
||||||
|
price_j?: boolean;
|
||||||
|
cert_part?: boolean;
|
||||||
|
part_qty?: number;
|
||||||
|
alt_co_id?: string;
|
||||||
|
alt_partno?: string;
|
||||||
|
alt_overrd?: boolean;
|
||||||
|
alt_partm?: string;
|
||||||
|
prt_dsmk_p?: string;
|
||||||
|
prt_dsmk_m?: string;
|
||||||
|
mod_lbr_ty?: string;
|
||||||
|
db_hrs?: number;
|
||||||
|
mod_lb_hrs?: number;
|
||||||
|
lbr_inc?: boolean;
|
||||||
|
lbr_op?: string;
|
||||||
|
lbr_hrs_j?: boolean;
|
||||||
|
lbr_typ_j?: boolean;
|
||||||
|
lbr_op_j?: boolean;
|
||||||
|
paint_stg?: string;
|
||||||
|
paint_tone?: string;
|
||||||
|
lbr_tax?: boolean;
|
||||||
|
lbr_amt?: number;
|
||||||
|
misc_amt?: number;
|
||||||
|
misc_sublt?: string;
|
||||||
|
misc_tax?: boolean;
|
||||||
|
bett_type?: string;
|
||||||
|
bett_pctg?: string | number;
|
||||||
|
bett_amt?: number;
|
||||||
|
bett_tax?: boolean;
|
||||||
|
op_code_desc?: string;
|
||||||
|
}
|
||||||
104
src/main/decoder/decode-lin.ts
Normal file
104
src/main/decoder/decode-lin.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import { DBFFile } from "dbffile";
|
||||||
|
import log from "electron-log/main";
|
||||||
|
import _ from "lodash";
|
||||||
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
|
import { DecodedLin } from "./decode-lin.interface";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
|
||||||
|
const DecodeLin = async (
|
||||||
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedLin[]> => {
|
||||||
|
let dbf: DBFFile;
|
||||||
|
try {
|
||||||
|
dbf = await DBFFile.open(`${extensionlessFilePath}.LIN`);
|
||||||
|
} catch (error) {
|
||||||
|
//LIN File only has 1 location.
|
||||||
|
log.error("Error opening LIN File.", errorTypeCheck(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbf) {
|
||||||
|
log.error(`Could not find any LIN files at ${extensionlessFilePath}`);
|
||||||
|
throw new Error(`Could not find any LIN files at ${extensionlessFilePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawDBFRecord = await dbf.readRecords();
|
||||||
|
|
||||||
|
//AD2 will always have only 1 row.
|
||||||
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
|
const rawLinData: DecodedLin[] = rawDBFRecord.map((record) => {
|
||||||
|
const singleLineData: DecodedLin = deepLowerCaseKeys(
|
||||||
|
_.pick(record, [
|
||||||
|
//TODO: Add typings for EMS File Formats.
|
||||||
|
"LINE_NO",
|
||||||
|
"LINE_IND",
|
||||||
|
"LINE_REF",
|
||||||
|
"TRAN_CODE",
|
||||||
|
"DB_REF",
|
||||||
|
"UNQ_SEQ",
|
||||||
|
// "WHO_PAYS",
|
||||||
|
"LINE_DESC",
|
||||||
|
"PART_TYPE",
|
||||||
|
//TODO: Believe this was previously broken in partner. Need to confirm.
|
||||||
|
// system == "M" ? "PART_DESCJ" : "PART_DES_J",
|
||||||
|
//"PART_DESC_J",
|
||||||
|
//End Check
|
||||||
|
"GLASS_FLAG",
|
||||||
|
"OEM_PARTNO",
|
||||||
|
"PRICE_INC",
|
||||||
|
"ALT_PART_I",
|
||||||
|
"TAX_PART",
|
||||||
|
"DB_PRICE",
|
||||||
|
"ACT_PRICE",
|
||||||
|
"PRICE_J",
|
||||||
|
"CERT_PART",
|
||||||
|
"PART_QTY",
|
||||||
|
"ALT_CO_ID",
|
||||||
|
"ALT_PARTNO",
|
||||||
|
"ALT_OVERRD",
|
||||||
|
"ALT_PARTM",
|
||||||
|
"PRT_DSMK_P",
|
||||||
|
"PRT_DSMK_M",
|
||||||
|
"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",
|
||||||
|
])
|
||||||
|
);
|
||||||
|
//Apply line by line adjustments.
|
||||||
|
singleLineData.op_code_desc = ""; //TODO: Implement the OP Code Lookup.
|
||||||
|
//Partner previously queried this on login and stored it. Then referenced it and added here.
|
||||||
|
// Sample Code:
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// lin.op_code_desc = Utils.AppMetaData.CiecaOpCodes[lin.lbr_op.Value]["desc"].Value;
|
||||||
|
// }
|
||||||
|
// catch (Exception Ex)
|
||||||
|
// {
|
||||||
|
// logger.Warn(Ex, "Couldnt find OpCodeDesc from {0} ", lin.lbr_op.Value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return singleLineData;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Apply business logic transfomrations.
|
||||||
|
//We don't have an inspection date, we instead have `date_estimated`
|
||||||
|
|
||||||
|
return rawLinData;
|
||||||
|
};
|
||||||
|
export default DecodeLin;
|
||||||
@@ -1 +1,61 @@
|
|||||||
export interface ParsedVeh {}
|
import { UUID } from "crypto";
|
||||||
|
|
||||||
|
export interface DecodedVeh {
|
||||||
|
// Basic vehicle information
|
||||||
|
plate_no?: string;
|
||||||
|
plate_st?: string;
|
||||||
|
v_vin?: string;
|
||||||
|
v_model_yr?: string;
|
||||||
|
v_make_desc?: string;
|
||||||
|
v_model_desc?: string;
|
||||||
|
v_color?: string;
|
||||||
|
kmin?: number;
|
||||||
|
|
||||||
|
// Complete vehicle data object
|
||||||
|
vehicle: { data: VehicleRecordInterface };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VehicleRecordInterface {
|
||||||
|
// Area of damage information
|
||||||
|
area_of_damage: {
|
||||||
|
impact1?: string;
|
||||||
|
impact2?: string;
|
||||||
|
};
|
||||||
|
// Paint code information
|
||||||
|
paint_codes: {
|
||||||
|
paint_cd1: string;
|
||||||
|
paint_cd2: string;
|
||||||
|
paint_cd3: string;
|
||||||
|
};
|
||||||
|
// Vehicle information from DBF file
|
||||||
|
db_v_code?: string;
|
||||||
|
plate_no?: string;
|
||||||
|
plate_st?: string;
|
||||||
|
v_vin?: string;
|
||||||
|
v_cond: string;
|
||||||
|
v_prod_dt?: Date;
|
||||||
|
v_model_yr: string;
|
||||||
|
v_makecode: string;
|
||||||
|
v_make_desc?: string;
|
||||||
|
v_model?: string;
|
||||||
|
v_model_desc?: string;
|
||||||
|
v_type: string;
|
||||||
|
v_bstyle?: string;
|
||||||
|
v_trimcode?: string;
|
||||||
|
trim_color?: string;
|
||||||
|
v_mldgcode?: string;
|
||||||
|
v_engine?: string;
|
||||||
|
v_mileage?: string;
|
||||||
|
v_color?: string;
|
||||||
|
v_tone?: string;
|
||||||
|
v_stage?: string;
|
||||||
|
shopid: UUID;
|
||||||
|
|
||||||
|
//These are removed during business logic processing.
|
||||||
|
v_makedesc?: string;
|
||||||
|
impact_1?: string;
|
||||||
|
impact_2?: string;
|
||||||
|
paint_cd1?: string;
|
||||||
|
paint_cd2?: string;
|
||||||
|
paint_cd3?: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,24 +2,24 @@ import { DBFFile } from "dbffile";
|
|||||||
import log from "electron-log/main";
|
import log from "electron-log/main";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import { ParsedAD2 } from "./decode-ad2.interface";
|
import { DecodedVeh, VehicleRecordInterface } from "./decode-veh.interface";
|
||||||
import { ParsedVeh } from "./decode-veh.interface";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
|
||||||
const DecodeVeh = async (extensionlessFilePath: string): Promise<ParsedVeh> => {
|
const DecodeVeh = async (
|
||||||
let dbf;
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedVeh> => {
|
||||||
|
let dbf: DBFFile;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}B.AD2`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}V.VEH`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Error opening AD2 File.", error);
|
log.error("Error opening VEH File.", errorTypeCheck(error));
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}.AD2`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}.VEH`);
|
||||||
log.log("Found AD2 file using regular CIECA Id.");
|
log.log("Found VEH file using regular CIECA Id.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbf) {
|
if (!dbf) {
|
||||||
log.error(`Could not find any AD2 files at ${extensionlessFilePath}`);
|
log.error(`Could not find any VEH files at ${extensionlessFilePath}`);
|
||||||
return {
|
throw new Error(`Could not find any VEH files at ${extensionlessFilePath}`);
|
||||||
id: 0,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawDBFRecord = await dbf.readRecords(1);
|
const rawDBFRecord = await dbf.readRecords(1);
|
||||||
@@ -27,122 +27,84 @@ const DecodeVeh = async (extensionlessFilePath: string): Promise<ParsedVeh> => {
|
|||||||
//AD2 will always have only 1 row.
|
//AD2 will always have only 1 row.
|
||||||
//Commented lines have been cross referenced with existing partner fields.
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
const rawAd2Data = deepLowerCaseKeys(
|
const rawVehData: VehicleRecordInterface = deepLowerCaseKeys(
|
||||||
_.pick(rawDBFRecord[0], [
|
_.pick(rawDBFRecord[0], [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
"CLMT_LN",
|
"IMPACT_1",
|
||||||
"CLMT_FN",
|
"IMPACT_2",
|
||||||
"CLMT_TITLE",
|
"DB_V_CODE",
|
||||||
"CLMT_CO_NM",
|
"PLATE_NO",
|
||||||
"CLMT_ADDR1",
|
"PLATE_ST",
|
||||||
"CLMT_ADDR2",
|
"V_VIN",
|
||||||
"CLMT_CITY",
|
"V_COND",
|
||||||
"CLMT_ST",
|
"V_PROD_DT",
|
||||||
"CLMT_ZIP",
|
"V_MODEL_YR",
|
||||||
"CLMT_CTRY",
|
"V_MAKECODE",
|
||||||
"CLMT_PH1",
|
"V_MAKEDESC",
|
||||||
//"CLMT_PH1X",
|
"V_MODEL",
|
||||||
"CLMT_PH2",
|
"V_TYPE",
|
||||||
//"CLMT_PH2X",
|
"V_BSTYLE",
|
||||||
//"CLMT_FAX",
|
"V_TRIMCODE",
|
||||||
//"CLMT_FAXX",
|
"TRIM_COLOR",
|
||||||
"CLMT_EA",
|
"V_MLDGCODE",
|
||||||
"EST_CO_ID",
|
"V_ENGINE",
|
||||||
"EST_CO_NM",
|
"V_MILEAGE",
|
||||||
"EST_ADDR1",
|
"V_COLOR",
|
||||||
"EST_ADDR2",
|
"V_TONE",
|
||||||
"EST_CITY",
|
"V_STAGE",
|
||||||
"EST_ST",
|
"PAINT_CD1",
|
||||||
"EST_ZIP",
|
"PAINT_CD2",
|
||||||
"EST_CTRY",
|
"PAINT_CD3",
|
||||||
"EST_PH1",
|
|
||||||
//"EST_PH1X",
|
|
||||||
//"EST_PH2",
|
|
||||||
//"EST_PH2X",
|
|
||||||
//"EST_FAX",
|
|
||||||
//"EST_FAXX",
|
|
||||||
"EST_CT_LN",
|
|
||||||
"EST_CT_FN",
|
|
||||||
"EST_EA",
|
|
||||||
//"EST_LIC_NO",
|
|
||||||
//"EST_FILENO",
|
|
||||||
// "INSP_CT_LN",
|
|
||||||
// "INSP_CT_FN",
|
|
||||||
// "INSP_ADDR1",
|
|
||||||
// "INSP_ADDR2",
|
|
||||||
// "INSP_CITY",
|
|
||||||
// "INSP_ST",
|
|
||||||
// "INSP_ZIP",
|
|
||||||
// "INSP_CTRY",
|
|
||||||
// "INSP_PH1",
|
|
||||||
// "INSP_PH1X",
|
|
||||||
// "INSP_PH2",
|
|
||||||
// "INSP_PH2X",
|
|
||||||
// "INSP_FAX",
|
|
||||||
// "INSP_FAXX",
|
|
||||||
// "INSP_EA",
|
|
||||||
// "INSP_CODE",
|
|
||||||
// "INSP_DESC",
|
|
||||||
"INSP_DATE", //RENAME TO date_estimated
|
|
||||||
// "INSP_TIME",
|
|
||||||
// "RF_CO_ID",
|
|
||||||
// "RF_CO_NM",
|
|
||||||
// "RF_ADDR1",
|
|
||||||
// "RF_ADDR2",
|
|
||||||
// "RF_CITY",
|
|
||||||
// "RF_ST",
|
|
||||||
// "RF_ZIP",
|
|
||||||
// "RF_CTRY",
|
|
||||||
// "RF_PH1",
|
|
||||||
// "RF_PH1X",
|
|
||||||
// "RF_PH2",
|
|
||||||
// "RF_PH2X",
|
|
||||||
// "RF_FAX",
|
|
||||||
// "RF_FAXX",
|
|
||||||
// "RF_CT_LN",
|
|
||||||
// "RF_CT_FN",
|
|
||||||
// "RF_EA",
|
|
||||||
// "RF_TAX_ID",
|
|
||||||
// "RF_LIC_NO",
|
|
||||||
// "RF_BAR_NO",
|
|
||||||
// "RO_IN_DATE",
|
|
||||||
// "RO_IN_TIME",
|
|
||||||
// "TAR_DATE",
|
|
||||||
// "TAR_TIME",
|
|
||||||
// "RO_CMPDATE",
|
|
||||||
// "RO_CMPTIME",
|
|
||||||
// "DATE_OUT",
|
|
||||||
// "TIME_OUT",
|
|
||||||
// "RF_ESTIMTR",
|
|
||||||
// "MKTG_TYPE",
|
|
||||||
// "MKTG_SRC",
|
|
||||||
// "LOC_NM",
|
|
||||||
// "LOC_ADDR1",
|
|
||||||
// "LOC_ADDR2",
|
|
||||||
// "LOC_CITY",
|
|
||||||
// "LOC_ST",
|
|
||||||
// "LOC_ZIP",
|
|
||||||
// "LOC_CTRY",
|
|
||||||
// "LOC_PH1",
|
|
||||||
// "LOC_PH1X",
|
|
||||||
// "LOC_PH2",
|
|
||||||
// "LOC_PH2X",
|
|
||||||
// "LOC_FAX",
|
|
||||||
// "LOC_FAXX",
|
|
||||||
// "LOC_CT_LN",
|
|
||||||
// "LOC_CT_FN",
|
|
||||||
// "LOC_TITLE",
|
|
||||||
// "LOC_PH",
|
|
||||||
// "LOC_PHX",
|
|
||||||
// "LOC_EA",
|
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
//We don't have an inspection date, we instead have `date_estimated`
|
|
||||||
rawAd2Data.date_estimated = rawAd2Data.insp_date;
|
|
||||||
delete rawAd2Data.insp_date;
|
|
||||||
|
|
||||||
return null;
|
//An old error where the column had an extra underscore.
|
||||||
|
rawVehData.v_make_desc = rawVehData.v_makedesc || rawVehData.v_makecode; //Fallback for US.
|
||||||
|
delete rawVehData.v_makedesc;
|
||||||
|
//An old error where the column had an extra underscore.
|
||||||
|
rawVehData.v_model_desc = rawVehData.v_model;
|
||||||
|
delete rawVehData.v_model;
|
||||||
|
|
||||||
|
//Consolidate Area of Damage.
|
||||||
|
rawVehData.area_of_damage = {
|
||||||
|
impact1: rawVehData.impact_1 ?? "",
|
||||||
|
impact2: rawVehData.impact_2 ?? "",
|
||||||
|
};
|
||||||
|
delete rawVehData.impact_1;
|
||||||
|
delete rawVehData.impact_2;
|
||||||
|
|
||||||
|
//Consolidate Paint Code information.
|
||||||
|
rawVehData.paint_codes = {
|
||||||
|
paint_cd1: rawVehData.paint_cd1 ?? "",
|
||||||
|
paint_cd2: rawVehData.paint_cd2 ?? "",
|
||||||
|
paint_cd3: rawVehData.paint_cd3 ?? "",
|
||||||
|
};
|
||||||
|
delete rawVehData.paint_cd1;
|
||||||
|
delete rawVehData.paint_cd2;
|
||||||
|
delete rawVehData.paint_cd3;
|
||||||
|
|
||||||
|
rawVehData.shopid = "UUID"; //TODO: Pass down the shopid for generation.
|
||||||
|
|
||||||
|
//Aggregate the vehicle data to be stamped onto the job record.
|
||||||
|
const jobVehiclData = {
|
||||||
|
plate_no: rawVehData.plate_no,
|
||||||
|
plate_st: rawVehData.plate_st,
|
||||||
|
v_vin: rawVehData.v_vin,
|
||||||
|
v_model_yr: rawVehData.v_model_yr,
|
||||||
|
v_make_desc: rawVehData.v_make_desc,
|
||||||
|
v_model_desc: rawVehData.v_model_desc,
|
||||||
|
v_color: rawVehData.v_color,
|
||||||
|
kmin: rawVehData.v_mileage,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...jobVehiclData,
|
||||||
|
vehicle: {
|
||||||
|
data: rawVehData,
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DecodeVeh;
|
export default DecodeVeh;
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ import log from "electron-log/main";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
import DecodeAD1 from "./decode-ad1";
|
import DecodeAD1 from "./decode-ad1";
|
||||||
import { ParsedAD1 } from "./decode-ad1.interface";
|
import { DecodedAd1 } from "./decode-ad1.interface";
|
||||||
import DecodeAD2 from "./decode-ad2";
|
import DecodeAD2 from "./decode-ad2";
|
||||||
import { ParsedAD2 } from "./decode-ad2.interface";
|
import { DecodedAD2 } from "./decode-ad2.interface";
|
||||||
|
import DecodeLin from "./decode-lin";
|
||||||
|
import { DecodedLin } from "./decode-lin.interface";
|
||||||
import DecodeVeh from "./decode-veh";
|
import DecodeVeh from "./decode-veh";
|
||||||
import { ParsedVeh } from "./decode-veh.interface";
|
import { DecodedVeh } from "./decode-veh.interface";
|
||||||
|
|
||||||
async function ImportJob(filepath: string): Promise<void> {
|
async function ImportJob(filepath: string): Promise<void> {
|
||||||
const parsedFilePath = path.parse(filepath);
|
const parsedFilePath = path.parse(filepath);
|
||||||
@@ -17,10 +19,13 @@ async function ImportJob(filepath: string): Promise<void> {
|
|||||||
log.debug("Importing Job", extensionlessFilePath);
|
log.debug("Importing Job", extensionlessFilePath);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ad1: ParsedAD1 = await DecodeAD1(extensionlessFilePath);
|
//The below all end up returning parts of the job object.
|
||||||
const ad2: ParsedAD2 = await DecodeAD2(extensionlessFilePath);
|
//Some of them return additional info - e.g. owner or vehicle record data at both the job and corresponding table level.
|
||||||
const veh: ParsedVeh = await DecodeVeh(extensionlessFilePath);
|
const ad1: DecodedAd1 = await DecodeAD1(extensionlessFilePath);
|
||||||
log.debug("EMS Object", { ad1, ad2, veh });
|
const ad2: DecodedAD2 = await DecodeAD2(extensionlessFilePath);
|
||||||
|
const veh: DecodedVeh = await DecodeVeh(extensionlessFilePath);
|
||||||
|
const lin: DecodedLin[] = await DecodeLin(extensionlessFilePath);
|
||||||
|
log.debug("EMS Object", { ad1, ad2, veh, lin });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Error encountered while decoding job. ", errorTypeCheck(error));
|
log.error("Error encountered while decoding job. ", errorTypeCheck(error));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user