public void ProcedureCodes_GetSubstituteCodeNum_InsPlanOverrideNever() { //First, setup the test scenario. string suffix = MethodBase.GetCurrentMethod().Name; Patient pat = PatientT.CreatePatient(suffix); Carrier carrier = CarrierT.CreateCarrier(MethodBase.GetCurrentMethod().Name); InsPlan plan = new InsPlan(); plan.CarrierNum = carrier.CarrierNum; plan.PlanType = ""; plan.CobRule = EnumCobRule.Basic; plan.PlanNum = InsPlans.Insert(plan); //Add a substitution code on the procedure level that has SubstitutionCondition.Never. ProcedureCode originalProcCode = ProcedureCodes.GetProcCode("D2330"); //clear out any substitution codes on this procedure originalProcCode.SubstitutionCode = ""; ProcedureCodeT.Update(originalProcCode); //Add an override for the inplan above for the originalProcCode to never substitute ProcedureCode downgradeProcCodeForIns = ProcedureCodes.GetProcCode("D2150"); SubstitutionLinkT.CreateSubstitutionLink(originalProcCode.CodeNum, downgradeProcCodeForIns.ProcCode, SubstitutionCondition.Never, plan.PlanNum); //Next, perform the thing you're trying to test. Procedure proc = ProcedureT.CreateProcedure(pat, originalProcCode.ProcCode, ProcStat.C, "9", 100);//Tooth 9 long subCodeNum = ProcedureCodes.GetSubstituteCodeNum(originalProcCode.ProcCode, proc.ToothNum, plan.PlanNum); //The procedure level and ins override is set SubstitutionCondition.Never so it should use originalProcCode.CodeNum Assert.AreEqual(originalProcCode.CodeNum, subCodeNum); }
public void ProcedureCodes_GetSubstituteCodeNum_InsPlanOverridePosterior() { //First, setup the test scenario. string suffix = MethodBase.GetCurrentMethod().Name; Patient pat = PatientT.CreatePatient(suffix); Carrier carrier = CarrierT.CreateCarrier(MethodBase.GetCurrentMethod().Name); InsPlan plan = new InsPlan(); plan.CarrierNum = carrier.CarrierNum; plan.PlanType = ""; plan.CobRule = EnumCobRule.Basic; plan.PlanNum = InsPlans.Insert(plan); //Procedure code does not have a substitution code ProcedureCode originalProcCode = ProcedureCodes.GetProcCode("D2740"); //clear out any substitution codes on this procedure originalProcCode.SubstitutionCode = ""; ProcedureCodeT.Update(originalProcCode); //Add an override for the inplan above for the originalProcCode to substitute if posterior ProcedureCode downgradeProcCodeForIns = ProcedureCodes.GetProcCode("D2750"); SubstitutionLinkT.CreateSubstitutionLink(originalProcCode.CodeNum, downgradeProcCodeForIns.ProcCode, SubstitutionCondition.Posterior, plan.PlanNum); //Posterior procedure Procedure proc = ProcedureT.CreateProcedure(pat, originalProcCode.ProcCode, ProcStat.C, "4", 100);//Tooth 4 long subCodeNum = ProcedureCodes.GetSubstituteCodeNum(originalProcCode.ProcCode, proc.ToothNum, plan.PlanNum); //The ins override is set to substitute only if posterior. Assert.AreEqual(downgradeProcCodeForIns.CodeNum, subCodeNum); }
public void InsPlan_PpoNoSubWriteoffsNoSub() { string suffix = MethodBase.GetCurrentMethod().Name; Patient pat = PatientT.CreatePatient(suffix); long ucrFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "UCR Fees" + suffix); long ppoFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "PPO " + suffix); InsuranceInfo ins = InsuranceT.AddInsurance(pat, suffix, planType: "p", feeSchedNum: ppoFeeSchedNum); ins.PriInsPlan.HasPpoSubstWriteoffs = false; InsPlans.Update(ins.PriInsPlan); BenefitT.CreateCategoryPercent(ins.PriInsPlan.PlanNum, EbenefitCategory.Restorative, 50); ProcedureCode originalProcCode = ProcedureCodes.GetProcCode("D2330"); ProcedureCode downgradeProcCode = ProcedureCodes.GetProcCode("D2140"); originalProcCode.SubstitutionCode = ""; //NOT substituting originalProcCode.SubstOnlyIf = SubstitutionCondition.Always; ProcedureCodeT.Update(originalProcCode); FeeT.CreateFee(ucrFeeSchedNum, originalProcCode.CodeNum, 100); FeeT.CreateFee(ucrFeeSchedNum, downgradeProcCode.CodeNum, 80); FeeT.CreateFee(ppoFeeSchedNum, originalProcCode.CodeNum, 60); FeeT.CreateFee(ppoFeeSchedNum, downgradeProcCode.CodeNum, 50); Procedure proc = ProcedureT.CreateProcedure(pat, "D2330", ProcStat.C, "9", 100);//Tooth 9 List <ClaimProc> listClaimProcs = ClaimProcs.Refresh(pat.PatNum); List <Procedure> listProcs = Procedures.Refresh(pat.PatNum); ins.RefreshBenefits(); Claim claim = ClaimT.CreateClaim("P", ins.ListPatPlans, ins.ListInsPlans, listClaimProcs, listProcs, pat, listProcs, ins.ListBenefits, ins.ListInsSubs); ClaimProc clProc = ClaimProcs.Refresh(pat.PatNum)[0]; //Should only be one Assert.AreEqual(50, clProc.Percentage); Assert.AreEqual(30, clProc.BaseEst); Assert.AreEqual(30, clProc.InsPayEst); Assert.AreEqual(40, clProc.WriteOffEst); }
public void ProcedureCodes_GetSubstituteCodeNum_InsPlanOverrideAlways() { //First, setup the test scenario. string suffix = MethodBase.GetCurrentMethod().Name; Patient pat = PatientT.CreatePatient(suffix); Carrier carrier = CarrierT.CreateCarrier(MethodBase.GetCurrentMethod().Name); InsPlan plan = new InsPlan(); plan.CarrierNum = carrier.CarrierNum; plan.PlanType = ""; plan.CobRule = EnumCobRule.Basic; plan.PlanNum = InsPlans.Insert(plan); //Add a substitution code on the procedure level. ProcedureCode originalProcCode = ProcedureCodes.GetProcCode("D2330"); ProcedureCode downgradeProcCode = ProcedureCodes.GetProcCode("D2140"); originalProcCode.SubstitutionCode = "D2140"; originalProcCode.SubstOnlyIf = SubstitutionCondition.Always; ProcedureCodeT.Update(originalProcCode); //Add an override for the inplan above for the originalProcCode ProcedureCode downgradeProcCodeForIns = ProcedureCodes.GetProcCode("D2150"); SubstitutionLinkT.CreateSubstitutionLink(originalProcCode.CodeNum, downgradeProcCodeForIns.ProcCode, SubstitutionCondition.Always, plan.PlanNum); //Next, perform the thing you're trying to test. Procedure proc = ProcedureT.CreateProcedure(pat, originalProcCode.ProcCode, ProcStat.C, "9", 100);//Tooth 9 long subCodeNum = ProcedureCodes.GetSubstituteCodeNum(originalProcCode.ProcCode, proc.ToothNum, plan.PlanNum); //Finally, use one or more asserts to verify the results. Assert.AreEqual(downgradeProcCodeForIns.CodeNum, subCodeNum); }
///<summary>Creates a procedure and returns its procedure fee.</summary> private double GetProcFee(string suffix, bool doUseMedicalCode) { Prefs.UpdateBool(PrefName.InsPpoAlwaysUseUcrFee, true); Prefs.UpdateBool(PrefName.MedicalFeeUsedForNewProcs, doUseMedicalCode); Patient pat = PatientT.CreatePatient(suffix); long ucrFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "UCR " + suffix); FeeSchedT.UpdateUCRFeeSched(pat, ucrFeeSchedNum); long ppoFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "PPO " + suffix); InsuranceT.AddInsurance(pat, suffix, "p", ppoFeeSchedNum, 1, true); List <InsSub> listSubs = InsSubT.GetInsSubs(pat); List <InsPlan> listPlans = InsPlans.RefreshForSubList(listSubs); List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum); string procStr = "D0150"; string procStrMed = "D0120"; ProcedureCode procCode = ProcedureCodes.GetProcCode(procStr); ProcedureCode procCodeMed = ProcedureCodes.GetProcCode(procStrMed); procCode.MedicalCode = procCodeMed.ProcCode; FeeT.CreateFee(ucrFeeSchedNum, procCode.CodeNum, 300); FeeT.CreateFee(ppoFeeSchedNum, procCode.CodeNum, 120); FeeT.CreateFee(ucrFeeSchedNum, procCodeMed.CodeNum, 175); FeeT.CreateFee(ppoFeeSchedNum, procCodeMed.CodeNum, 85); Procedure proc = ProcedureT.CreateProcedure(pat, procStr, ProcStat.TP, "", 300); return(Procedures.GetProcFee(pat, listPatPlans, listSubs, listPlans, procCode.CodeNum, proc.ProvNum, proc.ClinicNum, procCode.MedicalCode)); }
public void FeeSchedTools_GlobalUpdateWriteoffEstimates_SubscriberInDifferentFamily() { string suffix = MethodBase.GetCurrentMethod().Name; string procStr = "D0145"; double procFee = 100; ProcedureCode procCode = ProcedureCodes.GetProcCode(procStr); //Set up clinic, prov, pat Clinic clinic = ClinicT.CreateClinic(suffix); long feeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, suffix); long provNum = ProviderT.CreateProvider(suffix, feeSchedNum: feeSchedNum); Fee fee = FeeT.GetNewFee(feeSchedNum, procCode.CodeNum, procFee, clinic.ClinicNum, provNum); Patient pat = PatientT.CreatePatient(suffix, provNum, clinic.ClinicNum); Patient patSubscriber = PatientT.CreatePatient(suffix + "_Subscriber", provNum, clinic.ClinicNum); //Set up insurance InsuranceInfo info = InsuranceT.AddInsurance(pat, suffix, "p", feeSchedNum); info.PriInsSub.Subscriber = patSubscriber.PatNum; InsSubs.Update(info.PriInsSub); info.ListBenefits.Add(BenefitT.CreatePercentForProc(info.PriInsPlan.PlanNum, procCode.CodeNum, 100)); //Create the procedure and claimproc Procedure proc = ProcedureT.CreateProcedure(pat, procStr, ProcStat.TP, "", procFee); ClaimProc priClaimProc = ClaimProcT.CreateClaimProc(pat.PatNum, proc.ProcNum, info.PriInsPlan.PlanNum, info.PriInsSub.InsSubNum, DateTime.Today, -1, -1, -1, ClaimProcStatus.CapEstimate); Procedures.ComputeEstimates(proc, pat.PatNum, new List <ClaimProc>(), true, info.ListInsPlans, info.ListPatPlans, info.ListBenefits, pat.Age, info.ListInsSubs); priClaimProc = ClaimProcs.Refresh(pat.PatNum).FirstOrDefault(x => x.ProcNum == proc.ProcNum); Assert.AreEqual(procFee, priClaimProc.InsPayEst); GlobalUpdateWriteoffs(clinic.ClinicNum); priClaimProc = ClaimProcs.Refresh(pat.PatNum).FirstOrDefault(x => x.ClaimProcNum == priClaimProc.ClaimProcNum); Assert.AreEqual(procFee, priClaimProc.InsPayEst); }
///<summary>Creates a procedure and computes estimates for a patient where the secondary insurance has a COB rule of Medicaid.</summary> private void ComputeEstimatesMedicaidCOB(string suffix, double procFee, double priAllowed, double secAllowed, int priPercentCovered, int secPercentCovered, Action <ClaimProc /*Primary*/, ClaimProc /*Secondary*/, Procedure> assertAct) { Patient pat = PatientT.CreatePatient(suffix); long ppoFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "PPO " + suffix); InsuranceT.AddInsurance(pat, suffix, "p", ppoFeeSchedNum); long medicaidFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "PPO " + suffix); InsuranceT.AddInsurance(pat, suffix, "p", medicaidFeeSchedNum, 2, cobRule: EnumCobRule.SecondaryMedicaid); List <InsSub> listSubs = InsSubT.GetInsSubs(pat); List <InsPlan> listPlans = InsPlans.RefreshForSubList(listSubs); List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum); InsPlan priPlan = InsPlanT.GetPlanForPriSecMed(PriSecMed.Primary, listPatPlans, listPlans, listSubs); BenefitT.CreateCategoryPercent(priPlan.PlanNum, EbenefitCategory.Diagnostic, priPercentCovered); InsPlan secPlan = InsPlanT.GetPlanForPriSecMed(PriSecMed.Secondary, listPatPlans, listPlans, listSubs); BenefitT.CreateCategoryPercent(secPlan.PlanNum, EbenefitCategory.Diagnostic, secPercentCovered); List <Benefit> listBens = Benefits.Refresh(listPatPlans, listSubs); string procStr = "D0150"; Procedure proc = ProcedureT.CreateProcedure(pat, procStr, ProcStat.TP, "", procFee); ProcedureCode procCode = ProcedureCodes.GetProcCode(procStr); FeeT.CreateFee(ppoFeeSchedNum, procCode.CodeNum, priAllowed); FeeT.CreateFee(medicaidFeeSchedNum, procCode.CodeNum, secAllowed); Procedures.ComputeEstimates(proc, pat.PatNum, new List <ClaimProc>(), false, listPlans, listPatPlans, listBens, pat.Age, listSubs); List <ClaimProc> listClaimProcs = ClaimProcs.Refresh(pat.PatNum); assertAct(listClaimProcs.FirstOrDefault(x => x.PlanNum == priPlan.PlanNum), listClaimProcs.FirstOrDefault(x => x.PlanNum == secPlan.PlanNum), proc); }
public void FeeSchedTools_GlobalUpdateFees() { PrefT.UpdateBool(PrefName.MedicalFeeUsedForNewProcs, false); string suffix = MethodBase.GetCurrentMethod().Name; string procStr = "D0120"; string procStr2 = "D0145"; double procFee = 100; ProcedureCode procCode = ProcedureCodes.GetProcCode(procStr); ProcedureCode procCode2 = ProcedureCodes.GetProcCode(procStr2); //Set up clinic, prov, pat Clinic clinic = ClinicT.CreateClinic(suffix); long feeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, suffix, false); long provNum = ProviderT.CreateProvider(suffix, feeSchedNum: feeSchedNum); Fee fee = FeeT.GetNewFee(feeSchedNum, procCode.CodeNum, procFee, clinic.ClinicNum, provNum); Fee fee2 = FeeT.GetNewFee(feeSchedNum, procCode2.CodeNum, procFee, clinic.ClinicNum, provNum); Patient pat = PatientT.CreatePatient(suffix, provNum, clinic.ClinicNum); //Chart a procedure for this proccode/pat as well as a different proccode Procedure proc = ProcedureT.CreateProcedure(pat, procStr, ProcStat.TP, "", fee.Amount); Procedure proc2 = ProcedureT.CreateProcedure(pat, procStr2, ProcStat.TP, "", fee2.Amount); //Update the fee amount for only the D0120 code fee.Amount = 50; Fees.Update(fee); //Now run global update fees Procedures.GlobalUpdateFees(Fees.GetByClinicNum(clinic.ClinicNum), clinic.ClinicNum, clinic.Abbr); //Make sure we have the same number of updated fees, and fee amounts for both procs proc = Procedures.GetOneProc(proc.ProcNum, false); proc2 = Procedures.GetOneProc(proc2.ProcNum, false); Assert.AreEqual(fee.Amount, proc.ProcFee); Assert.AreEqual(fee2.Amount, proc2.ProcFee); }
public void ProcedureCodes_GetSubstituteCodeNum_Posterior() { //First, setup the test scenario. string suffix = MethodBase.GetCurrentMethod().Name; Patient pat = PatientT.CreatePatient(suffix); Carrier carrier = CarrierT.CreateCarrier(MethodBase.GetCurrentMethod().Name); InsPlan plan = new InsPlan(); plan.CarrierNum = carrier.CarrierNum; plan.PlanType = ""; plan.CobRule = EnumCobRule.Basic; plan.PlanNum = InsPlans.Insert(plan); //Add a substitution code on the procedure level. ProcedureCode originalProcCode = ProcedureCodes.GetProcCode("D2740"); ProcedureCode downgradeProcCode = ProcedureCodes.GetProcCode("D2750"); originalProcCode.SubstitutionCode = "D2750"; originalProcCode.SubstOnlyIf = SubstitutionCondition.Posterior; ProcedureCodeT.Update(originalProcCode); //Posterior Procedure= ToothNum 4 Procedure proc = ProcedureT.CreateProcedure(pat, originalProcCode.ProcCode, ProcStat.C, "4", 100);//Tooth 4 long subCodeNum = ProcedureCodes.GetSubstituteCodeNum(originalProcCode.ProcCode, proc.ToothNum, plan.PlanNum); //Finally, use one or more asserts to verify the results. Assert.AreEqual(downgradeProcCode.CodeNum, subCodeNum); }
public static string ClearDb() { string command = @" DELETE FROM carrier; DELETE FROM claim; DELETE FROM claimproc; DELETE FROM fee; DELETE FROM feesched WHERE FeeSchedNum !=53; /*because this is the default fee schedule for providers*/ DELETE FROM insplan; DELETE FROM patient; DELETE FROM patplan; DELETE FROM procedurelog; DELETE FROM etrans; " ; DataCore.NonQ(command); ProcedureCodes.RefreshCache(); ProcedureCode procCode; if (!ProcedureCodes.IsValidCode("99222")) { procCode = new ProcedureCode(); procCode.ProcCode = "99222"; procCode.Descript = "Lab2"; procCode.AbbrDesc = "Lab2"; procCode.IsCanadianLab = true; procCode.ProcCat = 256; procCode.ProcTime = "/X/"; procCode.TreatArea = TreatmentArea.Mouth; ProcedureCodes.Insert(procCode); ProcedureCodes.RefreshCache(); } procCode = ProcedureCodes.GetProcCode("99111"); procCode.IsCanadianLab = true; ProcedureCodes.Update(procCode); ProcedureCodes.RefreshCache(); if (!ProcedureCodes.IsValidCode("27213")) { procCode = new ProcedureCode(); procCode.ProcCode = "27213"; procCode.Descript = "Crown"; procCode.AbbrDesc = "Crn"; procCode.ProcCat = 250; procCode.ProcTime = "/X/"; procCode.TreatArea = TreatmentArea.Tooth; procCode.PaintType = ToothPaintingType.CrownLight; ProcedureCodes.Insert(procCode); ProcedureCodes.RefreshCache(); } procCode = ProcedureCodes.GetProcCode("67211"); procCode.TreatArea = TreatmentArea.Quad; ProcedureCodes.Update(procCode); ProcedureCodes.RefreshCache(); return("Database cleared of old data.\r\n"); }
private static Claim CreatePredetermination(Patient pat, List <Procedure> procList, long provTreat) { Family fam = Patients.GetFamily(pat.PatNum); List <InsSub> subList = InsSubs.RefreshForFam(fam); List <InsPlan> planList = InsPlans.RefreshForSubList(subList); List <PatPlan> patPlanList = PatPlans.Refresh(pat.PatNum); List <Benefit> benefitList = Benefits.Refresh(patPlanList, subList); List <ClaimProc> claimProcList = ClaimProcs.Refresh(pat.PatNum); List <Procedure> procsForPat = Procedures.Refresh(pat.PatNum); InsSub sub = InsSubs.GetSub(PatPlans.GetInsSubNum(patPlanList, 1), subList); InsPlan insPlan = InsPlans.GetPlan(sub.PlanNum, planList); Claim claim = new Claim(); Claims.Insert(claim); //to retreive a key for new Claim.ClaimNum claim.PatNum = pat.PatNum; claim.DateService = procList[0].ProcDate; claim.DateSent = DateTime.Today; claim.ClaimStatus = "W"; claim.InsSubNum = PatPlans.GetInsSubNum(patPlanList, 1); claim.InsSubNum2 = PatPlans.GetInsSubNum(patPlanList, 2); InsSub sub1 = InsSubs.GetSub(claim.InsSubNum, subList); InsSub sub2 = InsSubs.GetSub(claim.InsSubNum, subList); claim.PlanNum = sub1.PlanNum; claim.PlanNum2 = sub2.PlanNum; claim.PatRelat = PatPlans.GetRelat(patPlanList, 1); claim.PatRelat2 = PatPlans.GetRelat(patPlanList, 2); claim.ClaimType = "PreAuth"; claim.ProvTreat = provTreat; claim.IsProsthesis = "N"; claim.ProvBill = Providers.GetBillingProvNum(claim.ProvTreat, 0); claim.EmployRelated = YN.No; ClaimProc cp; List <Procedure> procListClaim = new List <Procedure>(); //this list will exclude lab fees for (int i = 0; i < procList.Count; i++) { if (procList[i].ProcNumLab == 0) { procListClaim.Add(procList[i]); } } for (int i = 0; i < procListClaim.Count; i++) { cp = new ClaimProc(); ClaimProcs.CreateEst(cp, procListClaim[i], insPlan, sub); cp.ClaimNum = claim.ClaimNum; cp.Status = ClaimProcStatus.NotReceived; cp.CodeSent = ProcedureCodes.GetProcCode(procListClaim[i].CodeNum).ProcCode; cp.LineNumber = (byte)(i + 1); ClaimProcs.Update(cp); } claimProcList = ClaimProcs.Refresh(pat.PatNum); ClaimL.CalculateAndUpdate(procsForPat, planList, claim, patPlanList, benefitList, pat.Age, subList); return(claim); }
public static void SetComplete(Procedure proc, Patient pat, List <InsPlan> planList, List <PatPlan> patPlanList, List <ClaimProc> claimProcList, List <Benefit> benefitList, List <InsSub> subList) { Procedure procOld = proc.Copy(); ProcedureCode procCode = ProcedureCodes.GetProcCode(proc.CodeNum); proc.DateEntryC = DateTime.Now; proc.ProcStatus = ProcStat.C; Procedures.Update(proc, procOld); Procedures.ComputeEstimates(proc, proc.PatNum, claimProcList, false, planList, patPlanList, benefitList, pat.Age, subList); }
///<summary>Financial transaction segment.</summary> private void FT1(List <Procedure> listProcs, bool justPDF) { if (justPDF) { return; //FT1 segment is not necessary when sending only a PDF. } ProcedureCode procCode; for (int i = 0; i < listProcs.Count; i++) { seg = new SegmentHL7(SegmentNameHL7.FT1); seg.SetField(0, "FT1"); seg.SetField(1, (i + 1).ToString()); seg.SetField(4, listProcs[i].ProcDate.ToString("yyyyMMdd")); seg.SetField(5, listProcs[i].ProcDate.ToString("yyyyMMdd")); seg.SetField(6, "CG"); seg.SetField(10, "1.0"); seg.SetField(16, ""); //location code and description??? seg.SetField(19, listProcs[i].DiagnosticCode); Provider prov = Providers.GetProv(listProcs[i].ProvNum); seg.SetField(20, prov.EcwID, prov.LName, prov.FName, prov.MI); //performed by provider. seg.SetField(21, prov.EcwID, prov.LName, prov.FName, prov.MI); //ordering provider. seg.SetField(22, listProcs[i].ProcFee.ToString("F2")); procCode = ProcedureCodes.GetProcCode(listProcs[i].CodeNum); if (procCode.ProcCode.Length > 5 && procCode.ProcCode.StartsWith("D")) { seg.SetField(25, procCode.ProcCode.Substring(0, 5)); //Remove suffix from all D codes. } else { seg.SetField(25, procCode.ProcCode); } if (procCode.TreatArea == TreatmentArea.ToothRange) { seg.SetField(26, listProcs[i].ToothRange, ""); } else if (procCode.TreatArea == TreatmentArea.Surf) //probably not necessary { seg.SetField(26, Tooth.ToInternat(listProcs[i].ToothNum), Tooth.SurfTidyForClaims(listProcs[i].Surf, listProcs[i].ToothNum)); } //this property will not exist if using Oracle, eCW will never use Oracle else if (procCode.TreatArea == TreatmentArea.Quad && ProgramProperties.GetPropVal(Programs.GetProgramNum(ProgramName.eClinicalWorks), "IsQuadAsToothNum") == "1") { seg.SetField(26, listProcs[i].Surf, ""); } else { seg.SetField(26, Tooth.ToInternat(listProcs[i].ToothNum), listProcs[i].Surf); } msg.Segments.Add(seg); } }
private static string gProcCode(Procedure proc) { string retVal = ""; ProcedureCode procCode = ProcedureCodes.GetProcCode(proc.CodeNum); if (procCode.ProcCode.Length > 5 && procCode.ProcCode.StartsWith("D")) { retVal = procCode.ProcCode.Substring(0, 5); //Remove suffix from all D codes. } else { retVal = procCode.ProcCode; } return(retVal); }
///<summary>Financial transaction segment.</summary> private void FT1(long aptNum, bool justPDF) { if (justPDF) { return; //FT1 segment is not necessary when sending only a PDF. } List <Procedure> procs = Procedures.GetProcsForSingle(aptNum, false); ProcedureCode procCode; for (int i = 0; i < procs.Count; i++) { seg = new SegmentHL7(SegmentNameHL7.FT1); seg.SetField(0, "FT1"); seg.SetField(1, (i + 1).ToString()); seg.SetField(4, procs[i].ProcDate.ToString("yyyyMMddHHmmss")); seg.SetField(5, procs[i].ProcDate.ToString("yyyyMMddHHmmss")); seg.SetField(6, "CG"); seg.SetField(10, "1.0"); seg.SetField(16, ""); //location code and description??? seg.SetField(19, procs[i].DiagnosticCode); Provider prov = Providers.GetProv(procs[i].ProvNum); seg.SetField(20, prov.EcwID, prov.LName, prov.FName, prov.MI); //performed by provider. seg.SetField(21, prov.EcwID, prov.LName, prov.FName, prov.MI); //ordering provider. seg.SetField(22, procs[i].ProcFee.ToString("F2")); procCode = ProcedureCodes.GetProcCode(procs[i].CodeNum); if (procCode.ProcCode.Length > 5 && procCode.ProcCode.StartsWith("D")) { seg.SetField(25, procCode.ProcCode.Substring(0, 5)); //Remove suffix from all D codes. } else { seg.SetField(25, procCode.ProcCode); } if (procCode.TreatArea == TreatmentArea.ToothRange) { seg.SetField(26, procs[i].ToothRange, ""); } else if (procCode.TreatArea == TreatmentArea.Surf) //probably not necessary { seg.SetField(26, Tooth.ToInternat(procs[i].ToothNum), Tooth.SurfTidyForClaims(procs[i].Surf, procs[i].ToothNum)); } else { seg.SetField(26, Tooth.ToInternat(procs[i].ToothNum), procs[i].Surf); } msg.Segments.Add(seg); } }
public void Claims_CalculateAndUpdate_ProcedureCodeDowngradeHigherFee() { string suffix = "61"; Patient pat = PatientT.CreatePatient(suffix); long ucrFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "UCR Fees" + suffix); long ppoFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "PPO Downgrades" + suffix); Carrier carrier = CarrierT.CreateCarrier(suffix); InsPlan plan = InsPlanT.CreateInsPlan(carrier.CarrierNum); InsSub sub = InsSubT.CreateInsSub(pat.PatNum, plan.PlanNum); long subNum = sub.InsSubNum; BenefitT.CreateCategoryPercent(plan.PlanNum, EbenefitCategory.Restorative, 100); PatPlanT.CreatePatPlan(1, pat.PatNum, subNum); ProcedureCode originalProcCode = ProcedureCodes.GetProcCode("D2391"); ProcedureCode downgradeProcCode = ProcedureCodes.GetProcCode("D2140"); originalProcCode.SubstitutionCode = "D2140"; originalProcCode.SubstOnlyIf = SubstitutionCondition.Always; ProcedureCodes.Update(originalProcCode); FeeT.CreateFee(ucrFeeSchedNum, originalProcCode.CodeNum, 140); FeeT.CreateFee(ucrFeeSchedNum, downgradeProcCode.CodeNum, 120); FeeT.CreateFee(ppoFeeSchedNum, originalProcCode.CodeNum, 80); FeeT.CreateFee(ppoFeeSchedNum, downgradeProcCode.CodeNum, 100); Procedure proc = ProcedureT.CreateProcedure(pat, "D2391", ProcStat.C, "1", 140);//Tooth 1 List <ClaimProc> claimProcs = ClaimProcs.Refresh(pat.PatNum); List <ClaimProc> claimProcListOld = new List <ClaimProc>(); Family fam = Patients.GetFamily(pat.PatNum); List <InsSub> subList = InsSubs.RefreshForFam(fam); List <InsPlan> planList = InsPlans.RefreshForSubList(subList); List <PatPlan> patPlans = PatPlans.Refresh(pat.PatNum); List <Benefit> benefitList = Benefits.Refresh(patPlans, subList); List <Procedure> ProcList = Procedures.Refresh(pat.PatNum); InsPlan insPlan = planList[0];//Should only be one InsPlan planOld = insPlan.Copy(); insPlan.PlanType = "p"; insPlan.FeeSched = ppoFeeSchedNum; InsPlans.Update(insPlan, planOld); //Creates the claim in the same manner as the account module, including estimates. Claim claim = ClaimT.CreateClaim("P", patPlans, planList, claimProcs, ProcList, pat, ProcList, benefitList, subList); ClaimProc clProc = ClaimProcs.Refresh(pat.PatNum)[0]; //Should only be one Assert.AreEqual(80, clProc.InsEstTotal); Assert.AreEqual(60, clProc.WriteOff); }
private static string gTreatArea(string componentSep, Procedure proc) { string retVal = ""; ProcedureCode procCode = ProcedureCodes.GetProcCode(proc.CodeNum); if (procCode.TreatArea == TreatmentArea.ToothRange) { retVal = proc.ToothRange; } else if (procCode.TreatArea == TreatmentArea.Surf) //probably not necessary { retVal = gConcat(componentSep, Tooth.ToInternat(proc.ToothNum), Tooth.SurfTidyForClaims(proc.Surf, proc.ToothNum)); } else { retVal = gConcat(componentSep, Tooth.ToInternat(proc.ToothNum), proc.Surf); } return(retVal); }
public void FeeSchedTools_GlobalUpdateWriteoffEstimates() { string suffix = MethodBase.GetCurrentMethod().Name; string procStr = "D0145"; double procFee = 100; ProcedureCode procCode = ProcedureCodes.GetProcCode(procStr); //Set up clinic, prov, pat Clinic clinic = ClinicT.CreateClinic(suffix); long feeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.FixedBenefit, suffix); long provNum = ProviderT.CreateProvider(suffix, feeSchedNum: feeSchedNum); Fee fee = FeeT.GetNewFee(feeSchedNum, procCode.CodeNum, procFee, clinic.ClinicNum, provNum); Patient pat = PatientT.CreatePatient(suffix, provNum, clinic.ClinicNum); //Set up insurance InsuranceInfo info = InsuranceT.AddInsurance(pat, suffix, "c", feeSchedNum); List <InsSub> listSubs = info.ListInsSubs; List <InsPlan> listPlans = info.ListInsPlans; List <PatPlan> listPatPlans = info.ListPatPlans; InsPlan priPlan = info.PriInsPlan; InsSub priSub = info.PriInsSub; info.ListBenefits.Add(BenefitT.CreatePercentForProc(priPlan.PlanNum, procCode.CodeNum, 90)); //Create the procedure and claimproc Procedure proc = ProcedureT.CreateProcedure(pat, procStr, ProcStat.TP, "", procFee); ClaimProc priClaimProc = ClaimProcT.CreateClaimProc(pat.PatNum, proc.ProcNum, priPlan.PlanNum, priSub.InsSubNum, DateTime.Today, -1, -1, -1, ClaimProcStatus.CapEstimate); Procedures.ComputeEstimates(proc, pat.PatNum, new List <ClaimProc>(), true, listPlans, listPatPlans, info.ListBenefits, pat.Age, info.ListInsSubs); priClaimProc = ClaimProcs.Refresh(pat.PatNum).FirstOrDefault(x => x.ProcNum == proc.ProcNum); Assert.AreEqual(procFee, priClaimProc.WriteOff); procFee = 50; Procedure procNew = proc.Copy(); procNew.ProcFee = procFee; Procedures.Update(procNew, proc); //GlobalUpdate long updated = GlobalUpdateWriteoffs(clinic.ClinicNum); Assert.AreEqual(1, updated); ClaimProc priClaimProcDb = ClaimProcs.Refresh(pat.PatNum).FirstOrDefault(x => x.ClaimProcNum == priClaimProc.ClaimProcNum); Assert.AreEqual(procFee, priClaimProcDb.WriteOff); }
public void Procedures_ComputeEstimates_PrimaryInsuranceMedicaidCOB() { string suffix = MethodBase.GetCurrentMethod().Name; Patient pat = PatientT.CreatePatient(suffix); long ppoFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "PPO " + suffix); InsuranceInfo insInfo = InsuranceT.AddInsurance(pat, suffix, "p", ppoFeeSchedNum, 1, cobRule: EnumCobRule.SecondaryMedicaid); InsPlan priPlan = InsPlanT.GetPlanForPriSecMed(PriSecMed.Primary, insInfo.ListPatPlans, insInfo.ListInsPlans, insInfo.ListInsSubs); BenefitT.CreateCategoryPercent(priPlan.PlanNum, EbenefitCategory.Diagnostic, percent: 50); List <Benefit> listBens = Benefits.Refresh(insInfo.ListPatPlans, insInfo.ListInsSubs); string procStr = "D0150"; Procedure proc = ProcedureT.CreateProcedure(pat, procStr, ProcStat.TP, "", 125); ProcedureCode procCode = ProcedureCodes.GetProcCode(procStr); FeeT.CreateFee(ppoFeeSchedNum, procCode.CodeNum, amount: 80); Procedures.ComputeEstimates(proc, pat.PatNum, new List <ClaimProc>(), false, insInfo.ListInsPlans, insInfo.ListPatPlans, listBens, pat.Age, insInfo.ListInsSubs); List <ClaimProc> listClaimProcs = ClaimProcs.Refresh(pat.PatNum); Assert.AreEqual(40, listClaimProcs[0].InsEstTotal, 0.001); Assert.AreEqual(45, listClaimProcs[0].WriteOffEst, 0.001); }
public static List <ImportantNotes> ParseNotes(string ediResponse) { List <ImportantNotes> Notes = new List <ImportantNotes>(); try { Library.WriteErrorLog("1"); ediResponse = Regex.Replace(ediResponse, "<[^>]+>", string.Empty); // Discover the delimiters used. They're always in the same positions char ElemDelimiter = ediResponse[103]; char SegDelimiter = ediResponse[105]; var segments = ediResponse.Split(SegDelimiter).Select(x => x.Trim()) .AsEnumerable() // select all users from the database and bring them back to the client .Select((seg, index) => new // project in the index { Elements = seg.Split(ElemDelimiter).ToArray(), index }); Library.WriteErrorLog("2"); //Find Imp dates reagrding policy //Only the DTP segments that come before the EB segments. So find EB's 1st occurence RTFBuilder sb = new RTFBuilder(); sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("***Important dates***"); //var result = segments.Where(x => x.Elements[0] == "EB" && x.Elements.Count() > 1).FirstOrDefault(); var policyDTP = from seg in segments where ((seg.Elements.Count() > 1) && (seg.Elements[0] == "DTP") && (new List <string>(new string[] { "291", "307", "346", "347", "348", "356", "357", "539", "540" }).Contains(seg.Elements[1]))) //|| (seg.index < result.index) select seg; Library.WriteErrorLog("3"); var policyDTPDistinct = policyDTP.GroupBy(x => x.Elements[1]) .Select(y => y.First()); foreach (var seg in policyDTPDistinct) { sb.FontStyle(FontStyle.Bold).Append(DTP271.GetQualifierDescript(seg.Elements[1])).Append(": ").Append(DTP271.GetDateStr(seg.Elements[2], seg.Elements[3])).AppendLine(); } Library.WriteErrorLog("4"); /* * X271 x271 = new X271(ediResponse); * List<EB271> listEB; * listEB = x271.GetListEB(true); */ //Delta Dental provides via EB01 = D other via EB01= "A" //Delta Dental case sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("***Co Ins***"); var coIns_seg_Delta = from seg in segments where (seg.Elements.Count() > 8) && (seg.Elements[1] == "D") && (seg.Elements[3] != "") && (seg.Elements[8] != "") && (seg.Elements[5].Contains("PARTICIPATING")) select seg; foreach (var seg in coIns_seg_Delta.OrderBy(c => c.Elements[8])) { //Console.WriteLine(" ****" + coIns_items_Delta.Count()); sb.ForeColor(KnownColor.Green).FontSize(18).Append(" Insurance Pays ").Append((PIn.Double(seg.Elements[8]) * 100).ToString() + "% ").Append(": ").AppendLine(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } //Other case1 - Eb03 - 1st Choice var coIns_seg_Other_with13 = from seg in segments where ((seg.Elements.Count() > 3) && (seg.Elements.Count() < 14)) && (seg.Elements[3] != "") && (seg.Elements[1] == "A") && (seg.Elements[8] != "") && (seg.Elements[12] != "N") select seg; bool flagEB03; flagEB03 = true; foreach (var seg in coIns_seg_Other_with13.OrderBy(c => c.Elements[8])) { //Console.WriteLine(" ****" + coIns_items_others.Count()); flagEB03 = false; sb.ForeColor(KnownColor.Green).FontSize(18).Append(" Patient Pays ").Append((PIn.Double(seg.Elements[8]) * 100).ToString() + "% ").Append(": ").AppendLine(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } if (flagEB03) { //Other case1 - With EB13 since No Eb03 Choice 2 var coIns_seg_Other_with13_noEb03 = from seg in segments where ((seg.Elements.Count() > 13) && ((seg.Elements[12] == "Y") || (seg.Elements[12] == "U"))) && (seg.Elements[1] == "A") && (seg.Elements[8] != "") && (seg.Elements[3] == "") select seg; foreach (var seg in coIns_seg_Other_with13_noEb03.OrderBy(c => c.Elements[8])) { //Console.WriteLine(" ****" + coIns_items_others.Count()); sb.ForeColor(KnownColor.Green).FontSize(18).Append(" Patient Pays ").Append((PIn.Double(seg.Elements[8]) * 100).ToString() + "% ").Append(": ").Append(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript).AppendLine(ProcedureCodes.GetProcCode(seg.Elements[13].Substring(3)).AbbrDesc); } } //Other case1 - Without EB13 var coIns_seg_Othen_NO_13 = from seg in segments where ((seg.Elements.Count() > 2) && (seg.Elements.Count() < 13)) && (seg.Elements[1] == "A") && (seg.Elements[8] != "") select seg; foreach (var seg in coIns_seg_Othen_NO_13.OrderBy(c => c.Elements[8])) { //Console.WriteLine(" ****" + coIns_items_others.Count()); sb.ForeColor(KnownColor.Green).FontSize(18).Append(" Patient Pays ").Append((PIn.Double(seg.Elements[8]) * 100).ToString() + "% ").Append(": ").Append(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } //Look For Special case When EB09 has value var coIns_seg_Sp = from seg in segments where ((seg.Elements.Count() > 13) && (seg.Elements[12] == "Y")) && (seg.Elements[1] == "A") && (seg.Elements[9] != "") select seg; foreach (var seg in coIns_seg_Sp) { //Console.WriteLine(" ****" + coIns_items_others.Count()); sb.ForeColor(KnownColor.Green).FontSize(18).Append(GeneralUtilities.getEB09List().First(x => x.Code == seg.Elements[9]).Descript).Append(": ").Append(seg.Elements[10]).Append(": ").AppendLine(ProcedureCodes.GetProcCode(seg.Elements[13].Substring(3)).AbbrDesc); } sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("***Deductible***"); var ded_items = from seg in segments where (seg.Elements.Count() > 7) && (seg.Elements[1] == "C") && (seg.Elements[2] == "IND") && (seg.Elements[3] != "") && (seg.Elements[7] != "") select seg; var ded_items_distinct = ded_items.GroupBy(x => x.Elements[3]) .Select(y => y.First()); foreach (var seg in ded_items_distinct.OrderBy(c => c.Elements[7])) { sb.ForeColor(KnownColor.Green).FontSize(18).Append(seg.Elements[7]).Append(": ").Append(GeneralUtilities.getEB06List().First(x => x.Code == seg.Elements[6]).Descript).Append(": ").AppendLine(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("***Limitations***"); //Here we consifer two cases //Case 1 When $$ amount is present //Case 2 without $$ Amount //Case 1 When $$ amount is present var limit_items = from seg in segments where ((seg.Elements.Count() > 12) && (seg.Elements[12] == "Y")) && ((seg.Elements[1] == "F") && (seg.Elements[3] != "") && (seg.Elements[6] != "")) select seg; var limit_items_distinct = limit_items.GroupBy(x => x.Elements[3]) .Select(y => y.First()); foreach (var seg in limit_items_distinct.OrderBy(c => c.Elements[7])) { sb.ForeColor(KnownColor.Green).FontSize(18).Append(seg.Elements[7]).Append(": ").Append(GeneralUtilities.getEB06List().First(x => x.Code == seg.Elements[6]).Descript).Append(": ").AppendLine(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } /* * var limit_items_distinct_sp = limit_items_sp.GroupBy(x => x.Segment.Elements[6]) * .Select(y => y.First()); */ //Case 2 without $$ Amount -- Date limitation with HSD var resultHSD = segments.Where(x => x.Elements[0] == "HSD" && x.Elements.Count() > 5); foreach (var segHSD in resultHSD) { var resultEB = segments.Where(x => (x.index == segHSD.index - 1) && (x.Elements[0] == "EB") && (x.Elements[1] == "F")); foreach (var segEB in resultEB) { //var code = GeneralUtilities.getEB06List().First(x => x.Code == segHSD.Elements[5]); if (segEB.Elements.Count() > 13) { sb.ForeColor(KnownColor.Green).FontSize(18).Append(segEB.Elements[13]).Append(": ").Append(segHSD.Elements[2]); sb.ForeColor(KnownColor.Red).Append(" Visit in ").Append(segHSD.Elements[6]).AppendLine(" " + GeneralUtilities.getEB06List().First(x => x.Code == segHSD.Elements[5]).Descript); } } } var spLimitation = segments.Where(x => x.Elements[0] == "EB" && x.Elements[1] == "F" && x.Elements.Count() < 3); foreach (var segSpLimit in spLimitation) { var spMSG = segments.Where(x => (x.index == segSpLimit.index + 1) && (x.Elements[0] == "MSG")); foreach (var segEB in spMSG) { //var code = GeneralUtilities.getEB06List().First(x => x.Code == segHSD.Elements[5]); sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("=>" + segEB.Elements[1]); } } // rtb_notes.Rtf = sb.ToString(); Library.WriteErrorLog("5"); StreamReader StrSB = new StreamReader(sb.ToString()); string line = ""; while ((line = StrSB.ReadLine()) != null) { Notes.Add(new ImportantNotes { Note = line.ToString() }); } Library.WriteErrorLog("6"); //Find if Ortho Covergage is there or not. var ebOrthoRem = from seg in segments where (seg.Elements.Count() > 7) && (seg.Elements[0] == "EB") && (seg.Elements[1] == "F") && (seg.Elements[3] == "38") && (seg.Elements[6] == "33") select decimal.Parse(seg.Elements[7]); //rtb_notes.Text = ""; /* * if (ebOrthoRem != null) * { * * int count = 0; * * IEnumerator<decimal> str = ebOrthoRem.GetEnumerator(); * if (str.ToString().Trim() != null) * { * while (str.MoveNext()) * { * count++; * strnotes = strnotes + count + ". " + str.Current.ToString().Trim() + Environment.NewLine + Environment.NewLine; * } * if(string.IsNullOrEmpty(strnotes)) * strnotes = "NONE"; * } * else * { * strnotes = "NONE"; * } * //rtb_notes.Text = strnotes; * } * else * { * rtb_notes.Text = "NONE"; * } */ } catch (Exception ex) { Library.WriteErrorLog(ex); Notes.Add(new ImportantNotes { Note = ex.Message.Trim() }); Notes.Add(new ImportantNotes { Note = ex.StackTrace.Trim() }); } return(Notes); }
///<summary>Creates a procedure and computes estimates for a patient where the secondary insurance has a COB rule of Medicaid.</summary> private void ComputeEstimatesFixedBenefits(string suffix, double procFee, double ppoFee, double fixedBenefitFee , int priPercentCoveredOverride, bool hasSecondary, double secFee, Action <FixedBenefitAssertItem> assertAct) { Patient pat = PatientT.CreatePatient(suffix); string procStr = "D0150"; Procedure proc = ProcedureT.CreateProcedure(pat, procStr, ProcStat.TP, "", procFee); ProcedureCode procCode = ProcedureCodes.GetProcCode(procStr); long ppoFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "PPO " + suffix); long catPercFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, "Category % " + suffix); long fixedBenefitFeeSchedNum = FeeSchedT.CreateFeeSched(FeeScheduleType.FixedBenefit, "Fixed Benefit " + suffix); if (ppoFee > -1) { FeeT.CreateFee(ppoFeeSchedNum, procCode.CodeNum, ppoFee); } FeeT.CreateFee(fixedBenefitFeeSchedNum, procCode.CodeNum, fixedBenefitFee); InsuranceT.AddInsurance(pat, suffix, "p", ppoFeeSchedNum, copayFeeSchedNum: fixedBenefitFeeSchedNum); if (hasSecondary) { FeeT.CreateFee(catPercFeeSchedNum, procCode.CodeNum, secFee); InsuranceT.AddInsurance(pat, suffix, "", catPercFeeSchedNum, 2, false, EnumCobRule.Standard); } List <InsSub> listSubs = InsSubT.GetInsSubs(pat); List <InsPlan> listPlans = InsPlans.RefreshForSubList(listSubs); List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum); InsPlan priPlan = InsPlanT.GetPlanForPriSecMed(PriSecMed.Primary, listPatPlans, listPlans, listSubs); InsPlan secPlan = null; if (hasSecondary) { secPlan = InsPlanT.GetPlanForPriSecMed(PriSecMed.Secondary, listPatPlans, listPlans, listSubs); //TODO: Add diagnostic code benefit for 100% BenefitT.CreateCategoryPercent(secPlan.PlanNum, EbenefitCategory.Diagnostic, 100); } List <Benefit> listBens = Benefits.Refresh(listPatPlans, listSubs); Procedures.ComputeEstimates(proc, pat.PatNum, new List <ClaimProc>(), false, listPlans, listPatPlans, listBens, pat.Age, listSubs); List <ClaimProc> listClaimProcs = ClaimProcs.Refresh(pat.PatNum); if (priPercentCoveredOverride > 0) { foreach (ClaimProc cpCur in listClaimProcs) { cpCur.PercentOverride = priPercentCoveredOverride; ClaimProcs.Update(cpCur); } Procedures.ComputeEstimates(proc, pat.PatNum, new List <ClaimProc>(), false, listPlans, listPatPlans, listBens, pat.Age, listSubs); listClaimProcs = ClaimProcs.Refresh(pat.PatNum); } foreach (ClaimProc cpCur in listClaimProcs) { cpCur.PercentOverride = priPercentCoveredOverride; ClaimProcs.Update(cpCur); } Procedures.ComputeEstimates(proc, pat.PatNum, listClaimProcs, false, listPlans, listPatPlans, listBens, pat.Age, listSubs); listClaimProcs = ClaimProcs.Refresh(pat.PatNum); assertAct(new FixedBenefitAssertItem() { Procedure = proc, PrimaryClaimProc = listClaimProcs.FirstOrDefault(x => x.PlanNum == priPlan.PlanNum), SecondaryClaimProc = secPlan == null ? null : listClaimProcs.FirstOrDefault(x => x.PlanNum == secPlan.PlanNum), }); }
///<summary>Called once for each claim to be created. For claims with a lot of procedures, this may actually create multiple claims. ///Normally returns empty string unless something went wrong.</summary> public static bool CreateClaim(Clearinghouse clearinghouseClin, ClaimSendQueueItem queueItem, int batchNum) { StringBuilder strb = new StringBuilder(); string t = "\t"; strb.Append("110\t111\t112\t118\t203/403\tF108/204/404\t205/405\t206\t207\t208\t209\t210\t211\t212\t215\t217\t219\t406\t408\t409\t410\t411\t413\t414\t415\t416\t418\t419\t420\t421\t422\t423\t424\t425\t426\t428\t429\t430\t432\t433\r\n"); Claim claim = Claims.GetClaim(queueItem.ClaimNum); Provider provBill = Providers.GetProv(claim.ProvBill); Patient pat = Patients.GetPat(claim.PatNum); InsPlan insplan = InsPlans.GetPlan(claim.PlanNum, new List <InsPlan>()); InsSub insSub = InsSubs.GetSub(claim.InsSubNum, new List <InsSub>()); Carrier carrier = Carriers.GetCarrier(insplan.CarrierNum); List <ClaimProc> claimProcList = ClaimProcs.Refresh(pat.PatNum); List <ClaimProc> claimProcsForClaim = ClaimProcs.GetForSendClaim(claimProcList, claim.ClaimNum); List <Procedure> procList = Procedures.Refresh(claim.PatNum); Procedure proc; ProcedureCode procCode; //ProcedureCode procCode; for (int i = 0; i < claimProcsForClaim.Count; i++) { //claimProcsForClaim already excludes any claimprocs with ProcNum=0, so no payments etc. proc = Procedures.GetProcFromList(procList, claimProcsForClaim[i].ProcNum); //procCode=Pro strb.Append(provBill.SSN + t); //110 strb.Append(provBill.MedicaidID + t); //111 strb.Append(t); //112 strb.Append(t); //118 strb.Append(pat.SSN + t); //203/403 strb.Append(carrier.CarrierName + t); //carrier name? strb.Append(insSub.SubscriberID + t); strb.Append(pat.PatNum.ToString() + t); strb.Append(pat.Birthdate.ToString("dd-MM-yyyy") + t); if (pat.Gender == PatientGender.Female) { strb.Append("2" + t); //"V"+t); } else { strb.Append("1" + t); //M"+t); } strb.Append("1" + t); strb.Append(DutchLName(pat.LName) + t); //last name without prefix strb.Append(DutchLNamePrefix(pat.LName) + t); //prefix strb.Append("2" + t); strb.Append(DutchInitials(pat) + t); //215. initials strb.Append(pat.Zip + t); strb.Append(DutchAddressNumber(pat.Address) + t); //219 house number. Already validated. strb.Append(t); strb.Append(proc.ProcDate.ToString("dd-MM-yyyy") + t); //procDate procCode = ProcedureCodes.GetProcCode(proc.CodeNum); string strProcCode = procCode.ProcCode; if (strProcCode.EndsWith("00")) //ending with 00 indicates it's a lab code. { strb.Append("02" + t); } else { strb.Append("01" + t); //409. Procedure code (01) or lab costs (02) } strb.Append(t); strb.Append(t); strb.Append(strProcCode + t); strb.Append(GetUL(proc, procCode) + t); //414. U/L. strb.Append(Tooth.ToInternat(proc.ToothNum) + t); strb.Append(Tooth.SurfTidyForClaims(proc.Surf, proc.ToothNum) + t); //needs validation strb.Append(t); if (claim.AccidentRelated == "") //not accident { strb.Append("N" + t); } else { strb.Append("J" + t); } strb.Append(pat.SSN + t); strb.Append(t); strb.Append(t); strb.Append(t); strb.Append(proc.ProcFee.ToString("F") + t); strb.Append("1" + t); strb.Append(proc.ProcFee.ToString("F") + t); strb.Append(t); strb.Append(t); strb.Append(proc.ProcFee.ToString("F") + t); strb.Append(t); strb.Append(t); strb.Append("\r\n"); } string saveFolder = clearinghouseClin.ExportPath; if (!Directory.Exists(saveFolder)) { MessageBox.Show(saveFolder + " " + Lans.g("Dutch", "not found.")); return(false); } string saveFile = ODFileUtils.CombinePaths(saveFolder, "claims" + claim.ClaimNum.ToString() + ".txt"); File.WriteAllText(saveFile, strb.ToString()); //MessageBox.Show(strb.ToString()); return(true); }
///<summary>Sets the MissingData and Warnings fields on the queueItem as appropriate.</summary> public static void GetMissingData(Clearinghouse clearinghouseClin, ClaimSendQueueItem queueItem) { StringBuilder sbErrors = new StringBuilder(); StringBuilder sbWarnings = new StringBuilder(); Claim claim = Claims.GetClaim(queueItem.ClaimNum); Provider provClaimTreat = Providers.GetProv(claim.ProvTreat); InsSub insSub = InsSubs.GetOne(claim.InsSubNum); #region Header //TRNSM if (!Regex.IsMatch(clearinghouseClin.SenderTIN, @"^[0-9]+$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Tax ID Number (RAMQ TRNSM) is invalid"); } else { int trnsm = PIn.Int(clearinghouseClin.SenderTIN); if (clearinghouseClin.ISA15 != "T" && trnsm >= 18000 && trnsm <= 18999) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Tax ID Number (RAMQ TRNSM) is a test value on this production claim"); } else if (clearinghouseClin.ISA15 == "T" && (trnsm < 18000 || trnsm > 18999)) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Tax ID Number (RAMQ TRNSM) must be between 18000 and 18999 for this test claim"); } } //DISP if (!Regex.IsMatch(provClaimTreat.NationalProvID, @"^[27][0-9]{5}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Claim treating provider CDA Number for RAMQ is invalid"); } //DISP_REFNT if (claim.CanadianReferralProviderNum.Trim().Length > 0 && !Regex.IsMatch(claim.CanadianReferralProviderNum.Trim(), @"^[0-9]{6}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Referral provider CDA Number for RAMQ is invalid"); } //ETAB if (!Regex.IsMatch(provClaimTreat.CanadianOfficeNum, @"^[0-9]{5}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Claim treating provider Office Number for RAMQ is invalid"); } //SERV if (claim.DateService.Year < 1880) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Claim date of service is invalid or missing"); } #endregion Header #region Insurance //Most fields in the insuranace section are optional and thus do not require validation. //NAM if (!Regex.IsMatch(insSub.SubscriberID, @"^[a-zA-Z]{4}[0-9]{6}[a-zA-Z0-9][0-9]$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Subscriber ID for RAMQ is invalid"); } #endregion Insurance #region Procedures List <ProcedureCode> listProcCodes = ProcedureCodes.GetAllCodes(); List <ClaimProc> listClaimProcsForPat = ClaimProcs.Refresh(claim.PatNum); List <ClaimProc> listClaimProcsForClaim = ClaimProcs.GetForSendClaim(listClaimProcsForPat, claim.ClaimNum); //Excludes labs. List <Procedure> listProcsForPat = Procedures.Refresh(claim.PatNum); 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; } //ACTE if (procCode.ProcCode.Length < 5 || !Regex.IsMatch(procCode.ProcCode.Substring(0, 5), @"^[0-9]{5}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Procedure code invalid '" + procCode.ProcCode + "'"); } 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); if (labProcCode.ProcCode.Length < 5 || !Regex.IsMatch(labProcCode.ProcCode.Substring(0, 5), @"^[0-9]{5}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Lab code invalid '" + labProcCode.ProcCode + "'"); } } } #endregion Procedures queueItem.MissingData = sbErrors.ToString(); queueItem.Warnings = sbWarnings.ToString(); }
///<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); }
/// <summary>claimType="P","S","PreAuth","W" (waiting to send).</summary> public static Claim CreateClaim(string claimType, List <PatPlan> PatPlanList, List <InsPlan> InsPlanList, List <ClaimProc> ClaimProcList, List <Procedure> procsForPat, Patient pat, List <Procedure> procsForClaim, List <Benefit> benefitList, List <InsSub> SubList, bool calculateLineNumber = true) { //Claim ClaimCur=CreateClaim("P",PatPlanList,InsPlanList,ClaimProcList,procsForPat); InsPlan PlanCur1 = new InsPlan(); InsSub SubCur1 = new InsSub(); InsPlan PlanCur2 = new InsPlan(); InsSub SubCur2 = new InsSub(); switch (claimType) { case "P": SubCur1 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, 1), SubList); PlanCur1 = InsPlans.GetPlan(SubCur1.PlanNum, InsPlanList); SubCur2 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, 2), SubList); //PlanCur2=InsPlans.GetPlan(SubCur.PlanNum,InsPlanList);//can end up null break; case "S": SubCur1 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, 2), SubList); PlanCur1 = InsPlans.GetPlan(SubCur1.PlanNum, InsPlanList); SubCur2 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, 1), SubList); //PlanCur2=InsPlans.GetPlan(SubCur.PlanNum,InsPlanList);//can end up null break; case "PreAuth": SubCur1 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, 1), SubList); PlanCur1 = InsPlans.GetPlan(SubCur1.PlanNum, InsPlanList); SubCur2 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, 2), SubList); break; case "W": SubCur1 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, 1), SubList); PlanCur1 = InsPlans.GetPlan(SubCur1.PlanNum, InsPlanList); SubCur2 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, 2), SubList); break; case "Med": SubCur1 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, PatPlans.GetOrdinal(PriSecMed.Medical, PatPlanList, InsPlanList, SubList)), SubList); PlanCur1 = InsPlans.GetPlan(SubCur1.PlanNum, InsPlanList); SubCur2 = InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList, PatPlans.GetOrdinal(PriSecMed.Primary, PatPlanList, InsPlanList, SubList)), SubList); break; } //DataTable table=DataSetMain.Tables["account"]; Procedure proc; //proc=Procedures.GetProcFromList(procsForPat,PIn.Long(table.Rows[gridAccount.SelectedIndices[0]]["ProcNum"].ToString())); //long clinicNum=proc.ClinicNum; ClaimProc[] claimProcs = new ClaimProc[procsForClaim.Count]; //1:1 with procs long procNum; for (int i = 0; i < procsForClaim.Count; i++) //loop through selected procs //and try to find an estimate that can be used { procNum = procsForClaim[i].ProcNum; claimProcs[i] = Procedures.GetClaimProcEstimate(procNum, ClaimProcList, PlanCur1, SubCur1.InsSubNum); } for (int i = 0; i < claimProcs.Length; i++) //loop through each claimProc //and create any missing estimates. This handles claims to 3rd and 4th ins co's. { if (claimProcs[i] == null) { claimProcs[i] = new ClaimProc(); proc = procsForClaim[i]; ClaimProcs.CreateEst(claimProcs[i], proc, PlanCur1, SubCur1); } } Claim claim = new Claim(); Claims.Insert(claim); //to retreive a key for new Claim.ClaimNum claim.PatNum = pat.PatNum; claim.DateService = claimProcs[claimProcs.Length - 1].ProcDate; claim.ClinicNum = procsForClaim[0].ClinicNum; claim.DateSent = DateTime.Today; claim.DateSentOrig = claim.DateSent; claim.ClaimStatus = "S"; claim.AttachedFlags = "Mail"; //datereceived switch (claimType) { case "P": claim.PlanNum = SubCur1.PlanNum; claim.InsSubNum = PatPlans.GetInsSubNum(PatPlanList, 1); claim.PatRelat = PatPlans.GetRelat(PatPlanList, 1); claim.ClaimType = "P"; claim.PlanNum2 = SubCur2.PlanNum; //might be 0 if no sec ins claim.InsSubNum2 = PatPlans.GetInsSubNum(PatPlanList, 2); claim.PatRelat2 = PatPlans.GetRelat(PatPlanList, 2); break; case "S": claim.PlanNum = SubCur1.PlanNum; claim.InsSubNum = PatPlans.GetInsSubNum(PatPlanList, 2); claim.PatRelat = PatPlans.GetRelat(PatPlanList, 2); claim.ClaimType = "S"; claim.PlanNum2 = SubCur2.PlanNum; claim.InsSubNum2 = PatPlans.GetInsSubNum(PatPlanList, 1); claim.PatRelat2 = PatPlans.GetRelat(PatPlanList, 1); break; case "W": claim.PlanNum = SubCur1.PlanNum; claim.InsSubNum = PatPlans.GetInsSubNum(PatPlanList, 2); claim.PatRelat = PatPlans.GetRelat(PatPlanList, 2); claim.ClaimType = "P"; claim.ClaimStatus = "W"; claim.PlanNum2 = SubCur2.PlanNum; claim.InsSubNum2 = PatPlans.GetInsSubNum(PatPlanList, 1); claim.PatRelat2 = PatPlans.GetRelat(PatPlanList, 1); break; case "Med": claim.PlanNum = SubCur1.PlanNum; claim.InsSubNum = PatPlans.GetInsSubNum(PatPlanList, 1); claim.PatRelat = PatPlans.GetRelat(PatPlanList, 1); claim.ClaimType = "Other"; claim.PlanNum2 = SubCur2.PlanNum; //might be 0 if no other ins claim.InsSubNum2 = PatPlans.GetInsSubNum(PatPlanList, 2); claim.PatRelat2 = PatPlans.GetRelat(PatPlanList, 2); break; } claim.ProvTreat = procsForClaim[0].ProvNum; claim.IsProsthesis = "I"; claim.ProvBill = Providers.GetBillingProvNum(claim.ProvTreat, claim.ClinicNum); claim.EmployRelated = YN.No; //attach procedures Procedure ProcCur; for (int i = 0; i < claimProcs.Length; i++) { ProcCur = procsForClaim[i]; claimProcs[i].ClaimNum = claim.ClaimNum; claimProcs[i].Status = ClaimProcStatus.NotReceived; //status for claims unsent or sent. //writeoff handled in ClaimL.CalculateAndUpdate() claimProcs[i].CodeSent = ProcedureCodes.GetProcCode(ProcCur.CodeNum).ProcCode; if (claimProcs[i].CodeSent.Length > 5 && claimProcs[i].CodeSent.Substring(0, 1) == "D") { claimProcs[i].CodeSent = claimProcs[i].CodeSent.Substring(0, 5); } if (calculateLineNumber) { claimProcs[i].LineNumber = (byte)(i + 1); } ClaimProcs.Update(claimProcs[i]); } ClaimProcList = ClaimProcs.Refresh(pat.PatNum); Claims.CalculateAndUpdate(procsForPat, InsPlanList, claim, PatPlanList, benefitList, pat.Age, SubList); return(claim); }
///<summary>Procedure will have a completed status. For surfaces, since the scripts are faulty, pass in the exact surfaces that should be in the db, no validation will be done, and those exact same surfaces are what will go out on claim.</summary> public static Procedure AddProc(string procCode, long patNum, DateTime procDate, string toothNum, string surf, double fee, string typeCodes, long provNum) { Procedure proc = new Procedure(); ProcedureCode procedureCode = ProcedureCodes.GetProcCode(procCode); //procnum proc.PatNum = patNum; //aptnum proc.CodeNum = procedureCode.CodeNum; proc.ProcDate = procDate; proc.DateTP = proc.ProcDate; proc.ProcFee = fee; switch (toothNum) { case "": proc.ToothNum = ""; proc.Surf = surf; break; case "10": proc.ToothNum = ""; proc.Surf = "UR"; break; case "20": proc.ToothNum = ""; proc.Surf = "UL"; break; case "30": proc.ToothNum = ""; proc.Surf = "LL"; break; case "40": proc.ToothNum = ""; proc.Surf = "LR"; break; default: proc.ToothNum = Tooth.FromInternat(toothNum); proc.Surf = surf; //Tooth.SurfTidyFromDisplayToDb(surf,proc.ToothNum); break; } //ToothRange proc.Priority = 0; proc.ProcStatus = ProcStat.C; proc.ProvNum = provNum; proc.Note = ""; proc.ClinicNum = 0; //proc.Dx proc.MedicalCode = ""; proc.BaseUnits = 0; proc.SiteNum = 0; //nextaptnum proc.CanadianTypeCodes = typeCodes; Procedures.Insert(proc); //if an extraction, then mark previous procs hidden. Skip. //Recalls.Synch(PatCur.PatNum);//skip //Procedures.ComputeEstimates(proc,patNum,new List<ClaimProc>(),true,planList,patPlanList,benefitList,age); return(proc); }
private void FormInsurance_Load(object sender, EventArgs e) { //this.Location = new Point(aPOS, bPOS); //this.FillSummary(); try { if (ediResponse == null || ediResponse.Length < 1) { // this.FillSummary(); // FillNotes(); } else { lblerror.Visible = false; this.ediResponse = Regex.Replace(this.ediResponse, "<[^>]+>", string.Empty); // Discover the delimiters used. They're always in the same positions char ElemDelimiter = this.ediResponse[103]; char SegDelimiter = this.ediResponse[105]; var segments = ediResponse.Split(SegDelimiter).Select(x => x.Trim()) .AsEnumerable() // select all users from the database and bring them back to the client .Select((seg, index) => new // project in the index { Elements = seg.Split(ElemDelimiter).ToArray(), index }); //Find Imp dates reagrding policy //Only the DTP segments that come before the EB segments. So find EB's 1st occurence InsNotes.Add(new InsuranceNotes { Name = "***Important dates***" }); //RTFBuilder sb = new RTFBuilder(); //sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("***Important dates***"); //var result = segments.Where(x => x.Elements[0] == "EB" && x.Elements.Count() > 1).FirstOrDefault(); var policyDTP = from seg in segments where ((seg.Elements.Count() > 1) && (seg.Elements[0] == "DTP") && (new List <string>(new string[] { "291", "307", "346", "347", "348", "356", "357", "539", "540" }).Contains(seg.Elements[1]))) //|| (seg.index < result.index) select seg; var policyDTPDistinct = policyDTP.GroupBy(x => x.Elements[1]) .Select(y => y.First()); foreach (var seg in policyDTPDistinct) { InsNotes.Add(new InsuranceNotes { Name = "IMP" + DTP271.GetQualifierDescript(seg.Elements[1]) + ": " + DTP271.GetDateStr(seg.Elements[2], seg.Elements[3]) }); //sb.FontStyle(FontStyle.Bold).Append(DTP271.GetQualifierDescript(seg.Elements[1])).Append(": ").Append(DTP271.GetDateStr(seg.Elements[2], seg.Elements[3])).AppendLine(); } //Delta Dental provides via EB01 = D other via EB01= "A" //Delta Dental case InsNotes.Add(new InsuranceNotes { Name = "***Co Ins***" }); // sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("***Co Ins***"); var coIns_seg_Delta = from seg in segments where (seg.Elements.Count() > 8) && (seg.Elements[1] == "D") && (seg.Elements[3] != "") && (seg.Elements[8] != "") && (seg.Elements[5].Contains("PARTICIPATING")) select seg; foreach (var seg in coIns_seg_Delta.OrderBy(c => c.Elements[8])) { InsNotes.Add(new InsuranceNotes { Name = " Insurance Pays " + (PIn.Double(seg.Elements[8]) * 100).ToString() + "% " + ": " + GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript }); //Console.WriteLine(" ****" + coIns_items_Delta.Count()); // sb.ForeColor(KnownColor.Green).FontSize(18).Append(" Insurance Pays ").Append((PIn.Double(seg.Elements[8]) * 100).ToString() + "% ").Append(": ").AppendLine(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } //Other case1 - Eb03 - 1st Choice var coIns_seg_Other_with13 = from seg in segments where ((seg.Elements.Count() > 3) && (seg.Elements.Count() < 14)) && (seg.Elements[3] != "") && (seg.Elements[1] == "A") && (seg.Elements[8] != "") && (seg.Elements[12] != "N") select seg; bool flagEB03; flagEB03 = true; foreach (var seg in coIns_seg_Other_with13.OrderBy(c => c.Elements[8])) { //Console.WriteLine(" ****" + coIns_items_others.Count()); flagEB03 = false; InsNotes.Add(new InsuranceNotes { Name = " Patient Pays " + (PIn.Double(seg.Elements[8]) * 100).ToString() + "% " + ": " + GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript }); // sb.ForeColor(KnownColor.Green).FontSize(18).Append(" Patient Pays ").Append((PIn.Double(seg.Elements[8]) * 100).ToString() + "% ").Append(": ").AppendLine(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } if (flagEB03) { //Other case1 - With EB13 since No Eb03 Choice 2 var coIns_seg_Other_with13_noEb03 = from seg in segments where ((seg.Elements.Count() > 13) && ((seg.Elements[12] == "Y") || (seg.Elements[12] == "U"))) && (seg.Elements[1] == "A") && (seg.Elements[8] != "") && (seg.Elements[3] == "") select seg; foreach (var seg in coIns_seg_Other_with13_noEb03.OrderBy(c => c.Elements[8])) { //Console.WriteLine(" ****" + coIns_items_others.Count()); InsNotes.Add(new InsuranceNotes { Name = " Patient Pays " + (PIn.Double(seg.Elements[8]) * 100).ToString() + "% " + ": " + GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript + ProcedureCodes.GetProcCode(seg.Elements[13].Substring(3)).AbbrDesc }); // sb.ForeColor(KnownColor.Green).FontSize(18).Append(" Patient Pays ").Append((PIn.Double(seg.Elements[8]) * 100).ToString() + "% ").Append(": ").Append(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript).AppendLine(ProcedureCodes.GetProcCode(seg.Elements[13].Substring(3)).AbbrDesc); } } //Other case1 - Without EB13 var coIns_seg_Othen_NO_13 = from seg in segments where ((seg.Elements.Count() > 2) && (seg.Elements.Count() < 13)) && (seg.Elements[1] == "A") && (seg.Elements[8] != "") select seg; foreach (var seg in coIns_seg_Othen_NO_13.OrderBy(c => c.Elements[8])) { //Console.WriteLine(" ****" + coIns_items_others.Count()); InsNotes.Add(new InsuranceNotes { Name = " Patient Pays " + (PIn.Double(seg.Elements[8]) * 100).ToString() + "% " + ": " + GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript }); // sb.ForeColor(KnownColor.Green).FontSize(18).Append(" Patient Pays ").Append((PIn.Double(seg.Elements[8]) * 100).ToString() + "% ").Append(": ").Append(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } //Look For Special case When EB09 has value var coIns_seg_Sp = from seg in segments where ((seg.Elements.Count() > 13) && (seg.Elements[12] == "Y")) && (seg.Elements[1] == "A") && (seg.Elements[9] != "") select seg; foreach (var seg in coIns_seg_Sp) { //Console.WriteLine(" ****" + coIns_items_others.Count()); InsNotes.Add(new InsuranceNotes { Name = "ProcCode-" + GeneralUtilities.getEB09List().First(x => x.Code == seg.Elements[9]).Descript + ": " + seg.Elements[10] + ": " + ProcedureCodes.GetProcCode(seg.Elements[13].Substring(3)).AbbrDesc }); //sb.ForeColor(KnownColor.Green).FontSize(18).Append(GeneralUtilities.getEB09List().First(x => x.Code == seg.Elements[9]).Descript).Append(": ").Append(seg.Elements[10]).Append(": ").AppendLine(ProcedureCodes.GetProcCode(seg.Elements[13].Substring(3)).AbbrDesc); } InsNotes.Add(new InsuranceNotes { Name = "***Deductible***" }); //sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("***Deductible***"); var ded_items = from seg in segments where (seg.Elements.Count() > 7) && (seg.Elements[1] == "C") && (seg.Elements[2] == "IND") && (seg.Elements[3] != "") && (seg.Elements[7] != "") select seg; var ded_items_distinct = ded_items.GroupBy(x => x.Elements[3]) .Select(y => y.First()); foreach (var seg in ded_items_distinct.OrderBy(c => c.Elements[7])) { InsNotes.Add(new InsuranceNotes { Name = "Deductible-" + seg.Elements[7] + ": " + GeneralUtilities.getEB06List().First(x => x.Code == seg.Elements[6]).Descript + ": " + GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript }); //sb.ForeColor(KnownColor.Green).FontSize(18).Append(seg.Elements[7]).Append(": ").Append(GeneralUtilities.getEB06List().First(x => x.Code == seg.Elements[6]).Descript).Append(": ").AppendLine(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } InsNotes.Add(new InsuranceNotes { Name = "***Limitations***" }); //sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("***Limitations***"); //Here we consifer two cases //Case 1 When $$ amount is present //Case 2 without $$ Amount //Case 1 When $$ amount is present var limit_items = from seg in segments where ((seg.Elements.Count() > 12) && (seg.Elements[12] == "Y")) && ((seg.Elements[1] == "F") && (seg.Elements[3] != "") && (seg.Elements[6] != "")) select seg; var limit_items_distinct = limit_items.GroupBy(x => x.Elements[3]) .Select(y => y.First()); foreach (var seg in limit_items_distinct.OrderBy(c => c.Elements[7])) { InsNotes.Add(new InsuranceNotes { Name = "Limitations-" + seg.Elements[7] + ": " + GeneralUtilities.getEB06List().First(x => x.Code == seg.Elements[6]).Descript + ": " + GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript }); //sb.ForeColor(KnownColor.Green).FontSize(18).Append(seg.Elements[7]).Append(": ").Append(GeneralUtilities.getEB06List().First(x => x.Code == seg.Elements[6]).Descript).Append(": ").AppendLine(GeneralUtilities.getEB03List().First(x => x.Code == seg.Elements[3]).Descript); } //Case 2 without $$ Amount -- Date limitation with HSD var resultHSD = segments.Where(x => x.Elements[0] == "HSD" && x.Elements.Count() > 5); foreach (var segHSD in resultHSD) { var resultEB = segments.Where(x => (x.index == segHSD.index - 1) && (x.Elements[0] == "EB") && (x.Elements[1] == "F")); foreach (var segEB in resultEB) { //var code = GeneralUtilities.getEB06List().First(x => x.Code == segHSD.Elements[5]); if (segEB.Elements.Count() > 13) { InsNotes.Add(new InsuranceNotes { Name = "HSD-" + segEB.Elements[13] + ": " + segHSD.Elements[2] }); InsNotes.Add(new InsuranceNotes { Name = " Visit in " + segHSD.Elements[6] + " " + GeneralUtilities.getEB06List().First(x => x.Code == segHSD.Elements[5]).Descript }); // sb.ForeColor(KnownColor.Green).FontSize(18).Append(segEB.Elements[13]).Append(": ").Append(segHSD.Elements[2]); // sb.ForeColor(KnownColor.Red).Append(" Visit in ").Append(segHSD.Elements[6]).AppendLine(" " + GeneralUtilities.getEB06List().First(x => x.Code == segHSD.Elements[5]).Descript); } } } var spLimitation = segments.Where(x => x.Elements[0] == "EB" && x.Elements[1] == "F" && x.Elements.Count() < 3); foreach (var segSpLimit in spLimitation) { var spMSG = segments.Where(x => (x.index == segSpLimit.index + 1) && (x.Elements[0] == "MSG")); foreach (var segEB in spMSG) { //var code = GeneralUtilities.getEB06List().First(x => x.Code == segHSD.Elements[5]); InsNotes.Add(new InsuranceNotes { Name = "=>" + segEB.Elements[1] }); //sb.ForeColor(KnownColor.Red).FontSize(18).AppendLine("=>" + segEB.Elements[1]); } } FillNotes(); //rtb_notes.Rtf = sb.ToString(); //Find if Ortho Covergage is there or not. var ebOrthoRem = from seg in segments where (seg.Elements.Count() > 7) && (seg.Elements[0] == "EB") && (seg.Elements[1] == "F") && (seg.Elements[3] == "38") && (seg.Elements[6] == "33") select decimal.Parse(seg.Elements[7]); } this.Location = new Point(aPOS, bPOS); } catch (Exception pcex) { string strEx = ""; strEx = "Oops something went wrong!" + Environment.NewLine + Environment.NewLine + "Error Message:" + Environment.NewLine + Environment.NewLine + pcex.Message.ToString() + Environment.NewLine + Environment.NewLine; strEx = strEx + "Error Stack Trace:" + Environment.NewLine + Environment.NewLine + pcex.StackTrace.ToString() + Environment.NewLine + Environment.NewLine; MessageBox.Show(strEx.ToString(), "patientXpress", MessageBoxButtons.OK, MessageBoxIcon.Error); Library.WriteErrorLog(pcex); } }
///<summary>Sets the MissingData and Warnings fields on the queueItem as appropriate.</summary> public static void GetMissingData(ClaimSendQueueItem queueItem) { StringBuilder sbErrors = new StringBuilder(); StringBuilder sbWarnings = new StringBuilder(); Claim claim = Claims.GetClaim(queueItem.ClaimNum); Provider provClaimTreat = Providers.GetProv(claim.ProvTreat); InsSub insSub = InsSubs.GetOne(claim.InsSubNum); Patient pat = Patients.GetPat(claim.PatNum); #region Header //DISP if (!Regex.IsMatch(provClaimTreat.NationalProvID, @"^[27][0-9]{5}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Claim treating provider ID for RAMQ is invalid"); } //DISP_REFNT if (claim.CanadianReferralProviderNum.Trim().Length > 0 && !Regex.IsMatch(claim.CanadianReferralProviderNum.Trim(), @"^[0-9]{6}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Referral provider ID for RAMQ is invalid"); } //ETAB if (!Regex.IsMatch(provClaimTreat.CanadianOfficeNum, @"^[0-9]{5}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Claim treating provider office number is invalid"); } //SERV if (claim.DateService.Year < 1880) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Claim date of service is invalid or missing"); } #endregion Header #region Insurance //Most fields in the insuranace section are optional and thus do not require validation. //NAM if (!Regex.IsMatch(insSub.SubscriberID, @"^[a-zA-Z]{4}[0-9]{6}[a-zA-Z0-9][0-9]$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Subscriber ID invalid"); } #endregion Insurance #region Procedures List <ProcedureCode> listProcCodes = ProcedureCodes.GetAllCodes(); List <ClaimProc> listClaimProcsForPat = ClaimProcs.Refresh(claim.PatNum); List <ClaimProc> listClaimProcsForClaim = ClaimProcs.GetForSendClaim(listClaimProcsForPat, claim.ClaimNum); //Excludes labs. List <Procedure> listProcsForPat = Procedures.Refresh(claim.PatNum); 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; } //ACTE if (procCode.ProcCode.Length < 5 || !Regex.IsMatch(procCode.ProcCode.Substring(0, 5), @"^[0-9]{5}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Procedure code invalid '" + procCode.ProcCode + "'"); } 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); if (labProcCode.ProcCode.Length < 5 || !Regex.IsMatch(labProcCode.ProcCode.Substring(0, 5), @"^[0-9]{5}$")) { if (sbErrors.Length != 0) { sbErrors.Append(","); } sbErrors.Append("Lab code invalid '" + labProcCode.ProcCode + "'"); } } } #endregion Procedures queueItem.MissingData = sbErrors.ToString(); queueItem.Warnings = sbWarnings.ToString(); }