import { DBFFile } from "dbffile"; import log from "electron-log/main"; import _ from "lodash"; import deepLowerCaseKeys from "../../util/deepLowercaseKeys"; import errorTypeCheck from "../../util/errorTypeCheck"; import store from "../store/store"; import { DecodedLin, DecodedLinLine } from "./decode-lin.interface"; import { platform } from "@electron-toolkit/utils"; import { findFileCaseInsensitive } from "./decoder-utils"; const DecodeLin = async ( extensionlessFilePath: string, ): Promise => { let dbf: DBFFile | null = null; if (platform.isWindows) { 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}`, ); } } else { const possibleExtensions: string[] = ["lin"]; const filePath = await findFileCaseInsensitive( extensionlessFilePath, possibleExtensions, ); try { if (!filePath) { log.error(`Could not find any LIN files at ${extensionlessFilePath}`); throw new Error( `Could not find any LIN files at ${extensionlessFilePath}`, ); } dbf = await DBFFile.open(filePath); } catch (error) { log.error("Error opening LIN File.", errorTypeCheck(error)); throw error; } } const rawDBFRecord = await dbf.readRecords(); //AD2 will always have only 1 row. //Commented lines have been cross referenced with existing partner fields. const opCodeData = store.get("app.masterdata.opcodes"); //TODO: Type the op codes const rawLinData: DecodedLinLine[] = rawDBFRecord.map((record) => { const singleLineData: DecodedLinLine = 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 = opCodeData[singleLineData.lbr_op]?.desc; return singleLineData; }); //Apply business logic transfomrations. //We don't have an inspection date, we instead have `date_estimated` return { joblines: { data: rawLinData } }; }; export default DecodeLin;