Add several EMS file formats.
This commit is contained in:
@@ -8,7 +8,7 @@ import { DecodedAd1, OwnerRecordInterface } from "./decode-ad1.interface";
|
|||||||
const DecodeAD1 = async (
|
const DecodeAD1 = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
): Promise<DecodedAd1> => {
|
): Promise<DecodedAd1> => {
|
||||||
let dbf: DBFFile;
|
let dbf: DBFFile | null = null;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}A.AD1`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}A.AD1`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import errorTypeCheck from "../../util/errorTypeCheck";
|
|||||||
const DecodeAD2 = async (
|
const DecodeAD2 = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
): Promise<DecodedAD2> => {
|
): Promise<DecodedAD2> => {
|
||||||
let dbf: DBFFile;
|
let dbf: DBFFile | null = null;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}B.AD2`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}B.AD2`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import errorTypeCheck from "../../util/errorTypeCheck";
|
|||||||
const DecodeLin = async (
|
const DecodeLin = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
): Promise<DecodedLin[]> => {
|
): Promise<DecodedLin[]> => {
|
||||||
let dbf: DBFFile;
|
let dbf: DBFFile | null = null;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}.LIN`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}.LIN`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { DecodedPfh } from "./decode-pfh.interface";
|
|||||||
const DecodePfh = async (
|
const DecodePfh = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
): Promise<DecodedPfh> => {
|
): Promise<DecodedPfh> => {
|
||||||
let dbf: DBFFile;
|
let dbf: DBFFile | null = null;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}.PFH`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}.PFH`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
const DecodePfl = async (
|
const DecodePfl = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
): Promise<DecodedPfl> => {
|
): Promise<DecodedPfl> => {
|
||||||
let dbf: DBFFile;
|
let dbf: DBFFile | null = null;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}.PFL`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}.PFL`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
46
src/main/decoder/decode-pfm.interface.ts
Normal file
46
src/main/decoder/decode-pfm.interface.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
export interface DecodedPfmLine {
|
||||||
|
matl_type?: string;
|
||||||
|
cal_code?: number;
|
||||||
|
cal_desc?: string;
|
||||||
|
cal_maxdlr?: number;
|
||||||
|
cal_prip?: number;
|
||||||
|
cal_secp?: number;
|
||||||
|
mat_calp?: number;
|
||||||
|
cal_prethr?: number;
|
||||||
|
cal_pstthr?: number;
|
||||||
|
cal_thramt?: number;
|
||||||
|
cal_lbrmin?: number;
|
||||||
|
cal_lbrrte?: number;
|
||||||
|
cal_opcode?: string;
|
||||||
|
tax_ind?: boolean;
|
||||||
|
mat_taxp?: number;
|
||||||
|
mat_adjp?: number;
|
||||||
|
mat_tx_ty1?: string;
|
||||||
|
mat_tx_in1?: boolean;
|
||||||
|
mat_tx_ty2?: string;
|
||||||
|
mat_tx_in2?: boolean;
|
||||||
|
mat_tx_ty3?: string;
|
||||||
|
mat_tx_in3?: boolean;
|
||||||
|
mat_tx_ty4?: string;
|
||||||
|
mat_tx_in4?: boolean;
|
||||||
|
mat_tx_ty5?: string;
|
||||||
|
mat_tx_in5?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JobMaterialRateFields {
|
||||||
|
rate_mapa: number;
|
||||||
|
tax_paint_mat_rt: number;
|
||||||
|
rate_mash: number;
|
||||||
|
tax_shop_mat_rt: number;
|
||||||
|
rate_mahw: number;
|
||||||
|
tax_levies_rt: number;
|
||||||
|
rate_ma2s: number;
|
||||||
|
rate_ma2t: number;
|
||||||
|
rate_ma3s: number;
|
||||||
|
rate_macs: number;
|
||||||
|
rate_mabl: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DecodedPfm extends JobMaterialRateFields {
|
||||||
|
cieca_pfm: DecodedPfmLine[];
|
||||||
|
}
|
||||||
107
src/main/decoder/decode-pfm.ts
Normal file
107
src/main/decoder/decode-pfm.ts
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
import { DBFFile } from "dbffile";
|
||||||
|
import log from "electron-log/main";
|
||||||
|
import _ from "lodash";
|
||||||
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import {
|
||||||
|
DecodedPfm,
|
||||||
|
DecodedPfmLine,
|
||||||
|
JobMaterialRateFields,
|
||||||
|
} from "./decode-pfm.interface";
|
||||||
|
|
||||||
|
const DecodePfm = async (
|
||||||
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedPfm> => {
|
||||||
|
let dbf: DBFFile | null = null;
|
||||||
|
try {
|
||||||
|
dbf = await DBFFile.open(`${extensionlessFilePath}.PFM`);
|
||||||
|
} catch (error) {
|
||||||
|
//PFM File only has 1 location.
|
||||||
|
log.error("Error opening PFM File.", errorTypeCheck(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbf) {
|
||||||
|
log.error(`Could not find any PFM files at ${extensionlessFilePath}`);
|
||||||
|
throw new Error(`Could not find any PFM 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 jobMaterialRates: JobMaterialRateFields = {
|
||||||
|
rate_mapa: 0,
|
||||||
|
tax_paint_mat_rt: 0,
|
||||||
|
rate_mash: 0,
|
||||||
|
tax_shop_mat_rt: 0,
|
||||||
|
rate_mahw: 0,
|
||||||
|
tax_levies_rt: 0,
|
||||||
|
rate_ma2s: 0,
|
||||||
|
rate_ma2t: 0,
|
||||||
|
rate_ma3s: 0,
|
||||||
|
rate_macs: 0,
|
||||||
|
rate_mabl: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const rawPfmData: DecodedPfmLine[] = rawDBFRecord.map((record) => {
|
||||||
|
const singleLineData: DecodedPfmLine = deepLowerCaseKeys(
|
||||||
|
_.pick(record, [
|
||||||
|
//TODO: Add typings for EMS File Formats.
|
||||||
|
"MATL_TYPE",
|
||||||
|
"CAL_CODE",
|
||||||
|
"CAL_DESC",
|
||||||
|
"CAL_MAXDLR",
|
||||||
|
"CAL_PRIP",
|
||||||
|
|
||||||
|
"CAL_SECP",
|
||||||
|
"MAT_CALP",
|
||||||
|
"CAL_PRETHR", //Mitchell here
|
||||||
|
"CAL_PSTTHR",
|
||||||
|
"CAL_THRAMT",
|
||||||
|
|
||||||
|
"CAL_LBRMIN",
|
||||||
|
|
||||||
|
"CAL_LBRRTE", //Audatex puts it here
|
||||||
|
"CAL_OPCODE",
|
||||||
|
|
||||||
|
"TAX_IND",
|
||||||
|
"MAT_TAXP",
|
||||||
|
"MAT_ADJP",
|
||||||
|
"MAT_TX_TY1",
|
||||||
|
"MAT_TX_IN1",
|
||||||
|
"MAT_TX_TY2",
|
||||||
|
"MAT_TX_IN2",
|
||||||
|
"MAT_TX_TY3",
|
||||||
|
"MAT_TX_IN3",
|
||||||
|
"MAT_TX_TY4",
|
||||||
|
"MAT_TX_IN4",
|
||||||
|
"MAT_TX_TY5",
|
||||||
|
"MAT_TX_IN5",
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
//Also capture the whole object.
|
||||||
|
//This is segmented because the whole object was not previously captured for ImEX as it wasn't needed.
|
||||||
|
//Rome needs the whole object to accurately calculate the tax rates.
|
||||||
|
|
||||||
|
return singleLineData;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Apply line by line adjustments.
|
||||||
|
const materialsLine: DecodedPfmLine | undefined = rawPfmData.find(
|
||||||
|
(line) => line.matl_type === "MAPA"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (materialsLine) {
|
||||||
|
jobMaterialRates.rate_mapa =
|
||||||
|
materialsLine.cal_lbrrte || materialsLine.cal_prethr || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Apply business logic transfomrations.
|
||||||
|
//We don't have an inspection date, we instead have `date_estimated`
|
||||||
|
|
||||||
|
return { ...jobMaterialRates, cieca_pfm: rawPfmData };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DecodePfm;
|
||||||
28
src/main/decoder/decode-pfo.interface.ts
Normal file
28
src/main/decoder/decode-pfo.interface.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
export interface DecodedPfo {
|
||||||
|
tx_tow_ty?: string;
|
||||||
|
tow_t_ty1?: string;
|
||||||
|
tow_t_in1?: boolean;
|
||||||
|
tow_t_ty2?: string;
|
||||||
|
tow_t_in2?: boolean;
|
||||||
|
tow_t_ty3?: string;
|
||||||
|
tow_t_in3?: boolean;
|
||||||
|
tow_t_ty4?: string;
|
||||||
|
tow_t_in4?: boolean;
|
||||||
|
tow_t_ty5?: string;
|
||||||
|
tow_t_in5?: boolean;
|
||||||
|
tow_t_ty6?: string;
|
||||||
|
tow_t_in6?: boolean;
|
||||||
|
tx_stor_ty?: string;
|
||||||
|
stor_t_ty1?: string;
|
||||||
|
stor_t_in1?: boolean;
|
||||||
|
stor_t_ty2?: string;
|
||||||
|
stor_t_in2?: boolean;
|
||||||
|
stor_t_ty3?: string;
|
||||||
|
stor_t_in3?: boolean;
|
||||||
|
stor_t_ty4?: string;
|
||||||
|
stor_t_in4?: boolean;
|
||||||
|
stor_t_ty5?: string;
|
||||||
|
stor_t_in5?: boolean;
|
||||||
|
stor_t_ty6?: string;
|
||||||
|
stor_t_in6?: boolean;
|
||||||
|
}
|
||||||
66
src/main/decoder/decode-pfo.ts
Normal file
66
src/main/decoder/decode-pfo.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { DBFFile } from "dbffile";
|
||||||
|
import log from "electron-log/main";
|
||||||
|
import _ from "lodash";
|
||||||
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import { DecodedPfo } from "./decode-pfo.interface";
|
||||||
|
|
||||||
|
const DecodePfo = async (
|
||||||
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedPfo> => {
|
||||||
|
let dbf: DBFFile | null = null;
|
||||||
|
try {
|
||||||
|
dbf = await DBFFile.open(`${extensionlessFilePath}.PFO`);
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Error opening PFO File.", errorTypeCheck(error));
|
||||||
|
dbf = await DBFFile.open(`${extensionlessFilePath}.PFO`);
|
||||||
|
log.log("Trying to find PFO file using regular CIECA Id.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbf) {
|
||||||
|
log.error(`Could not find any PFO files at ${extensionlessFilePath}`);
|
||||||
|
throw new Error(`Could not find any PFO files at ${extensionlessFilePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawDBFRecord = await dbf.readRecords(1);
|
||||||
|
|
||||||
|
//PFO will always have only 1 row.
|
||||||
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
|
const rawPfoData: DecodedPfo = deepLowerCaseKeys(
|
||||||
|
_.pick(rawDBFRecord[0], [
|
||||||
|
//TODO: Add typings for EMS File Formats.
|
||||||
|
"TX_TOW_TY",
|
||||||
|
"TOW_T_TY1",
|
||||||
|
"TOW_T_IN1",
|
||||||
|
"TOW_T_TY2",
|
||||||
|
"TOW_T_IN2",
|
||||||
|
"TOW_T_TY3",
|
||||||
|
"TOW_T_IN3",
|
||||||
|
"TOW_T_TY4",
|
||||||
|
"TOW_T_IN4",
|
||||||
|
"TOW_T_TY5",
|
||||||
|
"TOW_T_IN5",
|
||||||
|
"TOW_T_TY6",
|
||||||
|
"TOW_T_IN6",
|
||||||
|
"TX_STOR_TY",
|
||||||
|
"STOR_T_TY1",
|
||||||
|
"STOR_T_IN1",
|
||||||
|
"STOR_T_TY2",
|
||||||
|
"STOR_T_IN2",
|
||||||
|
"STOR_T_TY3",
|
||||||
|
"STOR_T_IN3",
|
||||||
|
"STOR_T_TY4",
|
||||||
|
"STOR_T_IN4",
|
||||||
|
"STOR_T_TY5",
|
||||||
|
"STOR_T_IN5",
|
||||||
|
"STOR_T_TY6",
|
||||||
|
"STOR_T_IN6",
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
//Apply business logic transfomrations.
|
||||||
|
|
||||||
|
return rawPfoData;
|
||||||
|
};
|
||||||
|
export default DecodePfo;
|
||||||
143
src/main/decoder/decode-pft.interface.ts
Normal file
143
src/main/decoder/decode-pft.interface.ts
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* Interface representing decoded data from a PFT file
|
||||||
|
* Contains tax type information with up to 6 tax types and 5 tiers each
|
||||||
|
*/
|
||||||
|
export interface DecodedPft {
|
||||||
|
// Tax Type 1
|
||||||
|
tax_type1?: string;
|
||||||
|
ty1_tier1?: number;
|
||||||
|
ty1_thres1?: number;
|
||||||
|
ty1_rate1?: number;
|
||||||
|
ty1_sur1?: number;
|
||||||
|
ty1_tier2?: number;
|
||||||
|
ty1_thres2?: number;
|
||||||
|
ty1_rate2?: number;
|
||||||
|
ty1_sur2?: number;
|
||||||
|
ty1_tier3?: number;
|
||||||
|
ty1_thres3?: number;
|
||||||
|
ty1_rate3?: number;
|
||||||
|
ty1_sur3?: number;
|
||||||
|
ty1_tier4?: number;
|
||||||
|
ty1_thres4?: number;
|
||||||
|
ty1_rate4?: number;
|
||||||
|
ty1_sur4?: number;
|
||||||
|
ty1_tier5?: number;
|
||||||
|
ty1_thres5?: number;
|
||||||
|
ty1_rate5?: number;
|
||||||
|
ty1_sur5?: number;
|
||||||
|
|
||||||
|
// Tax Type 2
|
||||||
|
tax_type2?: string;
|
||||||
|
ty2_tier1?: number;
|
||||||
|
ty2_thres1?: number;
|
||||||
|
ty2_rate1?: number;
|
||||||
|
ty2_sur1?: number;
|
||||||
|
ty2_tier2?: number;
|
||||||
|
ty2_thres2?: number;
|
||||||
|
ty2_rate2?: number;
|
||||||
|
ty2_sur2?: number;
|
||||||
|
ty2_tier3?: number;
|
||||||
|
ty2_thres3?: number;
|
||||||
|
ty2_rate3?: number;
|
||||||
|
ty2_sur3?: number;
|
||||||
|
ty2_tier4?: number;
|
||||||
|
ty2_thres4?: number;
|
||||||
|
ty2_rate4?: number;
|
||||||
|
ty2_sur4?: number;
|
||||||
|
ty2_tier5?: number;
|
||||||
|
ty2_thres5?: number;
|
||||||
|
ty2_rate5?: number;
|
||||||
|
ty2_sur5?: number;
|
||||||
|
|
||||||
|
// Tax Type 3
|
||||||
|
tax_type3?: string;
|
||||||
|
ty3_tier1?: number;
|
||||||
|
ty3_thres1?: number;
|
||||||
|
ty3_rate1?: number;
|
||||||
|
ty3_sur1?: number;
|
||||||
|
ty3_tier2?: number;
|
||||||
|
ty3_thres2?: number;
|
||||||
|
ty3_rate2?: number;
|
||||||
|
ty3_sur2?: number;
|
||||||
|
ty3_tier3?: number;
|
||||||
|
ty3_thres3?: number;
|
||||||
|
ty3_rate3?: number;
|
||||||
|
ty3_sur3?: number;
|
||||||
|
ty3_tier4?: number;
|
||||||
|
ty3_thres4?: number;
|
||||||
|
ty3_rate4?: number;
|
||||||
|
ty3_sur4?: number;
|
||||||
|
ty3_tier5?: number;
|
||||||
|
ty3_thres5?: number;
|
||||||
|
ty3_rate5?: number;
|
||||||
|
ty3_sur5?: number;
|
||||||
|
|
||||||
|
// Tax Type 4
|
||||||
|
tax_type4?: string;
|
||||||
|
ty4_tier1?: number;
|
||||||
|
ty4_thres1?: number;
|
||||||
|
ty4_rate1?: number;
|
||||||
|
ty4_sur1?: number;
|
||||||
|
ty4_tier2?: number;
|
||||||
|
ty4_thres2?: number;
|
||||||
|
ty4_rate2?: number;
|
||||||
|
ty4_sur2?: number;
|
||||||
|
ty4_tier3?: number;
|
||||||
|
ty4_thres3?: number;
|
||||||
|
ty4_rate3?: number;
|
||||||
|
ty4_sur3?: number;
|
||||||
|
ty4_tier4?: number;
|
||||||
|
ty4_thres4?: number;
|
||||||
|
ty4_rate4?: number;
|
||||||
|
ty4_sur4?: number;
|
||||||
|
ty4_tier5?: number;
|
||||||
|
ty4_thres5?: number;
|
||||||
|
ty4_rate5?: number;
|
||||||
|
ty4_sur5?: number;
|
||||||
|
|
||||||
|
// Tax Type 5
|
||||||
|
tax_type5?: string;
|
||||||
|
ty5_tier1?: number;
|
||||||
|
ty5_thres1?: number;
|
||||||
|
ty5_rate1?: number;
|
||||||
|
ty5_sur1?: number;
|
||||||
|
ty5_tier2?: number;
|
||||||
|
ty5_thres2?: number;
|
||||||
|
ty5_rate2?: number;
|
||||||
|
ty5_sur2?: number;
|
||||||
|
ty5_tier3?: number;
|
||||||
|
ty5_thres3?: number;
|
||||||
|
ty5_rate3?: number;
|
||||||
|
ty5_sur3?: number;
|
||||||
|
ty5_tier4?: number;
|
||||||
|
ty5_thres4?: number;
|
||||||
|
ty5_rate4?: number;
|
||||||
|
ty5_sur4?: number;
|
||||||
|
ty5_tier5?: number;
|
||||||
|
ty5_thres5?: number;
|
||||||
|
ty5_rate5?: number;
|
||||||
|
ty5_sur5?: number;
|
||||||
|
|
||||||
|
// Tax Type 6
|
||||||
|
tax_type6?: string;
|
||||||
|
ty6_tier1?: number;
|
||||||
|
ty6_thres1?: number;
|
||||||
|
ty6_rate1?: number;
|
||||||
|
ty6_sur1?: number;
|
||||||
|
ty6_tier2?: number;
|
||||||
|
ty6_thres2?: number;
|
||||||
|
ty6_rate2?: number;
|
||||||
|
ty6_sur2?: number;
|
||||||
|
ty6_tier3?: number;
|
||||||
|
ty6_thres3?: number;
|
||||||
|
ty6_rate3?: number;
|
||||||
|
ty6_sur3?: number;
|
||||||
|
ty6_tier4?: number;
|
||||||
|
ty6_thres4?: number;
|
||||||
|
ty6_rate4?: number;
|
||||||
|
ty6_sur4?: number;
|
||||||
|
ty6_tier5?: number;
|
||||||
|
ty6_thres5?: number;
|
||||||
|
ty6_rate5?: number;
|
||||||
|
ty6_sur5?: number;
|
||||||
|
}
|
||||||
165
src/main/decoder/decode-pft.ts
Normal file
165
src/main/decoder/decode-pft.ts
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
import { DBFFile } from "dbffile";
|
||||||
|
import log from "electron-log/main";
|
||||||
|
import _ from "lodash";
|
||||||
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import { DecodedPft } from "./decode-pft.interface";
|
||||||
|
|
||||||
|
const DecodePft = async (
|
||||||
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedPft> => {
|
||||||
|
let dbf: DBFFile | null = null;
|
||||||
|
try {
|
||||||
|
dbf = await DBFFile.open(`${extensionlessFilePath}.PFT`);
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Error opening PFH File.", errorTypeCheck(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbf) {
|
||||||
|
log.error(`Could not find any PFT files at ${extensionlessFilePath}`);
|
||||||
|
throw new Error(`Could not find any PFT files at ${extensionlessFilePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawDBFRecord = await dbf.readRecords(1);
|
||||||
|
|
||||||
|
//PFT will always have only 1 row.
|
||||||
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
|
const rawPftData: DecodedPft = deepLowerCaseKeys(
|
||||||
|
_.pick(rawDBFRecord[0], [
|
||||||
|
//TODO: Add typings for EMS File Formats.
|
||||||
|
"TAX_TYPE1", //The below is is taken from a CCC estimate. Will require validation to ensure it is also accurate for Audatex/Mitchell
|
||||||
|
"TY1_TIER1",
|
||||||
|
"TY1_THRES1",
|
||||||
|
"TY1_RATE1",
|
||||||
|
"TY1_SUR1",
|
||||||
|
"TY1_TIER2",
|
||||||
|
"TY1_THRES2",
|
||||||
|
"TY1_RATE2",
|
||||||
|
"TY1_SUR2",
|
||||||
|
"TY1_TIER3",
|
||||||
|
"TY1_THRES3",
|
||||||
|
"TY1_RATE3",
|
||||||
|
"TY1_SUR3",
|
||||||
|
"TY1_TIER4",
|
||||||
|
"TY1_THRES4",
|
||||||
|
"TY1_RATE4",
|
||||||
|
"TY1_SUR4",
|
||||||
|
"TY1_TIER5",
|
||||||
|
"TY1_THRES5",
|
||||||
|
"TY1_RATE5",
|
||||||
|
"TY1_SUR5",
|
||||||
|
"TAX_TYPE2",
|
||||||
|
"TY2_TIER1",
|
||||||
|
"TY2_THRES1",
|
||||||
|
"TY2_RATE1",
|
||||||
|
"TY2_SUR1",
|
||||||
|
"TY2_TIER2",
|
||||||
|
"TY2_THRES2",
|
||||||
|
"TY2_RATE2",
|
||||||
|
"TY2_SUR2",
|
||||||
|
"TY2_TIER3",
|
||||||
|
"TY2_THRES3",
|
||||||
|
"TY2_RATE3",
|
||||||
|
"TY2_SUR3",
|
||||||
|
"TY2_TIER4",
|
||||||
|
"TY2_THRES4",
|
||||||
|
"TY2_RATE4",
|
||||||
|
"TY2_SUR4",
|
||||||
|
"TY2_TIER5",
|
||||||
|
"TY2_THRES5",
|
||||||
|
"TY2_RATE5",
|
||||||
|
"TY2_SUR5",
|
||||||
|
"TAX_TYPE3",
|
||||||
|
"TY3_TIER1",
|
||||||
|
"TY3_THRES1",
|
||||||
|
"TY3_RATE1",
|
||||||
|
"TY3_SUR1",
|
||||||
|
"TY3_TIER2",
|
||||||
|
"TY3_THRES2",
|
||||||
|
"TY3_RATE2",
|
||||||
|
"TY3_SUR2",
|
||||||
|
"TY3_TIER3",
|
||||||
|
"TY3_THRES3",
|
||||||
|
"TY3_RATE3",
|
||||||
|
"TY3_SUR3",
|
||||||
|
"TY3_TIER4",
|
||||||
|
"TY3_THRES4",
|
||||||
|
"TY3_RATE4",
|
||||||
|
"TY3_SUR4",
|
||||||
|
"TY3_TIER5",
|
||||||
|
"TY3_THRES5",
|
||||||
|
"TY3_RATE5",
|
||||||
|
"TY3_SUR5",
|
||||||
|
"TAX_TYPE4",
|
||||||
|
"TY4_TIER1",
|
||||||
|
"TY4_THRES1",
|
||||||
|
"TY4_RATE1",
|
||||||
|
"TY4_SUR1",
|
||||||
|
"TY4_TIER2",
|
||||||
|
"TY4_THRES2",
|
||||||
|
"TY4_RATE2",
|
||||||
|
"TY4_SUR2",
|
||||||
|
"TY4_TIER3",
|
||||||
|
"TY4_THRES3",
|
||||||
|
"TY4_RATE3",
|
||||||
|
"TY4_SUR3",
|
||||||
|
"TY4_TIER4",
|
||||||
|
"TY4_THRES4",
|
||||||
|
"TY4_RATE4",
|
||||||
|
"TY4_SUR4",
|
||||||
|
"TY4_TIER5",
|
||||||
|
"TY4_THRES5",
|
||||||
|
"TY4_RATE5",
|
||||||
|
"TY4_SUR5",
|
||||||
|
"TAX_TYPE5",
|
||||||
|
"TY5_TIER1",
|
||||||
|
"TY5_THRES1",
|
||||||
|
"TY5_RATE1",
|
||||||
|
"TY5_SUR1",
|
||||||
|
"TY5_TIER2",
|
||||||
|
"TY5_THRES2",
|
||||||
|
"TY5_RATE2",
|
||||||
|
"TY5_SUR2",
|
||||||
|
"TY5_TIER3",
|
||||||
|
"TY5_THRES3",
|
||||||
|
"TY5_RATE3",
|
||||||
|
"TY5_SUR3",
|
||||||
|
"TY5_TIER4",
|
||||||
|
"TY5_THRES4",
|
||||||
|
"TY5_RATE4",
|
||||||
|
"TY5_SUR4",
|
||||||
|
"TY5_TIER5",
|
||||||
|
"TY5_THRES5",
|
||||||
|
"TY5_RATE5",
|
||||||
|
"TY5_SUR5",
|
||||||
|
"TAX_TYPE6",
|
||||||
|
"TY6_TIER1",
|
||||||
|
"TY6_THRES1",
|
||||||
|
"TY6_RATE1",
|
||||||
|
"TY6_SUR1",
|
||||||
|
"TY6_TIER2",
|
||||||
|
"TY6_THRES2",
|
||||||
|
"TY6_RATE2",
|
||||||
|
"TY6_SUR2",
|
||||||
|
"TY6_TIER3",
|
||||||
|
"TY6_THRES3",
|
||||||
|
"TY6_RATE3",
|
||||||
|
"TY6_SUR3",
|
||||||
|
"TY6_TIER4",
|
||||||
|
"TY6_THRES4",
|
||||||
|
"TY6_RATE4",
|
||||||
|
"TY6_SUR4",
|
||||||
|
"TY6_TIER5",
|
||||||
|
"TY6_THRES5",
|
||||||
|
"TY6_RATE5",
|
||||||
|
"TY6_SUR5",
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
//Apply business logic transfomrations.
|
||||||
|
//We don't have an inspection date, we instead have `date_estimated`
|
||||||
|
|
||||||
|
return rawPftData;
|
||||||
|
};
|
||||||
|
export default DecodePft;
|
||||||
20
src/main/decoder/decode-stl.interface.ts
Normal file
20
src/main/decoder/decode-stl.interface.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export interface DecodedStl {
|
||||||
|
ttl_type?: string;
|
||||||
|
ttl_typecd?: string;
|
||||||
|
t_amt?: number;
|
||||||
|
t_hrs?: number;
|
||||||
|
t_addlbr?: number;
|
||||||
|
t_discamt?: number;
|
||||||
|
t_mkupamt?: number;
|
||||||
|
t_gdiscamt?: number;
|
||||||
|
tax_amt?: number;
|
||||||
|
nt_amt?: number;
|
||||||
|
nt_hrs?: number;
|
||||||
|
nt_addlbr?: number;
|
||||||
|
nt_disc?: number;
|
||||||
|
nt_mkup?: number;
|
||||||
|
nt_gdis?: number;
|
||||||
|
ttl_typamt?: number;
|
||||||
|
ttl_hrs?: number;
|
||||||
|
ttl_amt?: number;
|
||||||
|
}
|
||||||
62
src/main/decoder/decode-stl.ts
Normal file
62
src/main/decoder/decode-stl.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { DBFFile } from "dbffile";
|
||||||
|
import log from "electron-log/main";
|
||||||
|
import _ from "lodash";
|
||||||
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import { DecodedStl } from "./decode-stl.interface";
|
||||||
|
|
||||||
|
const DecodeStl = async (
|
||||||
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedStl[]> => {
|
||||||
|
let dbf: DBFFile | null = null;
|
||||||
|
try {
|
||||||
|
dbf = await DBFFile.open(`${extensionlessFilePath}.STL`);
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Error opening STL File.", errorTypeCheck(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbf) {
|
||||||
|
log.error(`Could not find any STL files at ${extensionlessFilePath}`);
|
||||||
|
throw new Error(`Could not find any STL 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 rawStlData: DecodedStl[] = rawDBFRecord.map((record) => {
|
||||||
|
const singleLineData: DecodedStl = deepLowerCaseKeys(
|
||||||
|
_.pick(record, [
|
||||||
|
//TODO: Add typings for EMS File Formats.
|
||||||
|
"TTL_TYPE",
|
||||||
|
"TTL_TYPECD",
|
||||||
|
"T_AMT",
|
||||||
|
"T_HRS",
|
||||||
|
"T_ADDLBR",
|
||||||
|
"T_DISCAMT",
|
||||||
|
"T_MKUPAMT",
|
||||||
|
"T_GDISCAMT",
|
||||||
|
"TAX_AMT",
|
||||||
|
"NT_AMT",
|
||||||
|
"NT_HRS",
|
||||||
|
"NT_ADDLBR",
|
||||||
|
"NT_DISC",
|
||||||
|
"NT_MKUP",
|
||||||
|
"NT_GDIS",
|
||||||
|
"TTL_TYPAMT",
|
||||||
|
"TTL_HRS",
|
||||||
|
"TTL_AMT",
|
||||||
|
])
|
||||||
|
);
|
||||||
|
//Apply line by line adjustments.
|
||||||
|
|
||||||
|
return singleLineData;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Apply business logic transfomrations.
|
||||||
|
//We don't have an inspection date, we instead have `date_estimated`
|
||||||
|
|
||||||
|
return rawStlData;
|
||||||
|
};
|
||||||
|
export default DecodeStl;
|
||||||
22
src/main/decoder/decode-ttl.interface.ts
Normal file
22
src/main/decoder/decode-ttl.interface.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
export interface DecodedTtl {
|
||||||
|
clm_total: number;
|
||||||
|
depreciation_taxes: number;
|
||||||
|
cieca_ttl: DecodedTtlLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DecodedTtlLine {
|
||||||
|
g_ttl_amt?: number;
|
||||||
|
g_bett_amt?: number;
|
||||||
|
g_rpd_amt?: number;
|
||||||
|
g_ded_amt?: number;
|
||||||
|
g_cust_amt?: number;
|
||||||
|
g_aa_amt?: number;
|
||||||
|
n_ttl_amt?: number;
|
||||||
|
prev_net?: number;
|
||||||
|
supp_amt?: number;
|
||||||
|
n_supp_amt?: number;
|
||||||
|
g_upd_amt?: number;
|
||||||
|
g_ttl_disc?: number;
|
||||||
|
g_tax?: number;
|
||||||
|
gst_amt?: number;
|
||||||
|
}
|
||||||
52
src/main/decoder/decode-ttl.ts
Normal file
52
src/main/decoder/decode-ttl.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import { DBFFile } from "dbffile";
|
||||||
|
import log from "electron-log/main";
|
||||||
|
import _ from "lodash";
|
||||||
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import { DecodedTtl, DecodedTtlLine } from "./decode-ttl.interface";
|
||||||
|
|
||||||
|
const DecodeTtl = async (
|
||||||
|
extensionlessFilePath: string
|
||||||
|
): Promise<DecodedTtl> => {
|
||||||
|
let dbf: DBFFile | null = null;
|
||||||
|
try {
|
||||||
|
dbf = await DBFFile.open(`${extensionlessFilePath}.TTL`);
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Error opening TTL File.", errorTypeCheck(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbf) {
|
||||||
|
log.error(`Could not find any TTL files at ${extensionlessFilePath}`);
|
||||||
|
throw new Error(`Could not find any TTL files at ${extensionlessFilePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawDBFRecord = await dbf.readRecords(1);
|
||||||
|
|
||||||
|
//PFT will always have only 1 row.
|
||||||
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
|
const rawTtlData: DecodedTtlLine = deepLowerCaseKeys(
|
||||||
|
_.pick(rawDBFRecord[0], [
|
||||||
|
//TODO: Add typings for EMS File Formats.
|
||||||
|
"G_TTL_AMT",
|
||||||
|
"G_BETT_AMT",
|
||||||
|
"G_RPD_AMT",
|
||||||
|
"G_DED_AMT",
|
||||||
|
"G_CUST_AMT",
|
||||||
|
"G_AA_AMT",
|
||||||
|
"N_TTL_AMT",
|
||||||
|
"PREV_NET",
|
||||||
|
"SUPP_AMT",
|
||||||
|
"N_SUPP_AMT", //Previously commented. Possible issue.
|
||||||
|
"G_UPD_AMT",
|
||||||
|
"G_TTL_DISC",
|
||||||
|
"G_TAX",
|
||||||
|
"GST_AMT",
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
//Apply business logic transfomrations.
|
||||||
|
|
||||||
|
return { clm_total: 0, depreciation_taxes: 0, cieca_ttl: rawTtlData };
|
||||||
|
};
|
||||||
|
export default DecodeTtl;
|
||||||
@@ -8,7 +8,7 @@ import errorTypeCheck from "../../util/errorTypeCheck";
|
|||||||
const DecodeVeh = async (
|
const DecodeVeh = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
): Promise<DecodedVeh> => {
|
): Promise<DecodedVeh> => {
|
||||||
let dbf: DBFFile;
|
let dbf: DBFFile | null = null;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}V.VEH`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}V.VEH`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -11,6 +11,16 @@ import DecodePfh from "./decode-pfh";
|
|||||||
import { DecodedPfh } from "./decode-pfh.interface";
|
import { DecodedPfh } from "./decode-pfh.interface";
|
||||||
import DecodePfl from "./decode-pfl";
|
import DecodePfl from "./decode-pfl";
|
||||||
import { DecodedPfl } from "./decode-pfl.interface";
|
import { DecodedPfl } from "./decode-pfl.interface";
|
||||||
|
import DecodePfm from "./decode-pfm";
|
||||||
|
import { DecodedPfm } from "./decode-pfm.interface";
|
||||||
|
import DecodePfo from "./decode-pfo";
|
||||||
|
import { DecodedPfo } from "./decode-pfo.interface";
|
||||||
|
import DecodePft from "./decode-pft";
|
||||||
|
import { DecodedPft } from "./decode-pft.interface";
|
||||||
|
import DecodeStl from "./decode-stl";
|
||||||
|
import { DecodedStl } from "./decode-stl.interface";
|
||||||
|
import DecodeTtl from "./decode-ttl";
|
||||||
|
import { DecodedTtl } from "./decode-ttl.interface";
|
||||||
import DecodeVeh from "./decode-veh";
|
import DecodeVeh from "./decode-veh";
|
||||||
import { DecodedVeh } from "./decode-veh.interface";
|
import { DecodedVeh } from "./decode-veh.interface";
|
||||||
|
|
||||||
@@ -31,7 +41,24 @@ async function ImportJob(filepath: string): Promise<void> {
|
|||||||
const lin: DecodedLin[] = await DecodeLin(extensionlessFilePath);
|
const lin: DecodedLin[] = await DecodeLin(extensionlessFilePath);
|
||||||
const pfh: DecodedPfh = await DecodePfh(extensionlessFilePath);
|
const pfh: DecodedPfh = await DecodePfh(extensionlessFilePath);
|
||||||
const pfl: DecodedPfl = await DecodePfl(extensionlessFilePath);
|
const pfl: DecodedPfl = await DecodePfl(extensionlessFilePath);
|
||||||
log.debug("EMS Object", { ad1, ad2, veh, lin, pfh, pfl });
|
const pft: DecodedPft = await DecodePft(extensionlessFilePath);
|
||||||
|
const pfm: DecodedPfm = await DecodePfm(extensionlessFilePath);
|
||||||
|
const pfo: DecodedPfo = await DecodePfo(extensionlessFilePath); // TODO: This will be the `cieca_pfo` object
|
||||||
|
const stl: DecodedStl[] = await DecodeStl(extensionlessFilePath); // TODO: This will be the `cieca_stl` object
|
||||||
|
const ttl: DecodedTtl = await DecodeTtl(extensionlessFilePath); //
|
||||||
|
log.debug("EMS Object", {
|
||||||
|
ad1,
|
||||||
|
ad2,
|
||||||
|
veh,
|
||||||
|
lin,
|
||||||
|
pfh,
|
||||||
|
pfl,
|
||||||
|
pft,
|
||||||
|
pfm,
|
||||||
|
pfo,
|
||||||
|
stl,
|
||||||
|
ttl,
|
||||||
|
});
|
||||||
} 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