///<summary>Called from Eclaims and includes multiple claims.</summary> public static string SendBatch(Clearinghouse clearinghouseClin, List <ClaimSendQueueItem> queueItems, int batchNum) { //STEP 1 - Build XML output. List <DP_RACINDP> listDps = new List <DP_RACINDP>(); List <ProcedureCode> listProcCodes = ProcedureCodes.GetAllCodes(); List <Etrans> listEtrans = new List <Etrans>(); foreach (ClaimSendQueueItem queueItem in queueItems) { Etrans etrans = Etranss.SetClaimSentOrPrinted(queueItem.ClaimNum, queueItem.PatNum, clearinghouseClin.HqClearinghouseNum, EtransType.Claim_Ramq, batchNum, Security.CurUser.UserNum); listEtrans.Add(etrans); //Now we need to update our cache of claims to reflect the change that took place in the database above in Etranss.SetClaimSentOrPrinted() queueItem.ClaimStatus = "S"; Claim claim = Claims.GetClaim(queueItem.ClaimNum); Provider provClaimTreat = Providers.GetProv(claim.ProvTreat); DP_RACINDP dp = new DP_RACINDP(); #region Header dp.CHN = DP_RACINDPCHN.Item06; dp.CHNSpecified = true; dp.ENRG = DP_RACINDPENRG.Item1; dp.ENRGSpecified = true; //We hijack the TaxID number for the TRNSM field. The TRNSM is a office identifying number. Test range for developers is 18000 to 18999. dp.TRNSM = clearinghouseClin.SenderTIN; dp.DISP = provClaimTreat.NationalProvID; //dp.CPTE_ADMN=;//Administrative account number. Not currently used. JulianCalendar calendar = new JulianCalendar(); dp.ATTES = (DateTime.Now.Year % 10).ToString() //One digit for year + calendar.GetDayOfYear(DateTime.Now).ToString().PadLeft(3, '0') //3 digits for Julian day of year. + (etrans.CarrierTransCounter % 1000).ToString().PadLeft(3, '0'); //3 digits for sequence number. dp.NCE = (etrans.CarrierTransCounter % 10000).ToString().PadLeft(4, '0'); dp.DISP_REFNT = claim.CanadianReferralProviderNum.Trim(); //dp.DIAGN=;//Diagnostic code. Not currently used. dp.ETAB = provClaimTreat.CanadianOfficeNum; //Usually empty. //dp.ADMIS=;//Date of patient admission. Not currently used. This would be the same as the date of service for dental claims anyway. //dp.SORTI=;//Date patient discharged. Not currently used. This would be the same as the date of service for dental claims anyway. dp.TOT_DEM = claim.ClaimFee.ToString().Replace(".", "").PadLeft(6, '0'); dp.COMPL = TidyStr(claim.ClaimNote, 200); //dp.CS=;//Not sure what this is. Not currently used. //dp.AUTOR=claim.PreAuthString;//Authorization number when invoicing acrylic prostheses. Required if DAT_AUTOR is present. Not currently used. //dp.DAT_AUTOR=claim.CanadianDateInitialLower;//Date of authorization when invoicing acrylic prostheses. Format YYMMDD. Not currently used. dp.SERV = claim.DateService.ToString("yyMMdd"); #endregion Header #region Insurance //Most fields in the insuranace section are optional. InsSub insSub = InsSubs.GetOne(claim.InsSubNum); dp.PERS_ASSU = new DP_RACINDPPERS_ASSU(); dp.PERS_ASSU.NAM = insSub.SubscriberID; Patient pat = Patients.GetPat(claim.PatNum); dp.PERS_ASSU.PRE = TidyStr(pat.FName, 20); dp.PERS_ASSU.NOM = TidyStr(pat.LName, 30); if (pat.Birthdate.Year > 1880) { dp.PERS_ASSU.NAISS = pat.Birthdate.ToString("yyyyMMdd"); } if (pat.Gender == PatientGender.Male) { dp.PERS_ASSU.SEXE = DP_RACINDPPERS_ASSUSEXE.M; } else if (pat.Gender == PatientGender.Female) { dp.PERS_ASSU.SEXE = DP_RACINDPPERS_ASSUSEXE.F; } else { //There is no value for UNKNOWN. This field is optional if the subscriber ID is present anyway. } List <PatPlan> listPatPlans = PatPlans.Refresh(claim.PatNum); PatPlan patPlan = PatPlans.GetByInsSubNum(listPatPlans, insSub.InsSubNum); dp.PERS_ASSU.CAM = patPlan.PatID; if (insSub.DateTerm.Year > 1880) { dp.PERS_ASSU.EXPIR_CAM = insSub.DateTerm.ToString("yyMM"); } InsPlan insPlan = InsPlans.RefreshOne(claim.PlanNum); InsPlan insPlan2 = InsPlans.RefreshOne(claim.PlanNum2); Carrier carrier = null; if (claim.ClaimType == "S") { carrier = Carriers.GetCarrier(insPlan2.CarrierNum); } else { carrier = Carriers.GetCarrier(insPlan.CarrierNum); } if (carrier.Address.Trim() != "") { dp.PERS_ASSU.ADR_1 = carrier.Address; dp.PERS_ASSU.ADR_2 = carrier.Address2; dp.PERS_ASSU.CP = carrier.Zip; } #endregion Insurance #region Procedures List <ClaimProc> listClaimProcsForPat = ClaimProcs.Refresh(claim.PatNum); List <ClaimProc> listClaimProcsForClaim = ClaimProcs.GetForSendClaim(listClaimProcsForPat, claim.ClaimNum); //Excludes labs. List <Procedure> listProcsForPat = Procedures.Refresh(claim.PatNum); List <DP_RACINDPACTE> listProcs = new List <DP_RACINDPACTE>(); foreach (ClaimProc claimProc in listClaimProcsForClaim) { Procedure proc = Procedures.GetProcFromList(listProcsForPat, claimProc.ProcNum); if (proc.ProcFee == 0) { continue; } ProcedureCode procCode = ProcedureCodes.GetProcCode(proc.CodeNum, listProcCodes); if (procCode.NoBillIns) { continue; } DP_RACINDPACTE acteProc = new DP_RACINDPACTE(); acteProc.ACTE = procCode.ProcCode; if (procCode.ProcCode.Length > 5) { acteProc.ACTE = procCode.ProcCode.Substring(0, 5); } acteProc.ROLE = "1"; //1 for principal role and 2 for assistant role. //acte.MODIF=;//Optional. Not sure what to put here, so leaving blank for now. acteProc.UNIT = proc.UnitQty.ToString().PadLeft(3, '0'); acteProc.MNT = proc.ProcFee.ToString("F").Replace(".", "").PadLeft(6, '0'); acteProc.DENT = proc.ToothNum.ToString().PadLeft(2, '0'); acteProc.SURF = proc.Surf.ToString().PadLeft(2, '0'); listProcs.Add(acteProc); List <Procedure> listLabProcs = Procedures.GetCanadianLabFees(proc.ProcNum, listProcsForPat); foreach (Procedure labProc in listLabProcs) { if (labProc.ProcFee == 0) { continue; } ProcedureCode labProcCode = ProcedureCodes.GetProcCode(labProc.CodeNum, listProcCodes); DP_RACINDPACTE acteLab = new DP_RACINDPACTE(); acteLab.ACTE = labProcCode.ProcCode; if (labProcCode.ProcCode.Length > 5) { acteLab.ACTE = labProcCode.ProcCode.Substring(0, 5); } acteLab.ROLE = "1"; //1 for principal role and 2 for assistant role. acteLab.MNT = labProc.ProcFee.ToString("F").Replace(".", "").PadLeft(6, '0'); listProcs.Add(acteLab); } } dp.ACTE = listProcs.ToArray(); #endregion Procedures listDps.Add(dp); } DP_RACIN batch = new DP_RACIN(); batch.DP = listDps.ToArray(); StringWriter sw = new StringWriter(); XmlSerializer serializer = new XmlSerializer(typeof(DP_RACIN)); serializer.Serialize(sw, batch); string xml = sw.ToString(); //Save a copy of the batch xml to each etrans entry (one per claim). EtransMessageText etransMsgText = new EtransMessageText(); etransMsgText.MessageText = xml; EtransMessageTexts.Insert(etransMsgText); foreach (Etrans etrans in listEtrans) { etrans.EtransMessageTextNum = etransMsgText.EtransMessageTextNum; Etranss.Update(etrans); } //Step 2 - ZIP XML and save to report path. The zip file name and file name within the zip file do not matter. string zipFilePath = CodeBase.ODFileUtils.CreateRandomFile(clearinghouseClin.ExportPath, ".zip", "claims"); ZipFile zip = null; try { zip = new ZipFile(); zip.UseZip64WhenSaving = Zip64Option.Always; zip.AddEntry("claims" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xml", xml); zip.Save(zipFilePath); zip.Dispose(); } catch (Exception ex) { ex.ToString(); if (zip != null) { zip.Dispose(); } if (File.Exists(zipFilePath)) { try { File.Delete(zipFilePath); } catch (Exception ex2) { ex2.ToString(); } } } return(xml); }