From 6a8c84bcd5bc28fb8c5c3be4169677f502e9f7a5 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 29 Jan 2020 16:58:35 -0800 Subject: [PATCH] AD2 parsing, PFH parsing, PFL parsing. --- BodyshopUploader/BodyshopUploader.csproj | 1 + .../Utils/Decoder/EstimateDecoder.cs | 691 +++++++++++------- BodyshopUploader/Utils/JobProcessingQueue.cs | 7 +- BodyshopUploader/Utils/JsonExtensions.cs | 33 + Reference/CIECA Standard.xlsx | Bin 0 -> 15653 bytes 5 files changed, 464 insertions(+), 268 deletions(-) create mode 100644 BodyshopUploader/Utils/JsonExtensions.cs create mode 100644 Reference/CIECA Standard.xlsx diff --git a/BodyshopUploader/BodyshopUploader.csproj b/BodyshopUploader/BodyshopUploader.csproj index 3607c1d..4c37c65 100644 --- a/BodyshopUploader/BodyshopUploader.csproj +++ b/BodyshopUploader/BodyshopUploader.csproj @@ -281,6 +281,7 @@ + diff --git a/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs b/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs index c594ade..3f71912 100644 --- a/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs +++ b/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs @@ -30,8 +30,11 @@ namespace BodyshopUploader.Utils.Decoder string _dir = Path.GetDirectoryName(FilePath) + @"\"; ParseAd1File(ref ret, _dir); + ParseAd2File(ref ret, _dir); ParseVehFile(ref ret, _dir); - //ParseStlFile(ref ret, _dir); + ParsePfhFile(ref ret, _dir); + ParsePflFile(ref ret, _dir); + //ParseStlFile(ref ret, _dir); //Contains information about the total amounts of the estimate. //ParseTtlFile(ref ret, _dir); //ParseLinFile(ref ret, _dir); @@ -70,143 +73,143 @@ namespace BodyshopUploader.Utils.Decoder }); var readValues = reader.NextRecord(); - dynamic o = new JObject(); - + dynamic ownerRoot = new JObject(); - j.ins_co_id = readValues[0]?.ToString(); - j.ins_co_nm = readValues[1]?.ToString(); - j.ins_addr1 = readValues[2]?.ToString(); - j.ins_addr2 = readValues[3]?.ToString(); - j.ins_city = readValues[4]?.ToString(); - j.ins_st = readValues[5]?.ToString(); - j.ins_zip = readValues[6]?.ToString(); - j.ins_ctry = readValues[7]?.ToString(); - j.ins_ea = readValues[8]?.ToString(); - j.policy_no = readValues[9]?.ToString(); - j.ded_amt = readValues[10]?.ToString(); - j.ded_status = readValues[11]?.ToString(); - j.asgn_no = readValues[12]?.ToString(); - j.asgn_date = readValues[13]?.ToString(); - j.asgn_type = readValues[14]?.ToString(); - j.clm_no = readValues[15]?.ToString(); - j.clm_ofc_id = readValues[16]?.ToString(); - j.clm_ofc_nm = readValues[17]?.ToString(); - j.clm_addr1 = readValues[18]?.ToString(); - j.clm_addr2 = readValues[19]?.ToString(); - j.clm_city = readValues[20]?.ToString(); - j.clm_st = readValues[21]?.ToString(); - j.clm_zip = readValues[22]?.ToString(); - j.clm_ctry = readValues[23]?.ToString(); - j.clm_ph1 = readValues[24]?.ToString(); - j.clm_ph1x = readValues[25]?.ToString(); - j.clm_ph2 = readValues[26]?.ToString(); - j.clm_ph2x = readValues[27]?.ToString(); - j.clm_fax = readValues[28]?.ToString(); - j.clm_faxx = readValues[29]?.ToString(); - j.clm_ct_ln = readValues[30]?.ToString(); - j.clm_ct_fn = readValues[31]?.ToString(); - j.clm_title = readValues[32]?.ToString(); - j.clm_ct_ph = readValues[33]?.ToString(); - j.clm_ct_phx = readValues[34]?.ToString(); - j.clm_ea = readValues[35]?.ToString(); - j.payee_nms = readValues[36]?.ToString(); - j.pay_type = readValues[37]?.ToString(); - j.pay_date = readValues[38]?.ToString(); - j.pay_chknm = readValues[39]?.ToString(); - j.pay_amt = readValues[40]?.ToString(); - j.agt_co_id = readValues[41]?.ToString(); - j.agt_co_nm = readValues[42]?.ToString(); - j.agt_addr1 = readValues[43]?.ToString(); - j.agt_addr2 = readValues[44]?.ToString(); - j.agt_city = readValues[45]?.ToString(); - j.agt_st = readValues[46]?.ToString(); - j.agt_zip = readValues[47]?.ToString(); - j.agt_ctry = readValues[48]?.ToString(); - j.agt_ph1 = readValues[49]?.ToString(); - j.agt_ph1x = readValues[50]?.ToString(); - j.agt_ph2 = readValues[51]?.ToString(); - j.agt_ph2x = readValues[52]?.ToString(); - j.agt_fax = readValues[53]?.ToString(); - j.agt_faxx = readValues[54]?.ToString(); - j.agt_ct_ln = readValues[55]?.ToString(); - j.agt_ct_fn = readValues[56]?.ToString(); - j.agt_ct_ph = readValues[57]?.ToString(); - j.agt_ct_phx = readValues[58]?.ToString(); - j.agt_ea = readValues[59]?.ToString(); - j.agt_lic_no = readValues[60]?.ToString(); - j.loss_date = readValues[61]?.ToString(); - j.loss_type = readValues[62]?.ToString(); - j.loss_desc = readValues[63]?.ToString(); - j.theft_ind = readValues[64]?.ToString(); //BOOL - j.cat_no = readValues[65]?.ToString(); - j.tlos_ind = readValues[66]?.ToString(); - j.cust_pr = readValues[67]?.ToString(); - j.insd_ln = readValues[68]?.ToString(); - j.insd_fn = readValues[69]?.ToString(); - j.insd_title = readValues[70]?.ToString(); - j.insd_co_nm = readValues[71]?.ToString(); - j.insd_addr1 = readValues[72]?.ToString(); - j.insd_addr2 = readValues[73]?.ToString(); - j.insd_city = readValues[74]?.ToString(); - j.insd_st = readValues[75]?.ToString(); - j.insd_zip = readValues[76]?.ToString(); - j.insd_ctry = readValues[77]?.ToString(); - j.insd_ph1 = readValues[78]?.ToString(); - j.insd_ph1x = readValues[79]?.ToString(); - j.insd_ph2 = readValues[80]?.ToString(); - j.insd_ph2x = readValues[81]?.ToString(); - j.insd_fax = readValues[82]?.ToString(); - j.insd_faxx = readValues[83]?.ToString(); - j.insd_ea = readValues[84]?.ToString(); - j.ownr_ln = readValues[85]?.ToString(); - j.ownr_fn = readValues[86]?.ToString(); - j.ownr_title = readValues[87]?.ToString(); - j.ownr_co_nm = readValues[88]?.ToString(); - j.ownr_addr1 = readValues[89]?.ToString(); - j.ownr_addr2 = readValues[90]?.ToString(); - j.ownr_city = readValues[91]?.ToString(); - j.ownr_st = readValues[92]?.ToString(); - j.ownr_zip = readValues[93]?.ToString(); - j.ownr_ctry = readValues[94]?.ToString(); - j.ownr_ph1 = readValues[95]?.ToString(); - //j.ownr_ph1x = readValues[96]?.ToString(); - j.ownr_ph2 = readValues[97]?.ToString(); - // j.ownr_ph2x = readValues[98]?.ToString(); - //j.ownr_fax = readValues[99]?.ToString(); - //j.ownr_faxx = readValues[100]?.ToString(); - j.ownr_ea = readValues[101]?.ToString(); - j.ins_ph1 = readValues[102]?.ToString(); - j.ins_ph1x = readValues[103]?.ToString(); - j.ins_ph2 = readValues[104]?.ToString(); - j.ins_ph2x = readValues[105]?.ToString(); - j.ins_fax = readValues[106]?.ToString(); - j.ins_faxx = readValues[107]?.ToString(); - j.ins_ct_ln = readValues[108]?.ToString(); - j.ins_ct_fn = readValues[109]?.ToString(); - j.ins_title = readValues[110]?.ToString(); - j.ins_ct_ph = readValues[111]?.ToString(); - j.ins_ct_phx = readValues[112]?.ToString(); - j.loss_cat = readValues[113]?.ToString(); + j.ins_co_id = readValues[0]; + j.ins_co_nm = readValues[1]; + j.ins_addr1 = readValues[2]; + j.ins_addr2 = readValues[3]; + j.ins_city = readValues[4]; + j.ins_st = readValues[5]; + j.ins_zip = readValues[6]; + j.ins_ctry = readValues[7]; + j.ins_ea = readValues[8]; + j.policy_no = readValues[9]; + j.ded_amt = readValues[10]; + j.ded_status = readValues[11]; + j.asgn_no = readValues[12]; + j.asgn_date = readValues[13]; + j.asgn_type = readValues[14]; + j.clm_no = readValues[15]; + j.clm_ofc_id = readValues[16]; + j.clm_ofc_nm = readValues[17]; + j.clm_addr1 = readValues[18]; + j.clm_addr2 = readValues[19]; + j.clm_city = readValues[20]; + j.clm_st = readValues[21]; + j.clm_zip = readValues[22]; + j.clm_ctry = readValues[23]; + j.clm_ph1 = readValues[24]; + j.clm_ph1x = readValues[25]; + j.clm_ph2 = readValues[26]; + j.clm_ph2x = readValues[27]; + j.clm_fax = readValues[28]; + j.clm_faxx = readValues[29]; + j.clm_ct_ln = readValues[30]; + j.clm_ct_fn = readValues[31]; + j.clm_title = readValues[32]; + j.clm_ct_ph = readValues[33]; + j.clm_ct_phx = readValues[34]; + j.clm_ea = readValues[35]; + j.payee_nms = readValues[36]; + j.pay_type = readValues[37]; + j.pay_date = readValues[38]; + j.pay_chknm = readValues[39]; + j.pay_amt = readValues[40]; + j.agt_co_id = readValues[41]; + j.agt_co_nm = readValues[42]; + j.agt_addr1 = readValues[43]; + j.agt_addr2 = readValues[44]; + j.agt_city = readValues[45]; + j.agt_st = readValues[46]; + j.agt_zip = readValues[47]; + j.agt_ctry = readValues[48]; + j.agt_ph1 = readValues[49]; + j.agt_ph1x = readValues[50]; + j.agt_ph2 = readValues[51]; + j.agt_ph2x = readValues[52]; + j.agt_fax = readValues[53]; + j.agt_faxx = readValues[54]; + j.agt_ct_ln = readValues[55]; + j.agt_ct_fn = readValues[56]; + j.agt_ct_ph = readValues[57]; + j.agt_ct_phx = readValues[58]; + j.agt_ea = readValues[59]; + j.agt_lic_no = readValues[60]; + j.loss_date = readValues[61]; + j.loss_type = readValues[62]; + j.loss_desc = readValues[63]; + j.theft_ind = readValues[64]; //BOOL + j.cat_no = readValues[65]; + j.tlos_ind = readValues[66]; + j.cust_pr = readValues[67]; + j.insd_ln = readValues[68]; + j.insd_fn = readValues[69]; + j.insd_title = readValues[70]; + j.insd_co_nm = readValues[71]; + j.insd_addr1 = readValues[72]; + j.insd_addr2 = readValues[73]; + j.insd_city = readValues[74]; + j.insd_st = readValues[75]; + j.insd_zip = readValues[76]; + j.insd_ctry = readValues[77]; + j.insd_ph1 = readValues[78]; + j.insd_ph1x = readValues[79]; + j.insd_ph2 = readValues[80]; + j.insd_ph2x = readValues[81]; + j.insd_fax = readValues[82]; + j.insd_faxx = readValues[83]; + j.insd_ea = readValues[84]; + j.ownr_ln = readValues[85]; + j.ownr_fn = readValues[86]; + j.ownr_title = readValues[87]; + j.ownr_co_nm = readValues[88]; + j.ownr_addr1 = readValues[89]; + j.ownr_addr2 = readValues[90]; + j.ownr_city = readValues[91]; + j.ownr_st = readValues[92]; + j.ownr_zip = readValues[93]; + j.ownr_ctry = readValues[94]; + j.ownr_ph1 = readValues[95]; + //j.ownr_ph1x = readValues[96]; + j.ownr_ph2 = readValues[97]; + // j.ownr_ph2x = readValues[98]; + //j.ownr_fax = readValues[99]; + //j.ownr_faxx = readValues[100]; + j.ownr_ea = readValues[101]; + j.ins_ph1 = readValues[102]; + j.ins_ph1x = readValues[103]; + j.ins_ph2 = readValues[104]; + j.ins_ph2x = readValues[105]; + j.ins_fax = readValues[106]; + j.ins_faxx = readValues[107]; + j.ins_ct_ln = readValues[108]; + j.ins_ct_fn = readValues[109]; + j.ins_title = readValues[110]; + j.ins_ct_ph = readValues[111]; + j.ins_ct_phx = readValues[112]; + j.loss_cat = readValues[113]; j.shopid = AppMetaData.ActiveShopId; //Set Owner Record - o.ownr_ln = readValues[85]?.ToString(); - o.ownr_fn = readValues[86]?.ToString(); - o.ownr_title = readValues[87]?.ToString(); - o.ownr_co_nm = readValues[88]?.ToString(); - o.ownr_addr1 = readValues[89]?.ToString(); - o.ownr_addr2 = readValues[90]?.ToString(); - o.ownr_city = readValues[91]?.ToString(); - o.ownr_st = readValues[92]?.ToString(); - o.ownr_zip = readValues[93]?.ToString(); - o.ownr_ctry = readValues[94]?.ToString(); - o.ownr_ph1 = readValues[95]?.ToString(); - o.ownr_ph2 = readValues[97]?.ToString(); - o.ownr_ea = readValues[101]?.ToString(); - o.shopid = AppMetaData.ActiveShopId; + //Owner record will be removed by the application if required. + ownerRoot.ownr_ln = readValues[85]; + ownerRoot.ownr_fn = readValues[86]; + ownerRoot.ownr_title = readValues[87]; + ownerRoot.ownr_co_nm = readValues[88]; + ownerRoot.ownr_addr1 = readValues[89]; + ownerRoot.ownr_addr2 = readValues[90]; + ownerRoot.ownr_city = readValues[91]; + ownerRoot.ownr_st = readValues[92]; + ownerRoot.ownr_zip = readValues[93]; + ownerRoot.ownr_ctry = readValues[94]; + ownerRoot.ownr_ph1 = readValues[95]; + ownerRoot.ownr_ph2 = readValues[97]; + ownerRoot.ownr_ea = readValues[101]; + ownerRoot.shopid = AppMetaData.ActiveShopId; j.owner = new JObject(); - j.owner.data = o; + j.owner.data = ownerRoot; return; } } @@ -234,147 +237,137 @@ namespace BodyshopUploader.Utils.Decoder { try { - using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + "A.ad2", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + "B.ad2", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var reader = new DBFReader(fis); + //RO_AUTH references a memo file and had to be reemoved. + reader.SetSelectFields(new string[] { "CLMT_LN","CLMT_FN","CLMT_TITLE","CLMT_CO_NM","CLMT_ADDR1","CLMT_ADDR2","CLMT_CITY","CLMT_ST","CLMT_ZIP","CLMT_CTRY","CLMT_PH1", +"CLMT_PH1X","CLMT_PH2","CLMT_PH2X","CLMT_FAX","CLMT_FAXX","CLMT_EA","EST_CO_ID","EST_CO_NM","EST_ADDR1","EST_ADDR2","EST_CITY","EST_ST","EST_ZIP","EST_CTRY","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","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" - reader.SetSelectFields(new string[] { "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" }); var readValues = reader.NextRecord(); - j.ins_co_id = readValues[0]?.ToString(); - j.ins_co_nm = readValues[1]?.ToString(); - j.ins_addr1 = readValues[2]?.ToString(); - j.ins_addr2 = readValues[3]?.ToString(); - j.ins_city = readValues[4]?.ToString(); - j.ins_st = readValues[5]?.ToString(); - j.ins_zip = readValues[6]?.ToString(); - j.ins_ctry = readValues[7]?.ToString(); - j.ins_ea = readValues[8]?.ToString(); - j.policy_no = readValues[9]?.ToString(); - j.ded_amt = readValues[10]?.ToString(); - j.ded_status = readValues[11]?.ToString(); - j.asgn_no = readValues[12]?.ToString(); - j.asgn_date = readValues[13]?.ToString(); - j.asgn_type = readValues[14]?.ToString(); - j.clm_no = readValues[15]?.ToString(); - j.clm_ofc_id = readValues[16]?.ToString(); - j.clm_ofc_nm = readValues[17]?.ToString(); - j.clm_addr1 = readValues[18]?.ToString(); - j.clm_addr2 = readValues[19]?.ToString(); - j.clm_city = readValues[20]?.ToString(); - j.clm_st = readValues[21]?.ToString(); - j.clm_zip = readValues[22]?.ToString(); - j.clm_ctry = readValues[23]?.ToString(); - j.clm_ph1 = readValues[24]?.ToString(); - j.clm_ph1x = readValues[25]?.ToString(); - j.clm_ph2 = readValues[26]?.ToString(); - j.clm_ph2x = readValues[27]?.ToString(); - j.clm_fax = readValues[28]?.ToString(); - j.clm_faxx = readValues[29]?.ToString(); - j.clm_ct_ln = readValues[30]?.ToString(); - j.clm_ct_fn = readValues[31]?.ToString(); - j.clm_title = readValues[32]?.ToString(); - j.clm_ct_ph = readValues[33]?.ToString(); - j.clm_ct_phx = readValues[34]?.ToString(); - j.clm_ea = readValues[35]?.ToString(); - j.payee_nms = readValues[36]?.ToString(); - j.pay_type = readValues[37]?.ToString(); - j.pay_date = readValues[38]?.ToString(); - j.pay_chknm = readValues[39]?.ToString(); - j.pay_amt = readValues[40]?.ToString(); - j.agt_co_id = readValues[41]?.ToString(); - j.agt_co_nm = readValues[42]?.ToString(); - j.agt_addr1 = readValues[43]?.ToString(); - j.agt_addr2 = readValues[44]?.ToString(); - j.agt_city = readValues[45]?.ToString(); - j.agt_st = readValues[46]?.ToString(); - j.agt_zip = readValues[47]?.ToString(); - j.agt_ctry = readValues[48]?.ToString(); - j.agt_ph1 = readValues[49]?.ToString(); - j.agt_ph1x = readValues[50]?.ToString(); - j.agt_ph2 = readValues[51]?.ToString(); - j.agt_ph2x = readValues[52]?.ToString(); - j.agt_fax = readValues[53]?.ToString(); - j.agt_faxx = readValues[54]?.ToString(); - j.agt_ct_ln = readValues[55]?.ToString(); - j.agt_ct_fn = readValues[56]?.ToString(); - j.agt_ct_ph = readValues[57]?.ToString(); - j.agt_ct_phx = readValues[58]?.ToString(); - j.agt_ea = readValues[59]?.ToString(); - j.agt_lic_no = readValues[60]?.ToString(); - j.loss_date = readValues[61]?.ToString(); - j.loss_type = readValues[62]?.ToString(); - j.loss_desc = readValues[63]?.ToString(); - j.theft_ind = readValues[64]?.ToString(); //BOOL - j.cat_no = readValues[65]?.ToString(); - j.tlos_ind = readValues[66]?.ToString(); - j.cust_pr = readValues[67]?.ToString(); - j.insd_ln = readValues[68]?.ToString(); - j.insd_fn = readValues[69]?.ToString(); - j.insd_title = readValues[70]?.ToString(); - j.insd_co_nm = readValues[71]?.ToString(); - j.insd_addr1 = readValues[72]?.ToString(); - j.insd_addr2 = readValues[73]?.ToString(); - j.insd_city = readValues[74]?.ToString(); - j.insd_st = readValues[75]?.ToString(); - j.insd_zip = readValues[76]?.ToString(); - j.insd_ctry = readValues[77]?.ToString(); - j.insd_ph1 = readValues[78]?.ToString(); - j.insd_ph1x = readValues[79]?.ToString(); - j.insd_ph2 = readValues[80]?.ToString(); - j.insd_ph2x = readValues[81]?.ToString(); - j.insd_fax = readValues[82]?.ToString(); - j.insd_faxx = readValues[82]?.ToString(); - j.insd_ea = readValues[83]?.ToString(); - j.ownr_ln = readValues[84]?.ToString(); - j.ownr_fn = readValues[85]?.ToString(); - j.ownr_title = readValues[86]?.ToString(); - j.ownr_co_nm = readValues[87]?.ToString(); - j.ownr_addr1 = readValues[88]?.ToString(); - j.ownr_addr2 = readValues[89]?.ToString(); - j.ownr_city = readValues[90]?.ToString(); - j.ownr_st = readValues[91]?.ToString(); - j.ownr_zip = readValues[92]?.ToString(); - j.ownr_ctry = readValues[93]?.ToString(); - j.ownr_ph1 = readValues[94]?.ToString(); - j.ownr_ph1x = readValues[95]?.ToString(); - j.ownr_ph2 = readValues[96]?.ToString(); - j.ownr_ph2x = readValues[97]?.ToString(); - j.ownr_fax = readValues[98]?.ToString(); - j.ownr_faxx = readValues[99]?.ToString(); - j.ownr_ea = readValues[100]?.ToString(); - j.ins_ph1 = readValues[101]?.ToString(); - j.ins_ph1x = readValues[102]?.ToString(); - j.ins_ph2 = readValues[103]?.ToString(); - j.ins_ph2x = readValues[104]?.ToString(); - j.ins_fax = readValues[105]?.ToString(); - j.ins_faxx = readValues[106]?.ToString(); - j.ins_ct_ln = readValues[107]?.ToString(); - j.ins_ct_fn = readValues[108]?.ToString(); - j.ins_title = readValues[109]?.ToString(); - j.ins_ct_ph = readValues[110]?.ToString(); - j.ins_ct_phx = readValues[111]?.ToString(); - j.loss_cat = readValues[112]?.ToString(); - j.shopid = AppMetaData.ActiveShopId; + //j.clmt_ln = readValues[0];//CLMT_LN + //j.clmt_fn = readValues[1];//CLMT_FN + //j.clmt_title = readValues[2];//CLMT_TITLE + //j.clmt_co_nm = readValues[3];//CLMT_CO_NM + //j.clmt_addr1 = readValues[4];//CLMT_ADDR1 + //j.clmt_addr2 = readValues[5];//CLMT_ADDR2 + //j.clmt_city = readValues[6];//CLMT_CITY + //j.clmt_st = readValues[7];//CLMT_ST + //j.clmt_zip = readValues[8];//CLMT_ZIP + //j.clmt_ctry = readValues[9];//CLMT_CTRY + //j.clmt_ph1 = readValues[10];//CLMT_PH1 + //j.clmt_ph1x = readValues[11];//CLMT_PH1X + //j.clmt_ph2 = readValues[12];//CLMT_PH2 + //j.clmt_ph2x = readValues[13];//CLMT_PH2X + //j.clmt_fax = readValues[14];//CLMT_FAX + //j.clmt_faxx = readValues[15];//CLMT_FAXX + //j.clmt_ea = readValues[16];//CLMT_EA + //j.est_co_id = readValues[17];//EST_CO_ID + j.est_co_nm = readValues[18];//EST_CO_NM + j.est_addr1 = readValues[19];//EST_ADDR1 + j.est_addr2 = readValues[20];//EST_ADDR2 + j.est_city = readValues[21];//EST_CITY + j.est_st = readValues[22];//EST_ST + j.est_zip = readValues[23];//EST_ZIP + j.est_ctry = readValues[24];//EST_CTRY + j.est_ph1 = readValues[25];//EST_PH1 + //j.est_ph1x = readValues[26];//EST_PH1X + //j.est_ph2 = readValues[27];//EST_PH2 + //j.est_ph2x = readValues[28];//EST_PH2X + //j.est_fax = readValues[29];//EST_FAX + //j.est_faxx = readValues[30];//EST_FAXX + j.est_ct_ln = readValues[31];//EST_CT_LN + j.est_ct_fn = readValues[32];//EST_CT_FN + j.est_ea = readValues[33];//EST_EA + //j.est_lic_no = readValues[34];//EST_LIC_NO + //j.est_fileno = readValues[35];//EST_FILENO + //j.insp_ct_ln = readValues[36];//INSP_CT_LN + //j.insp_ct_fn = readValues[37];//INSP_CT_FN + //j.insp_addr1 = readValues[38];//INSP_ADDR1 + //j.insp_addr2 = readValues[39];//INSP_ADDR2 + //j.insp_city = readValues[40];//INSP_CITY + //j.insp_st = readValues[41];//INSP_ST + //j.insp_zip = readValues[42];//INSP_ZIP + //j.insp_ctry = readValues[43];//INSP_CTRY + //j.insp_ph1 = readValues[44];//INSP_PH1 + //j.insp_ph1x = readValues[45];//INSP_PH1X + //j.insp_ph2 = readValues[46];//INSP_PH2 + //j.insp_ph2x = readValues[47];//INSP_PH2X + //j.insp_fax = readValues[48];//INSP_FAX + //j.insp_faxx = readValues[49];//INSP_FAXX + //j.insp_ea = readValues[50];//INSP_EA + //j.insp_code = readValues[51];//INSP_CODE + //j.insp_desc = readValues[52];//INSP_DESC + //j.insp_date = readValues[53];//INSP_DATE + //j.insp_time = readValues[54];//INSP_TIME + //j.rf_co_id = readValues[55];//RF_CO_ID + //j.rf_co_nm = readValues[56];//RF_CO_NM + //j.rf_addr1 = readValues[57];//RF_ADDR1 + //j.rf_addr2 = readValues[58];//RF_ADDR2 + //j.rf_city = readValues[59];//RF_CITY + //j.rf_st = readValues[60];//RF_ST + //j.rf_zip = readValues[61];//RF_ZIP + //j.rf_ctry = readValues[62];//RF_CTRY + //j.rf_ph1 = readValues[63];//RF_PH1 + //j.rf_ph1x = readValues[64];//RF_PH1X + //j.rf_ph2 = readValues[65];//RF_PH2 + //j.rf_ph2x = readValues[66];//RF_PH2X + //j.rf_fax = readValues[67];//RF_FAX + //j.rf_faxx = readValues[68];//RF_FAXX + //j.rf_ct_ln = readValues[69];//RF_CT_LN + //j.rf_ct_fn = readValues[70];//RF_CT_FN + //j.rf_ea = readValues[71];//RF_EA + //j.rf_tax_id = readValues[72];//RF_TAX_ID + //j.rf_lic_no = readValues[73];//RF_LIC_NO + //j.rf_bar_no = readValues[74];//RF_BAR_NO + //j.ro_in_date = readValues[75];//RO_IN_DATE + //j.ro_in_time = readValues[76];//RO_IN_TIME + //j.tar_date = readValues[77];//TAR_DATE + //j.tar_time = readValues[78];//TAR_TIME + //j.ro_cmpdate = readValues[79];//RO_CMPDATE + //j.ro_cmptime = readValues[80];//RO_CMPTIME + //j.date_out = readValues[81];//DATE_OUT + //j.time_out = readValues[82];//TIME_OUT + //j.rf_estimtr = readValues[83];//RF_ESTIMTR + //j.mktg_type = readValues[84];//MKTG_TYPE + //j.mktg_src = readValues[85];//MKTG_SRC + //j.loc_nm = readValues[86];//LOC_NM + //j.loc_addr1 = readValues[87];//LOC_ADDR1 + //j.loc_addr2 = readValues[88];//LOC_ADDR2 + //j.loc_city = readValues[89];//LOC_CITY + //j.loc_st = readValues[90];//LOC_ST + //j.loc_zip = readValues[91];//LOC_ZIP + //j.loc_ctry = readValues[92];//LOC_CTRY + //j.loc_ph1 = readValues[93];//LOC_PH1 + //j.loc_ph1x = readValues[94];//LOC_PH1X + //j.loc_ph2 = readValues[95];//LOC_PH2 + //j.loc_ph2x = readValues[96];//LOC_PH2X + //j.loc_fax = readValues[97];//LOC_FAX + //j.loc_faxx = readValues[98];//LOC_FAXX + //j.loc_ct_ln = readValues[99];//LOC_CT_LN + //j.loc_ct_fn = readValues[100];//LOC_CT_FN + //j.loc_title = readValues[101];//LOC_TITLE + //j.loc_ph = readValues[102];//LOC_PH + //j.loc_phx = readValues[103];//LOC_PHX + //j.loc_ea = readValues[104];//LOC_EA + + + return; } } catch (IOException ex) { - logger.Trace(ex, "Unable to open AD1 file. Retrying. "); + logger.Trace(ex, "Unable to open AD2 file. Retrying. "); retryNumber++; Thread.Sleep(3000); } @@ -383,6 +376,175 @@ namespace BodyshopUploader.Utils.Decoder } + public static void ParsePfhFile(ref dynamic j, string RootFilePath) + { + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) + { + return; + } + logger.Trace(@"Parsing PFH at: {0}{1}", RootFilePath, j.ciecaid.Value); + + int retryNumber = 0; + while (retryNumber < 11) + { + try + { + using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + ".pfh", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + var reader = new DBFReader(fis); + reader.SetSelectFields(new string[] { "ID_PRO_NAM","TAX_PRETHR","TAX_THRAMT","TAX_PSTTHR","TAX_TOW_IN","TAX_TOW_RT","TAX_STR_IN","TAX_STR_RT","TAX_SUB_IN","TAX_SUB_RT", + "TAX_BTR_IN","TAX_LBR_RT","TAX_GST_RT","TAX_GST_IN","ADJ_G_DISC","ADJ_TOWDIS","ADJ_STRDIS","ADJ_BTR_IN","TAX_PREDIS", + }); + var readValues = reader.NextRecord(); + + //Values divided by 100 to make consistent. + + //j.id_pro_nam = readValues[0];//ID_PRO_NAM + //j.tax_prethr = readValues[1];//TAX_PRETHR + //j.tax_thramt = readValues[2];//TAX_THRAMT + //j.tax_pstthr = float.Parse(readValues[3].ToString())/100;//TAX_PSTTHR //PST for Parts + //j.tax_tow_in = readValues[4];//TAX_TOW_IN + j.tax_tow_rt = (bool)readValues[4] ? float.Parse(readValues[5].ToString()) / 100 : 0;//TAX_TOW_RT + //j.tax_str_in = readValues[6];//TAX_STR_IN + //j.tax_str_rt = readValues[7];//TAX_STR_RT + //j.tax_sub_in = readValues[8];//TAX_SUB_IN + //j.tax_sub_rt = (bool)readValues[8] ? float.Parse(readValues[9].ToString()) / 100 : 0;//TAX_SUB_RT + //j.tax_btr_in = readValues[10];//TAX_BTR_IN + //j.tax_lbr_rt = readValues[11];//TAX_LBR_RT + j.federal_tax_rate = float.Parse(readValues[12].ToString()) / 100;//TAX_GST_RT + //j.tax_gst_in = readValues[13];//TAX_GST_IN + //j.adj_g_disc = readValues[14];//ADJ_G_DISC + //j.adj_towdis = readValues[15];//ADJ_TOWDIS + //j.adj_strdis = readValues[16];//ADJ_STRDIS + //j.adj_btr_in = readValues[17];//ADJ_BTR_IN + //j.tax_predis = readValues[18];//TAX_PREDIS + + return; + } + } + catch (IOException ex) + { + logger.Trace(ex, "Unable to open PFH file. Retrying. "); + retryNumber++; + Thread.Sleep(3000); + } + } + } + + public static void ParsePflFile(ref dynamic j, string RootFilePath) + { + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) + { + return; + } + logger.Trace(@"Parsing PFl at: {0}{1}", RootFilePath, j.ciecaid.Value); + + int retryNumber = 0; + while (retryNumber < 11) + { + try + { + using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + ".pfl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + var reader = new DBFReader(fis); + reader.SetSelectFields(new string[] { "LBR_TYPE", + "LBR_DESC", + "LBR_RATE", + "LBR_TAX_IN", + "LBR_TAXP", + "LBR_ADJP", + "LBR_TX_TY1", + "LBR_TX_IN1", + "LBR_TX_TY2", + "LBR_TX_IN2", + "LBR_TX_TY3", + "LBR_TX_IN3", + "LBR_TX_TY4", + "LBR_TX_IN4", + "LBR_TX_TY5", + "LBR_TX_IN5" + }); + for (int i = 0; i < reader.RecordCount; i++) + { + var readValues = reader.NextRecord(); + switch (readValues[0].ToString())//Case switch on LBR_TYPE to assign correctly. + { + case "LAB": + j.rate_lab = readValues[2]; + break; + case "LAD": + j.rate_lad = readValues[2]; + break; + case "LAS": + j.rate_las = readValues[2]; + break; + case "LAR": + j.rate_lar = readValues[2]; + break; + case "LAE": + j.rate_lae = readValues[2]; + break; + case "LAG": + j.rate_lag = readValues[2]; + break; + case "LAF": + j.rate_laf = readValues[2]; + break; + case "LAM": + j.rate_lam = readValues[2]; + break; + case "LAU": + j.rate_lau = readValues[2]; + break; + case "LA1": + j.rate_la1 = readValues[2]; + break; + case "LA2": + j.rate_la2 = readValues[2]; + break; + case "LA3": + j.rate_la3 = readValues[2]; + break; + case "LA4": + j.rate_la4 = readValues[2]; + break; + default: + logger.Error("Unknown type value present in PFL file. {0}:{1}", readValues[0].ToString(), readValues[2]); + break; + } + } + + + //j.lbr_type = readValues[0];//LBR_TYPE + //j.lbr_desc = readValues[1];//LBR_DESC + //j.lbr_rate = readValues[2];//LBR_RATE + //j.lbr_tax_in = readValues[3];//LBR_TAX_IN + //j.lbr_taxp = readValues[4];//LBR_TAXP + //j.lbr_adjp = readValues[5];//LBR_ADJP + //j.lbr_tx_ty1 = readValues[6];//LBR_TX_TY1 + //j.lbr_tx_in1 = readValues[7];//LBR_TX_IN1 + //j.lbr_tx_ty2 = readValues[8];//LBR_TX_TY2 + //j.lbr_tx_in2 = readValues[9];//LBR_TX_IN2 + //j.lbr_tx_ty3 = readValues[10];//LBR_TX_TY3 + //j.lbr_tx_in3 = readValues[11];//LBR_TX_IN3 + //j.lbr_tx_ty4 = readValues[12];//LBR_TX_TY4 + //j.lbr_tx_in4 = readValues[13];//LBR_TX_IN4 + //j.lbr_tx_ty5 = readValues[14];//LBR_TX_TY5 + //j.lbr_tx_in5 = readValues[15];//LBR_TX_IN5 + + + return; + } + } + catch (IOException ex) + { + logger.Trace(ex, "Unable to open PFl file. Retrying. "); + retryNumber++; + Thread.Sleep(3000); + } + } + } + public static void ParseVehFile(ref dynamic j, string RootFilePath) { if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } @@ -397,7 +559,7 @@ namespace BodyshopUploader.Utils.Decoder using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + "v.veh", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { dynamic v = new JObject(); - + //V_Options references a memo file and had to be removed var reader = new DBFReader(fis); reader.SetSelectFields(new string[] { "IMPACT_1", "IMPACT_2", @@ -411,7 +573,7 @@ namespace BodyshopUploader.Utils.Decoder "V_MAKECODE", "V_MAKEDESC", "V_MODEL", - "V_TYPE", + "V_TYPE", "V_BSTYLE", "V_TRIMCODE", "TRIM_COLOR", @@ -450,7 +612,6 @@ namespace BodyshopUploader.Utils.Decoder v.trim_color = readValues[15]?.ToString(); v.v_mldgcode = readValues[16]?.ToString(); v.v_engine = readValues[17]?.ToString(); - // v.v_options = readValues[18]?.ToString(); v.v_color = readValues[18]?.ToString(); v.v_tone = readValues[19]?.ToString(); v.v_stage = readValues[20]?.ToString(); @@ -512,8 +673,6 @@ namespace BodyshopUploader.Utils.Decoder logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.ciecaid.Value); - - int retryNumber = 0; while (retryNumber < 11) { diff --git a/BodyshopUploader/Utils/JobProcessingQueue.cs b/BodyshopUploader/Utils/JobProcessingQueue.cs index bc2ff97..29bfb34 100644 --- a/BodyshopUploader/Utils/JobProcessingQueue.cs +++ b/BodyshopUploader/Utils/JobProcessingQueue.cs @@ -87,6 +87,9 @@ namespace BodyshopUploader.Utils { //TODO: This should perform some sort of upsert to update the vehicle with more up to date information. + //Strip out what isn't needed by replacing it with nulls to save DB space. + //https://stackoverflow.com/questions/29475467/when-merging-objects-using-newtonsoft-json-how-do-you-ignore-empty-string-value + ((JObject)item.Job).RemovePropertiesByValue(v => v.Type == JTokenType.String && string.IsNullOrEmpty((string)v.Value)); //Add to Holding Queue @@ -95,9 +98,9 @@ namespace BodyshopUploader.Utils newJob.bodyshopid = AppMetaData.ActiveShopId; newJob.cieca_id = item.Job.ciecaid; newJob.est_data = item.Job; - newJob.ownr_name = item.Job.ownr_fn.Value + " " + item.Job.ownr_ln.Value; + newJob.ownr_name = item.Job.ownr_fn?.Value + " " + item.Job.ownr_ln?.Value; newJob.vehicle_info = item.Job.vehicle.data.v_model_yr.Value + " " + item.Job.vehicle.data.v_make_desc.Value + " " + item.Job.vehicle.data.v_model_desc.Value; - newJob.clm_no = item.Job.clm_no.Value; + newJob.clm_no = item.Job.clm_no?.Value; var vehuuid = await Utils.Queries.VehicleQueries.GetVehicleUuidByVin(item?.Job?.vehicle?.data?.v_vin.Value ?? ""); if (!string.IsNullOrEmpty(vehuuid)) diff --git a/BodyshopUploader/Utils/JsonExtensions.cs b/BodyshopUploader/Utils/JsonExtensions.cs new file mode 100644 index 0000000..0500193 --- /dev/null +++ b/BodyshopUploader/Utils/JsonExtensions.cs @@ -0,0 +1,33 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BodyshopUploader.Utils +{ + public static class JsonExtensions + { + public static void RemovePropertiesByValue(this JToken root, Predicate filter) + { + var nulls = root.DescendantsAndSelf().OfType().Where(v => v.Parent is JProperty && filter(v)).ToList(); + foreach (var value in nulls) + { + var parent = (JProperty)value.Parent; + parent.Remove(); + } + } + + public static IEnumerable DescendantsAndSelf(this JToken node) + { + if (node == null) + return Enumerable.Empty(); + var container = node as JContainer; + if (container != null) + return container.DescendantsAndSelf(); + else + return new[] { node }; + } + } +} diff --git a/Reference/CIECA Standard.xlsx b/Reference/CIECA Standard.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..638bf93301503a6f0df0d03bc63dbb532da57bfa GIT binary patch literal 15653 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 literal 0 HcmV?d00001