Beispiel #1
0
        ///<summary>Creates a general deductible of $50, a deductible of $50 on D0220, sets a $30 D0220 complete and creates a claim,
        ///creates a $100 D2750, that is TP'ed, and then creates a $30 D0220 that is TP'ed.</summary>
        ///<param name="actAssert">The first claimproc is for the D2750 and the second claimproc is for the second D0220.</param>
        public void GetDeductibleByCodeDeductLessThanGeneral(string suffix, Action <ClaimProc, ClaimProc> actAssert)
        {
            Patient pat = PatientT.CreatePatient(suffix);

            InsuranceT.AddInsurance(pat, suffix);
            List <InsSub>  listSubs     = InsSubT.GetInsSubs(pat);
            List <InsPlan> listPlans    = InsPlans.RefreshForSubList(listSubs);
            List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum);
            InsPlan        plan         = InsPlanT.GetPlanForPriSecMed(PriSecMed.Primary, listPatPlans, listPlans, listSubs);

            BenefitT.CreateDeductibleGeneral(plan.PlanNum, BenefitCoverageLevel.Individual, 50);
            BenefitT.CreateCategoryPercent(plan.PlanNum, EbenefitCategory.Diagnostic, 100);
            BenefitT.CreateCategoryPercent(plan.PlanNum, EbenefitCategory.Crowns, 50);
            BenefitT.CreateDeductible(plan.PlanNum, EbenefitCategory.Diagnostic, 0);
            BenefitT.CreateDeductible(plan.PlanNum, "D0220", 50);
            List <Benefit> listBens = Benefits.Refresh(listPatPlans, listSubs);
            Procedure      proc1    = ProcedureT.CreateProcedure(pat, "D0220", ProcStat.C, "", 30);//proc1 - Intraoral - periapical first film

            ClaimT.CreateClaim("P", listPatPlans, listPlans, new List <ClaimProc>(), new List <Procedure> {
                proc1
            }, pat, new List <Procedure> {
                proc1
            }, listBens,
                               listSubs);
            Procedure        proc2      = ProcedureT.CreateProcedure(pat, "D2750", ProcStat.TP, "", 100, priority: 0); //proc2 - Crown
            Procedure        proc3      = ProcedureT.CreateProcedure(pat, "D0220", ProcStat.TP, "", 30, priority: 1);  //proc3 - Intraoral - periapical first film
            List <ClaimProc> claimProcs = ProcedureT.ComputeEstimates(pat, listPatPlans, listPlans, listSubs, listBens);
            ClaimProc        claimProc2 = claimProcs.FirstOrDefault(x => x.ProcNum == proc2.ProcNum);
            ClaimProc        claimProc3 = claimProcs.FirstOrDefault(x => x.ProcNum == proc3.ProcNum);

            actAssert(claimProc2, claimProc3);
        }
Beispiel #2
0
        public void InsPlan_GetInsUsedDisplay_OrthoProcsNotAffectInsUsed()
        {
            string  suffix  = "13";
            Patient pat     = PatientT.CreatePatient(suffix);
            Carrier carrier = CarrierT.CreateCarrier(suffix);
            InsPlan plan    = InsPlanT.CreateInsPlan(carrier.CarrierNum);
            InsSub  sub     = InsSubT.CreateInsSub(pat.PatNum, plan.PlanNum);
            long    subNum  = sub.InsSubNum;
            PatPlan patPlan = PatPlanT.CreatePatPlan(1, pat.PatNum, subNum);

            BenefitT.CreateAnnualMax(plan.PlanNum, 100);
            BenefitT.CreateOrthoMax(plan.PlanNum, 500);
            BenefitT.CreateCategoryPercent(plan.PlanNum, EbenefitCategory.Diagnostic, 100);
            BenefitT.CreateCategoryPercent(plan.PlanNum, EbenefitCategory.Orthodontics, 100);
            Procedure proc1 = ProcedureT.CreateProcedure(pat, "D0140", ProcStat.C, "", 59);      //limEx
            Procedure proc2 = ProcedureT.CreateProcedure(pat, "D8090", ProcStat.C, "", 348);     //Comprehensive ortho

            ClaimProcT.AddInsPaid(pat.PatNum, plan.PlanNum, proc1.ProcNum, 59, subNum, 0, 0);
            ClaimProcT.AddInsPaid(pat.PatNum, plan.PlanNum, proc2.ProcNum, 348, subNum, 0, 0);
            //Lists
            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 <ClaimProcHist> histList    = ClaimProcs.GetHistList(pat.PatNum, benefitList, patPlans, planList, DateTime.Today, subList);
            //Validate
            double insUsed = InsPlans.GetInsUsedDisplay(histList, DateTime.Today, plan.PlanNum, patPlan.PatPlanNum, -1, planList, benefitList, pat.PatNum, subNum);

            Assert.AreEqual(59, insUsed);
        }
Beispiel #3
0
        public void InsPlan_GetPendingDisplay_LimitationsOverrideGeneralLimitations()
        {
            string  suffix     = "31";
            Patient pat        = PatientT.CreatePatient(suffix);
            long    patNum     = pat.PatNum;
            Carrier carrier    = CarrierT.CreateCarrier(suffix);
            InsPlan plan       = InsPlanT.CreateInsPlan(carrier.CarrierNum);
            long    planNum    = plan.PlanNum;
            InsSub  sub        = InsSubT.CreateInsSub(pat.PatNum, planNum); //guarantor is subscriber
            long    subNum     = sub.InsSubNum;
            long    patPlanNum = PatPlanT.CreatePatPlan(1, pat.PatNum, subNum).PatPlanNum;

            BenefitT.CreateAnnualMax(planNum, 1000);
            BenefitT.CreateCategoryPercent(planNum, EbenefitCategory.RoutinePreventive, 100);
            BenefitT.CreateLimitation(planNum, EbenefitCategory.RoutinePreventive, 1000);        //Changing this amount would affect patient portion vs ins portion.  But regardless of the amount, this should prevent any pending from showing in the box, which is for general pending only.
            Procedure proc = ProcedureT.CreateProcedure(pat, "D1110", ProcStat.C, "", 125);      //Prophy
            //Lists
            List <ClaimProc>     claimProcs  = ClaimProcs.Refresh(pat.PatNum);
            Family               fam         = Patients.GetFamily(patNum);
            List <InsSub>        subList     = InsSubs.RefreshForFam(fam);
            List <InsPlan>       planList    = InsPlans.RefreshForSubList(subList);
            List <PatPlan>       patPlans    = PatPlans.Refresh(patNum);
            List <Benefit>       benefitList = Benefits.Refresh(patPlans, subList);
            List <Procedure>     ProcList    = Procedures.Refresh(pat.PatNum);
            Claim                claim       = ClaimT.CreateClaim("P", patPlans, planList, claimProcs, ProcList, pat, ProcList, benefitList, subList);//Creates the claim in the same manner as the account module, including estimates and status NotReceived.
            List <ClaimProcHist> histList    = ClaimProcs.GetHistList(patNum, benefitList, patPlans, planList, DateTime.Today, subList);

            //Validate
            Assert.AreEqual(0, InsPlans.GetPendingDisplay(histList, DateTime.Today, plan, patPlanNum, -1, patNum, subNum, benefitList));
        }
Beispiel #4
0
        public void InsPlan_GetInsUsedDisplay_LimitationsOverride()
        {
            string  suffix     = "6";
            Patient pat        = PatientT.CreatePatient(suffix);
            long    patNum     = pat.PatNum;
            Carrier carrier    = CarrierT.CreateCarrier(suffix);
            InsPlan plan       = InsPlanT.CreateInsPlan(carrier.CarrierNum);
            long    planNum    = plan.PlanNum;
            InsSub  sub        = InsSubT.CreateInsSub(pat.PatNum, planNum); //guarantor is subscriber
            long    subNum     = sub.InsSubNum;
            long    patPlanNum = PatPlanT.CreatePatPlan(1, pat.PatNum, subNum).PatPlanNum;

            BenefitT.CreateAnnualMax(planNum, 1000);
            BenefitT.CreateLimitation(planNum, EbenefitCategory.Diagnostic, 1000);
            Procedure proc    = ProcedureT.CreateProcedure(pat, "D0120", ProcStat.C, "", 50);   //An exam
            long      procNum = proc.ProcNum;
            Procedure proc2   = ProcedureT.CreateProcedure(pat, "D2750", ProcStat.C, "8", 830); //create a crown

            ClaimProcT.AddInsPaid(patNum, planNum, procNum, 50, subNum, 0, 0);
            ClaimProcT.AddInsPaid(patNum, planNum, proc2.ProcNum, 400, subNum, 0, 0);
            //Lists
            Family               fam         = Patients.GetFamily(patNum);
            List <InsSub>        subList     = InsSubs.RefreshForFam(fam);
            List <InsPlan>       planList    = InsPlans.RefreshForSubList(subList);
            List <PatPlan>       patPlans    = PatPlans.Refresh(patNum);
            List <Benefit>       benefitList = Benefits.Refresh(patPlans, subList);
            List <ClaimProcHist> histList    = ClaimProcs.GetHistList(patNum, benefitList, patPlans, planList, DateTime.Today, subList);
            //Validate
            double insUsed = InsPlans.GetInsUsedDisplay(histList, DateTime.Today, planNum, patPlanNum, -1, planList, benefitList, patNum, subNum);

            Assert.AreEqual(400, insUsed);
        }
Beispiel #5
0
        ///<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);
        }
Beispiel #6
0
        ///<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));
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        public void InsPlan_GetDedRemainDisplay_IndividualAndFamilyDeductiblesInsRemaining()
        {
            string  suffix = "20";
            Patient pat    = PatientT.CreatePatient(suffix);       //guarantor
            long    patNum = pat.PatNum;
            Patient pat2   = PatientT.CreatePatient(suffix);

            PatientT.SetGuarantor(pat2, pat.PatNum);
            Patient pat3 = PatientT.CreatePatient(suffix);

            PatientT.SetGuarantor(pat3, pat.PatNum);
            Carrier carrier  = CarrierT.CreateCarrier(suffix);
            InsPlan plan     = InsPlanT.CreateInsPlan(carrier.CarrierNum);
            long    planNum  = plan.PlanNum;
            InsSub  sub      = InsSubT.CreateInsSub(pat.PatNum, planNum);      //guarantor is subscriber
            long    subNum   = sub.InsSubNum;
            PatPlan patPlan  = PatPlanT.CreatePatPlan(1, pat.PatNum, subNum);  //all three patients have the same plan
            PatPlan patPlan2 = PatPlanT.CreatePatPlan(1, pat2.PatNum, subNum); //all three patients have the same plan
            PatPlan patPlan3 = PatPlanT.CreatePatPlan(1, pat3.PatNum, subNum); //all three patients have the same plan

            BenefitT.CreateDeductibleGeneral(planNum, BenefitCoverageLevel.Individual, 75);
            BenefitT.CreateDeductibleGeneral(planNum, BenefitCoverageLevel.Family, 150);
            ClaimProcT.AddInsUsedAdjustment(pat3.PatNum, planNum, 0, subNum, 75);               //Adjustment goes on the third patient
            Procedure proc = ProcedureT.CreateProcedure(pat2, "D2750", ProcStat.C, "20", 1280); //proc for second patient with a deductible already applied.

            ClaimProcT.AddInsPaid(pat2.PatNum, planNum, proc.ProcNum, 304, subNum, 50, 597);
            proc = ProcedureT.CreateProcedure(pat, "D4355", ProcStat.TP, "", 135);      //proc is for the first patient
            long procNum = proc.ProcNum;
            //Lists
            List <ClaimProc>     claimProcs  = ClaimProcs.Refresh(patNum);
            Family               fam         = Patients.GetFamily(patNum);
            List <InsSub>        subList     = InsSubs.RefreshForFam(fam);
            List <InsPlan>       planList    = InsPlans.RefreshForSubList(subList);
            List <PatPlan>       patPlans    = PatPlans.Refresh(patNum);
            List <Benefit>       benefitList = Benefits.Refresh(patPlans, subList);
            List <ClaimProcHist> histList    = ClaimProcs.GetHistList(patNum, benefitList, patPlans, planList, DateTime.Today, subList);
            List <ClaimProcHist> loopList    = new List <ClaimProcHist>();
            //Validate
            List <ClaimProcHist> HistList = ClaimProcs.GetHistList(pat.PatNum, benefitList, patPlans, planList, DateTime.Today, subList);
            double dedFam = Benefits.GetDeductGeneralDisplay(benefitList, planNum, patPlan.PatPlanNum, BenefitCoverageLevel.Family);
            double ded    = Benefits.GetDeductGeneralDisplay(benefitList, planNum, patPlan.PatPlanNum, BenefitCoverageLevel.Individual);
            double dedRem = InsPlans.GetDedRemainDisplay(HistList, DateTime.Today, planNum, patPlan.PatPlanNum, -1, planList, pat.PatNum, ded, dedFam);  //test family and individual deductible together

            Assert.AreEqual(25, dedRem);
            dedRem = InsPlans.GetDedRemainDisplay(HistList, DateTime.Today, planNum, patPlan.PatPlanNum, -1, planList, pat.PatNum, ded, -1);  //test individual deductible by itself
            Assert.AreEqual(75, dedRem);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        public void Claims_CalculateAndUpdate_PreauthOrderWriteoff()
        {
            string suffix = MethodBase.GetCurrentMethod().Name;
            //create the patient and insurance information
            Patient pat = PatientT.CreatePatient(suffix);
            //proc - Crown
            Procedure proc         = ProcedureT.CreateProcedure(pat, "D2750", ProcStat.C, "8", 1000);
            long      feeSchedNum1 = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, suffix);

            FeeT.CreateFee(feeSchedNum1, proc.CodeNum, 900);
            Carrier carrier = CarrierT.CreateCarrier(suffix);
            InsPlan insPlan = InsPlanT.CreateInsPlanPPO(carrier.CarrierNum, feeSchedNum1);

            BenefitT.CreateAnnualMax(insPlan.PlanNum, 1000);
            BenefitT.CreateCategoryPercent(insPlan.PlanNum, EbenefitCategory.Crowns, 100);
            InsSub  sub = InsSubT.CreateInsSub(pat.PatNum, insPlan.PlanNum);
            PatPlan pp  = PatPlanT.CreatePatPlan(1, pat.PatNum, sub.InsSubNum);
            //create lists and variables required for ComputeEstimates()
            List <InsSub>    SubList         = InsSubs.RefreshForFam(Patients.GetFamily(pat.PatNum));
            List <InsPlan>   listInsPlan     = InsPlans.RefreshForSubList(SubList);
            List <PatPlan>   listPatPlan     = PatPlans.Refresh(pat.PatNum);
            List <Benefit>   listBenefits    = Benefits.Refresh(listPatPlan, SubList);
            List <Procedure> listProcsForPat = Procedures.Refresh(pat.PatNum);
            List <Procedure> procsForClaim   = new List <Procedure>();

            procsForClaim.Add(proc);
            //Create the claim and associated claimprocs
            //The order of these claimprocs is the whole point of the unit test.
            //Create Preauth
            ClaimProcs.CreateEst(new ClaimProc(), proc, insPlan, sub, 0, 500, true, true);
            //Create Estimate
            ClaimProcs.CreateEst(new ClaimProc(), proc, insPlan, sub, 1000, 1000, true, false);
            List <ClaimProc> listClaimProcs = ClaimProcs.Refresh(pat.PatNum);
            Claim            claimWaiting   = ClaimT.CreateClaim("W", listPatPlan, listInsPlan, listClaimProcs, listProcsForPat, pat, procsForClaim, listBenefits, SubList, false);

            Assert.AreEqual(100, claimWaiting.WriteOff, "WriteOff Amount");
        }
Beispiel #11
0
        public void Claims_CalculateAndUpdate_Allowed1Allowed2CompletedProcedures()
        {
            string  suffix       = "8";
            Patient pat          = PatientT.CreatePatient(suffix);
            long    patNum       = pat.PatNum;
            long    feeSchedNum1 = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, suffix);
            long    feeSchedNum2 = FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, suffix + "b");
            //Standard Fee
            long codeNum = ProcedureCodes.GetCodeNum("D2750");
            Fee  fee     = Fees.GetFee(codeNum, 53, 0, 0);

            if (fee == null)
            {
                fee          = new Fee();
                fee.CodeNum  = codeNum;
                fee.FeeSched = 53;
                fee.Amount   = 1200;
                Fees.Insert(fee);
            }
            else
            {
                fee.Amount = 1200;
                Fees.Update(fee);
            }
            //PPO fees
            fee          = new Fee();
            fee.CodeNum  = codeNum;
            fee.FeeSched = feeSchedNum1;
            fee.Amount   = 600;
            Fees.Insert(fee);
            fee          = new Fee();
            fee.CodeNum  = codeNum;
            fee.FeeSched = feeSchedNum2;
            fee.Amount   = 800;
            Fees.Insert(fee);
            //Carrier
            Carrier carrier  = CarrierT.CreateCarrier(suffix);
            long    planNum1 = InsPlanT.CreateInsPlanPPO(carrier.CarrierNum, feeSchedNum1).PlanNum;
            long    planNum2 = InsPlanT.CreateInsPlanPPO(carrier.CarrierNum, feeSchedNum2).PlanNum;
            InsSub  sub1     = InsSubT.CreateInsSub(pat.PatNum, planNum1);
            long    subNum1  = sub1.InsSubNum;
            InsSub  sub2     = InsSubT.CreateInsSub(pat.PatNum, planNum2);
            long    subNum2  = sub2.InsSubNum;

            BenefitT.CreateCategoryPercent(planNum1, EbenefitCategory.Crowns, 50);
            BenefitT.CreateCategoryPercent(planNum2, EbenefitCategory.Crowns, 50);
            BenefitT.CreateAnnualMax(planNum1, 1000);
            BenefitT.CreateAnnualMax(planNum2, 1000);
            PatPlanT.CreatePatPlan(1, patNum, subNum1);
            PatPlanT.CreatePatPlan(2, patNum, subNum2);
            Procedure proc    = ProcedureT.CreateProcedure(pat, "D2750", ProcStat.TP, "8", Fees.GetAmount0(codeNum, 53));  //crown on 8
            long      procNum = proc.ProcNum;
            //Lists
            List <ClaimProc> claimProcs  = ClaimProcs.Refresh(patNum);
            Family           fam         = Patients.GetFamily(patNum);
            List <InsSub>    subList     = InsSubs.RefreshForFam(fam);
            List <InsPlan>   planList    = InsPlans.RefreshForSubList(subList);
            List <PatPlan>   patPlans    = PatPlans.Refresh(patNum);
            List <Benefit>   benefitList = Benefits.Refresh(patPlans, subList);
            List <Procedure> procList    = Procedures.Refresh(patNum);

            //Set complete and attach to claim
            ProcedureT.SetComplete(proc, pat, planList, patPlans, claimProcs, benefitList, subList);
            claimProcs = ClaimProcs.Refresh(patNum);
            List <Procedure> procsForClaim = new List <Procedure>();

            procsForClaim.Add(proc);
            Claim claim = ClaimT.CreateClaim("P", patPlans, planList, claimProcs, procList, pat, procsForClaim, benefitList, subList);

            //Validate
            Assert.AreEqual(500, claim.WriteOff);
        }
Beispiel #12
0
        ///<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),
            });
        }
Beispiel #13
0
        ///<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);
        }
Beispiel #14
0
        public void FillInsInfo()
        {
            //Broken during overhaul of 6.7, fixed in 6.8 by DrTech
            textPriMax.Text    = "";
            textPriDed.Text    = "";
            textPriDedFam.Text = "";
            textPriDedRem.Text = "";
            textPriUsed.Text   = "";
            textPriPend.Text   = "";
            textPriRem.Text    = "";
            textSecMax.Text    = "";
            textSecDed.Text    = "";
            textSecDedFam.Text = "";
            textSecDedRem.Text = "";
            textSecUsed.Text   = "";
            textSecPend.Text   = "";
            textSecRem.Text    = "";
            if (PatCur == null)             //redundant
            {
                return;
            }
            List <InsSub>        SubList       = InsSubs.RefreshForFam(FamCur);
            List <InsPlan>       InsPlanList   = InsPlans.RefreshForSubList(SubList);
            List <PatPlan>       PatPlanList   = PatPlans.Refresh(PatCur.PatNum);
            List <Benefit>       BenefitList   = Benefits.Refresh(PatPlanList, SubList);
            List <ClaimProc>     ClaimProcList = ClaimProcs.Refresh(PatCur.PatNum);
            List <ClaimProcHist> HistList      = ClaimProcs.GetHistList(PatCur.PatNum, BenefitList, PatPlanList, InsPlanList, DateTime.Today, SubList);
            double  max     = 0;
            double  ded     = 0;
            double  dedFam  = 0;
            double  dedUsed = 0;
            double  remain  = 0;
            double  pend    = 0;
            double  used    = 0;
            InsPlan PlanCur;            //=new InsPlan();

            if (PatPlanList.Count > 0)
            {
                PlanCur = InsPlans.GetPlan(InsSubs.GetOne(PatPlanList[0].InsSubNum).PlanNum, InsPlanList);
                pend    = InsPlans.GetPendingDisplay(HistList, DateTime.Today, PlanCur, PatPlanList[0].PatPlanNum, -1, PatCur.PatNum, PatPlanList[0].InsSubNum, BenefitList);
                used    = InsPlans.GetInsUsedDisplay(HistList, DateTime.Today, PlanCur.PlanNum, PatPlanList[0].PatPlanNum,
                                                     -1, InsPlanList, BenefitList, PatCur.PatNum, PatPlanList[0].InsSubNum);
                textPriPend.Text = pend.ToString("F");
                textPriUsed.Text = used.ToString("F");
                max = Benefits.GetAnnualMaxDisplay(BenefitList, PlanCur.PlanNum, PatPlanList[0].PatPlanNum, false);
                if (max == -1)                 //if annual max is blank
                {
                    textPriMax.Text = "";
                    textPriRem.Text = "";
                }
                else
                {
                    remain = max - used - pend;
                    if (remain < 0)
                    {
                        remain = 0;
                    }
                    textPriMax.Text = max.ToString("F");
                    textPriRem.Text = remain.ToString("F");
                }
                //deductible:
                ded    = Benefits.GetDeductGeneralDisplay(BenefitList, PlanCur.PlanNum, PatPlanList[0].PatPlanNum, BenefitCoverageLevel.Individual);
                dedFam = Benefits.GetDeductGeneralDisplay(BenefitList, PlanCur.PlanNum, PatPlanList[0].PatPlanNum, BenefitCoverageLevel.Family);
                if (ded != -1)
                {
                    textPriDed.Text = ded.ToString("F");
                    dedUsed         = InsPlans.GetDedUsedDisplay(HistList, DateTime.Today, PlanCur.PlanNum, PatPlanList[0].PatPlanNum, -1, InsPlanList,
                                                                 BenefitCoverageLevel.Individual, PatCur.PatNum);
                    textPriDedRem.Text = (ded - dedUsed).ToString("F");
                }
                if (dedFam != -1)
                {
                    textPriDedFam.Text = dedFam.ToString("F");
                }
            }
            if (PatPlanList.Count > 1)
            {
                PlanCur          = InsPlans.GetPlan(InsSubs.GetOne(PatPlanList[0].InsSubNum).PlanNum, InsPlanList);
                pend             = InsPlans.GetPendingDisplay(HistList, DateTime.Today, PlanCur, PatPlanList[1].PatPlanNum, -1, PatCur.PatNum, PatPlanList[1].InsSubNum, BenefitList);
                textSecPend.Text = pend.ToString("F");
                used             = InsPlans.GetInsUsedDisplay(HistList, DateTime.Today, PlanCur.PlanNum, PatPlanList[1].PatPlanNum, -1,
                                                              InsPlanList, BenefitList, PatCur.PatNum, PatPlanList[1].InsSubNum);
                textSecUsed.Text = used.ToString("F");
                max = Benefits.GetAnnualMaxDisplay(BenefitList, PlanCur.PlanNum, PatPlanList[1].PatPlanNum, false);
                if (max == -1)
                {
                    textSecMax.Text = "";
                    textSecRem.Text = "";
                }
                else
                {
                    remain = max - used - pend;
                    if (remain < 0)
                    {
                        remain = 0;
                    }
                    textSecMax.Text = max.ToString("F");
                    textSecRem.Text = remain.ToString("F");
                }
                ded    = Benefits.GetDeductGeneralDisplay(BenefitList, PlanCur.PlanNum, PatPlanList[1].PatPlanNum, BenefitCoverageLevel.Individual);
                dedFam = Benefits.GetDeductGeneralDisplay(BenefitList, PlanCur.PlanNum, PatPlanList[1].PatPlanNum, BenefitCoverageLevel.Family);
                if (ded != -1)
                {
                    textSecDed.Text = ded.ToString("F");
                    dedUsed         = InsPlans.GetDedUsedDisplay(HistList, DateTime.Today, PlanCur.PlanNum, PatPlanList[1].PatPlanNum, -1, InsPlanList,
                                                                 BenefitCoverageLevel.Individual, PatCur.PatNum);
                    textSecDedRem.Text = (ded - dedUsed).ToString("F");
                }
                if (dedFam != -1)
                {
                    textSecDedFam.Text = dedFam.ToString("F");
                }
            }

            /*
             * //**only different line from tx pl routine fillsummary
             * if(PatPlanList.Count == 0) {
             *      labelInsLeft.Text = Lan.g(this,"No Ins.");
             *      labelInsLeftAmt.Text = "";
             * }
             * else {
             *      labelInsLeft.Text = Lan.g(this,"Ins. Left");
             *      labelInsLeftAmt.Text = textPriRem.Text;
             * }*/
        }
Beispiel #15
0
        public static void FillPtInfo(OpenDental.ContrChart sender, Patient PatCur)
        {
            //first, get all the objects we need. Because they are by ref, the original gets altered.
            ODGrid     gridPtInfo         = (ODGrid)sender.Controls.Find("gridPtInfo", true)[0];
            TabControl tabControlImages   = (TabControl)sender.Controls.Find("tabControlImages", true)[0];
            TextBox    textTreatmentNotes = (TextBox)sender.Controls.Find("textTreatmentNotes", true)[0];
            //bool TreatmentNoteChanged=sender.TreatmentNoteChanged;//might have to do a by ref here?
            //Then get some data that we need
            Family         fam            = null;
            PatientNote    PatientNoteCur = null;
            List <PatPlan> PatPlanList    = null;
            List <InsSub>  SubList        = null;
            List <InsPlan> PlanList       = null;

            if (PatCur != null)
            {
                fam            = Patients.GetFamily(PatCur.PatNum);
                PatientNoteCur = PatientNotes.Refresh(PatCur.PatNum, PatCur.Guarantor);
                PatPlanList    = PatPlans.Refresh(PatCur.PatNum);
                SubList        = InsSubs.RefreshForFam(fam);
                PlanList       = InsPlans.RefreshForSubList(SubList);
            }
            //Then, continue with the slightly altered original method.
            gridPtInfo.Height       = tabControlImages.Top - gridPtInfo.Top;
            textTreatmentNotes.Text = "";
            if (PatCur != null)
            {
                textTreatmentNotes.Text    = PatientNoteCur.Treatment;
                textTreatmentNotes.Enabled = true;
                textTreatmentNotes.Select(textTreatmentNotes.Text.Length + 2, 1);
                textTreatmentNotes.ScrollToCaret();
                sender.TreatmentNoteChanged = false;
            }
            gridPtInfo.BeginUpdate();
            gridPtInfo.Columns.Clear();
            ODGridColumn col = new ODGridColumn("", 100);         //Lan.g("TableChartPtInfo",""),);

            gridPtInfo.Columns.Add(col);
            col = new ODGridColumn("", 300);
            gridPtInfo.Columns.Add(col);
            gridPtInfo.Rows.Clear();
            if (PatCur == null)
            {
                gridPtInfo.EndUpdate();
                return;
            }
            ODGridRow row;

            //Age
            row = new ODGridRow();
            row.Cells.Add("Age");
            row.Cells.Add(PatientLogic.DateToAgeString(PatCur.Birthdate));
            row.Tag = null;
            gridPtInfo.Rows.Add(row);
            //Credit type
            row = new ODGridRow();
            row.Cells.Add(Lan.g("TableChartPtInfo", "ABC0"));
            row.Cells.Add(PatCur.CreditType);
            row.Tag = null;
            gridPtInfo.Rows.Add(row);
            //Billing type
            row = new ODGridRow();
            row.Cells.Add(Lan.g("TableChartPtInfo", "Billing Type"));
            row.Cells.Add(DefC.GetName(DefCat.BillingTypes, PatCur.BillingType));
            row.Tag = null;
            gridPtInfo.Rows.Add(row);
            //Referrals
            RefAttach[] RefAttachList = RefAttaches.Refresh(PatCur.PatNum);
            for (int i = 0; i < RefAttachList.Length; i++)
            {
                row            = new ODGridRow();
                row.ColorBackG = Color.Aquamarine;
                if (RefAttachList[i].IsFrom)
                {
                    row.Cells.Add("Referred From");
                }
                else
                {
                    row.Cells.Add("Referred To");
                }
                row.Cells.Add(Referrals.GetNameLF(RefAttachList[i].ReferralNum));
                row.Tag = null;
                gridPtInfo.Rows.Add(row);
            }
            //Date First Visit
            row = new ODGridRow();
            row.Cells.Add(Lan.g("TableChartPtInfo", "Date First Visit"));
            if (PatCur.DateFirstVisit.Year < 1880)
            {
                row.Cells.Add("??");
            }
            else if (PatCur.DateFirstVisit == DateTime.Today)
            {
                row.Cells.Add(Lan.g("TableChartPtInfo", "NEW PAT"));
            }
            else
            {
                row.Cells.Add(PatCur.DateFirstVisit.ToShortDateString());
            }
            row.Tag = null;
            gridPtInfo.Rows.Add(row);
            //Prov - Pri & Sec
            row = new ODGridRow();
            row.Cells.Add(Lan.g("TableChartPtInfo", "Prov. (Pri, Sec)"));
            if (PatCur.SecProv != 0)
            {
                row.Cells.Add(Providers.GetAbbr(PatCur.PriProv) + ", " + Providers.GetAbbr(PatCur.SecProv));
            }
            else
            {
                row.Cells.Add(Providers.GetAbbr(PatCur.PriProv) + ", " + "None");
            }
            row.Tag = null;
            gridPtInfo.Rows.Add(row);
            //PriIns
            row = new ODGridRow();
            row.Cells.Add(Lan.g("TableChartPtInfo", "Pri Ins"));
            string name;

            if (PatPlanList.Count > 0)
            {
                name = InsPlans.GetCarrierName(PatPlans.GetPlanNum(PatPlanList, 1), PlanList);
                if (PatPlanList[0].IsPending)
                {
                    name += Lan.g("TableChartPtInfo", " (pending)");
                }
                row.Cells.Add(name);
            }
            else
            {
                row.Cells.Add("");
            }
            row.Tag = null;
            gridPtInfo.Rows.Add(row);
            //SecIns
            row = new ODGridRow();
            row.Cells.Add(Lan.g("TableChartPtInfo", "Sec Ins"));
            if (PatPlanList.Count > 1)
            {
                name = InsPlans.GetCarrierName(PatPlans.GetPlanNum(PatPlanList, 2), PlanList);
                if (PatPlanList[1].IsPending)
                {
                    name += Lan.g("TableChartPtInfo", " (pending)");
                }
                row.Cells.Add(name);
            }
            else
            {
                row.Cells.Add("");
            }
            row.Tag = null;
            gridPtInfo.Rows.Add(row);
            //Registration keys-------------------------------------------------------------------------------------------
            if (PrefC.GetBool(PrefName.DistributorKey))
            {
                RegistrationKey[] keys = RegistrationKeys.GetForPatient(PatCur.PatNum);
                for (int i = 0; i < keys.Length; i++)
                {
                    row = new ODGridRow();
                    row.Cells.Add(Lan.g("TableChartPtInfo", "Registration Key"));
                    string str = keys[i].RegKey.Substring(0, 4) + "-" + keys[i].RegKey.Substring(4, 4) + "-" +
                                 keys[i].RegKey.Substring(8, 4) + "-" + keys[i].RegKey.Substring(12, 4);
                    if (keys[i].IsForeign)
                    {
                        str += "\r\nForeign";
                    }
                    else
                    {
                        str += "\r\nUSA";
                    }
                    str += "\r\nStarted: " + keys[i].DateStarted.ToShortDateString();
                    if (keys[i].DateDisabled.Year > 1880)
                    {
                        str += "\r\nDisabled: " + keys[i].DateDisabled.ToShortDateString();
                    }
                    if (keys[i].DateEnded.Year > 1880)
                    {
                        str += "\r\nEnded: " + keys[i].DateEnded.ToShortDateString();
                    }
                    if (keys[i].Note != "")
                    {
                        str += keys[i].Note;
                    }
                    row.Cells.Add(str);
                    row.Tag = keys[i].Copy();
                    gridPtInfo.Rows.Add(row);
                }
            }
            ODGridCell cell;
            //medical fields-----------------------------------------------------------------
            bool showMed = true;

            if (Programs.IsEnabled(ProgramName.eClinicalWorks) && ProgramProperties.GetPropVal(ProgramName.eClinicalWorks, "IsStandalone") == "0")
            {
                showMed = false;
            }
            if (showMed)
            {
                //premed flag.
                if (PatCur.Premed)
                {
                    row = new ODGridRow();
                    row.Cells.Add("");
                    cell           = new ODGridCell();
                    cell.Text      = Lan.g("TableChartPtInfo", "Premedicate");
                    cell.ColorText = Color.Red;
                    cell.Bold      = YN.Yes;
                    row.Cells.Add(cell);
                    row.ColorBackG = DefC.Long[(int)DefCat.MiscColors][3].ItemColor;
                    row.Tag        = "med";
                    gridPtInfo.Rows.Add(row);
                }
                //diseases
                Disease[] DiseaseList = Diseases.Refresh(PatCur.PatNum);
                row       = new ODGridRow();
                cell      = new ODGridCell(Lan.g("TableChartPtInfo", "Diseases"));
                cell.Bold = YN.Yes;
                row.Cells.Add(cell);
                if (DiseaseList.Length > 0)
                {
                    row.Cells.Add("");
                }
                else
                {
                    row.Cells.Add(Lan.g("TableChartPtInfo", "none"));
                }
                row.ColorBackG = DefC.Long[(int)DefCat.MiscColors][3].ItemColor;
                row.Tag        = "med";
                gridPtInfo.Rows.Add(row);
                for (int i = 0; i < DiseaseList.Length; i++)
                {
                    row            = new ODGridRow();
                    cell           = new ODGridCell(DiseaseDefs.GetName(DiseaseList[i].DiseaseDefNum));
                    cell.ColorText = Color.Red;
                    cell.Bold      = YN.Yes;
                    row.Cells.Add(cell);
                    row.Cells.Add(DiseaseList[i].PatNote);
                    row.ColorBackG = DefC.Long[(int)DefCat.MiscColors][3].ItemColor;
                    row.Tag        = "med";
                    gridPtInfo.Rows.Add(row);
                }
                //MedUrgNote
                row = new ODGridRow();
                row.Cells.Add(Lan.g("TableChartPtInfo", "Med Urgent"));
                cell           = new ODGridCell();
                cell.Text      = PatCur.MedUrgNote;
                cell.ColorText = Color.Red;
                cell.Bold      = YN.Yes;
                row.Cells.Add(cell);
                row.ColorBackG = DefC.Long[(int)DefCat.MiscColors][3].ItemColor;
                row.Tag        = "med";
                gridPtInfo.Rows.Add(row);
                //Medical
                row = new ODGridRow();
                row.Cells.Add(Lan.g("TableChartPtInfo", "Medical Summary"));
                row.Cells.Add(PatientNoteCur.Medical);
                row.ColorBackG = DefC.Long[(int)DefCat.MiscColors][3].ItemColor;
                row.Tag        = "med";
                gridPtInfo.Rows.Add(row);
                //Service
                row = new ODGridRow();
                row.Cells.Add(Lan.g("TableChartPtInfo", "Service Notes"));
                row.Cells.Add(PatientNoteCur.Service);
                row.ColorBackG = DefC.Long[(int)DefCat.MiscColors][3].ItemColor;
                row.Tag        = "med";
                gridPtInfo.Rows.Add(row);
                //medications
                Medications.Refresh();
                MedicationPats.Refresh(PatCur.PatNum);
                row       = new ODGridRow();
                cell      = new ODGridCell(Lan.g("TableChartPtInfo", "Medications"));
                cell.Bold = YN.Yes;
                row.Cells.Add(cell);
                if (MedicationPats.List.Length > 0)
                {
                    row.Cells.Add("");
                }
                else
                {
                    row.Cells.Add(Lan.g("TableChartPtInfo", "none"));
                }
                row.ColorBackG = DefC.Long[(int)DefCat.MiscColors][3].ItemColor;
                row.Tag        = "med";
                gridPtInfo.Rows.Add(row);
                string     text;
                Medication med;
                for (int i = 0; i < MedicationPats.List.Length; i++)
                {
                    row  = new ODGridRow();
                    med  = Medications.GetMedication(MedicationPats.List[i].MedicationNum);
                    text = med.MedName;
                    if (med.MedicationNum != med.GenericNum)
                    {
                        text += "(" + Medications.GetMedication(med.GenericNum).MedName + ")";
                    }
                    row.Cells.Add(text);
                    text = MedicationPats.List[i].PatNote
                           + "(" + Medications.GetGeneric(MedicationPats.List[i].MedicationNum).Notes + ")";
                    row.Cells.Add(text);
                    row.ColorBackG = DefC.Long[(int)DefCat.MiscColors][3].ItemColor;
                    row.Tag        = "med";
                    gridPtInfo.Rows.Add(row);
                }
            }            //if !eCW.enabled
            gridPtInfo.EndUpdate();
        }
Beispiel #16
0
        ///<summary>Most of the logic for breaking an appointment. Pass in the brokenFee (the number the user enters in the brokenAppointment window),
        ///Optionally pass in if the brokenappointment procedure is being deleted. Returns the broken procedure that was created.</summary>
        public static Procedure BreakAppointment(Appointment appt, Patient pat, ProcedureCode procCode, double feeOverride, bool isDeleteBrokenProc = false)
        {
            //suppressHistory is true due to below logic creating a log with a specific HistAppointmentAction instead of the generic changed.
            DateTime datePrevious    = appt.DateTStamp;
            bool     suppressHistory = false;

            if (procCode != null)
            {
                suppressHistory = procCode.ProcCode == "D9986" || procCode.ProcCode == "D9987";
            }
            Appointments.SetAptStatus(appt, ApptStatus.Broken, suppressHistory); //Appointments S-Class handles Signalods
            if (appt.AptStatus != ApptStatus.Complete)                           //seperate log entry for completed appointments.
            {
                SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit, pat.PatNum,
                                          appt.ProcDescript + ", " + appt.AptDateTime.ToString()
                                          + ", Broken from the Appts module.", appt.AptNum, datePrevious);
            }
            else
            {
                SecurityLogs.MakeLogEntry(Permissions.AppointmentCompleteEdit, pat.PatNum,
                                          appt.ProcDescript + ", " + appt.AptDateTime.ToString()
                                          + ", Broken from the Appts module.", appt.AptNum, datePrevious);
            }
            List <Procedure> listProcedures = Procedures.GetProcsForSingle(appt.AptNum, false);
            //splits should only exist on procs if they are using tp pre-payments
            List <PaySplit> listSplitsForApptProcs = new List <PaySplit>();
            bool            isNonRefundable        = false;
            double          brokenProcAmount       = 0;

            if (listProcedures.Count > 0)
            {
                listSplitsForApptProcs = PaySplits.GetPaySplitsFromProcs(listProcedures.Select(x => x.ProcNum).ToList());
            }
            Procedure brokenProcedure = new Procedure();

            #region Charting the proc
            if (procCode != null)
            {
                switch (procCode.ProcCode)
                {
                case "D9986":                        //Missed
                    HistAppointments.CreateHistoryEntry(appt.AptNum, HistAppointmentAction.Missed);
                    break;

                case "D9987":                        //Cancelled
                    HistAppointments.CreateHistoryEntry(appt.AptNum, HistAppointmentAction.Cancelled);
                    break;
                }
                brokenProcedure.PatNum       = pat.PatNum;
                brokenProcedure.ProvNum      = (procCode.ProvNumDefault > 0 ? procCode.ProvNumDefault : appt.ProvNum);
                brokenProcedure.CodeNum      = procCode.CodeNum;
                brokenProcedure.ProcDate     = DateTime.Today;
                brokenProcedure.DateEntryC   = DateTime.Now;
                brokenProcedure.ProcStatus   = ProcStat.C;
                brokenProcedure.ClinicNum    = appt.ClinicNum;
                brokenProcedure.UserNum      = Security.CurUser.UserNum;
                brokenProcedure.Note         = Lans.g("AppointmentEdit", "Appt BROKEN for") + " " + appt.ProcDescript + "  " + appt.AptDateTime.ToString();
                brokenProcedure.PlaceService = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService);              //Default proc place of service for the Practice is used.
                List <InsSub>  listInsSubs    = InsSubs.RefreshForFam(Patients.GetFamily(pat.PatNum));
                List <InsPlan> listInsPlans   = InsPlans.RefreshForSubList(listInsSubs);
                List <PatPlan> listPatPlans   = PatPlans.Refresh(pat.PatNum);
                InsPlan        insPlanPrimary = null;
                InsSub         insSubPrimary  = null;
                if (listPatPlans.Count > 0)
                {
                    insSubPrimary  = InsSubs.GetSub(listPatPlans[0].InsSubNum, listInsSubs);
                    insPlanPrimary = InsPlans.GetPlan(insSubPrimary.PlanNum, listInsPlans);
                }
                double procFee;
                long   feeSch;
                if (insPlanPrimary == null || procCode.NoBillIns)
                {
                    feeSch = FeeScheds.GetFeeSched(0, pat.FeeSched, brokenProcedure.ProvNum);
                }
                else                  //Only take into account the patient's insurance fee schedule if the D9986 procedure is not marked as NoBillIns
                {
                    feeSch = FeeScheds.GetFeeSched(insPlanPrimary.FeeSched, pat.FeeSched, brokenProcedure.ProvNum);
                }
                procFee = Fees.GetAmount0(brokenProcedure.CodeNum, feeSch, brokenProcedure.ClinicNum, brokenProcedure.ProvNum);
                if (insPlanPrimary != null && insPlanPrimary.PlanType == "p" && !insPlanPrimary.IsMedical)         //PPO
                {
                    double provFee = Fees.GetAmount0(brokenProcedure.CodeNum, Providers.GetProv(brokenProcedure.ProvNum).FeeSched, brokenProcedure.ClinicNum,
                                                     brokenProcedure.ProvNum);
                    brokenProcedure.ProcFee = Math.Max(provFee, procFee);
                }
                else
                {
                    brokenProcedure.ProcFee = procFee;
                }
                if (!PrefC.GetBool(PrefName.EasyHidePublicHealth))
                {
                    brokenProcedure.SiteNum = pat.SiteNum;
                }
                Procedures.Insert(brokenProcedure);
                Procedure procOld = brokenProcedure.Copy();
                //Now make a claimproc if the patient has insurance.  We do this now for consistency because a claimproc could get created in the future.
                List <Benefit>   listBenefits          = Benefits.Refresh(listPatPlans, listInsSubs);
                List <ClaimProc> listClaimProcsForProc = ClaimProcs.RefreshForProc(brokenProcedure.ProcNum);
                Procedures.ComputeEstimates(brokenProcedure, pat.PatNum, listClaimProcsForProc, false, listInsPlans, listPatPlans, listBenefits, pat.Age, listInsSubs);
                if (listSplitsForApptProcs.Count > 0 && PrefC.GetBool(PrefName.TpPrePayIsNonRefundable) && procCode.ProcCode == "D9986")
                {
                    //if there are pre-payments, non-refundable pre-payments is turned on, and the broken appointment is a missed code then auto-fill
                    //the window with the sum of the procs for the appointment. Transfer money below after broken procedure is confirmed by the user.
                    //normally goes to the form to let the user speficy, this is the auto filled amount for the form.
                    brokenProcedure.ProcFee = feeOverride;                  //listSplitsForApptProcs.Sum(x => x.SplitAmt);
                    isNonRefundable         = true;
                }
                if (isDeleteBrokenProc)
                {
                    brokenProcedure.ProcStatus = ProcStat.D;
                }
                brokenProcedure.ProcFee = feeOverride;
                brokenProcAmount        = feeOverride;
                Procedures.Update(brokenProcedure, procOld);
            }
            #endregion
            //Note this MUST come after FormProcBroken since clicking cancel in that window will delete the procedure.
            if (isNonRefundable && !isDeleteBrokenProc && listSplitsForApptProcs.Count > 0)
            {
                //transfer what the user specified in the broken appointment window.
                //transfer up to the amount specified by the user
                foreach (Procedure proc in listProcedures)
                {
                    if (brokenProcAmount == 0)
                    {
                        break;
                    }
                    List <PaySplit> listSplitsForAppointmentProcedure = listSplitsForApptProcs.FindAll(x => x.ProcNum == proc.ProcNum);
                    foreach (PaySplit split in listSplitsForAppointmentProcedure)
                    {
                        if (brokenProcAmount == 0)
                        {
                            break;
                        }
                        double amt = Math.Min(brokenProcAmount, split.SplitAmt);
                        Payments.CreateTransferForTpProcs(proc, new List <PaySplit> {
                            split
                        }, brokenProcedure, amt);
                        brokenProcAmount -= amt;
                    }
                }
            }
            return(brokenProcedure);
        }
        ///<summary>Returns null if there is no HL7Def enabled or if there is no outbound DFT defined for the enabled HL7Def.</summary>
        public static MessageHL7 GenerateDFT(List <Procedure> listProcs, EventTypeHL7 eventType, Patient pat, Patient guar, long aptNum, string pdfDescription, string pdfDataString)
        {
            //In \\SERVERFILES\storage\OPEN DENTAL\Programmers Documents\Standards (X12, ADA, etc)\HL7\Version2.6\V26_CH02_Control_M4_JAN2007.doc
            //On page 28, there is a Message Construction Pseudocode as well as a flowchart which might help.
            MessageHL7 msgHl7 = new MessageHL7(MessageTypeHL7.DFT);
            HL7Def     hl7Def = HL7Defs.GetOneDeepEnabled();

            if (hl7Def == null)
            {
                return(null);
            }
            //find a DFT message in the def
            HL7DefMessage hl7DefMessage = null;

            for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++)
            {
                if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.DFT && hl7Def.hl7DefMessages[i].InOrOut == InOutHL7.Outgoing)
                {
                    hl7DefMessage = hl7Def.hl7DefMessages[i];
                    //continue;
                    break;
                }
            }
            if (hl7DefMessage == null)           //DFT message type is not defined so do nothing and return
            {
                return(null);
            }
            if (PrefC.GetBool(PrefName.ShowFeaturePatientClone))
            {
                pat = Patients.GetOriginalPatientForClone(pat);
            }
            Provider       prov         = Providers.GetProv(Patients.GetProvNum(pat));
            Appointment    apt          = Appointments.GetOneApt(aptNum);
            List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum);

            for (int i = 0; i < hl7DefMessage.hl7DefSegments.Count; i++)
            {
                int repeatCount = 1;
                if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.FT1)
                {
                    repeatCount = listProcs.Count;
                }
                else if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)
                {
                    repeatCount = listPatPlans.Count;
                }
                //for example, countRepeat can be zero in the case where we are only sending a PDF of the TP to eCW, and no procs.
                //or the patient does not have any current insplans for IN1 segments
                for (int j = 0; j < repeatCount; j++)           //FT1 is optional and can repeat so add as many FT1's as procs in procList, IN1 is optional and can repeat as well, repeat for the number of patplans in patplanList
                {
                    if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.FT1 && listProcs.Count > j)
                    {
                        prov = Providers.GetProv(listProcs[j].ProvNum);
                    }
                    Procedure proc = null;
                    if (listProcs.Count > j)                   //procList could be an empty list
                    {
                        proc = listProcs[j];
                    }
                    PatPlan patPlanCur = null;
                    InsPlan insPlanCur = null;
                    InsSub  insSubCur  = null;
                    Carrier carrierCur = null;
                    Patient subscriber = null;
                    if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)
                    {
                        patPlanCur = listPatPlans[j];
                        insSubCur  = InsSubs.GetOne(patPlanCur.InsSubNum);
                        insPlanCur = InsPlans.RefreshOne(insSubCur.PlanNum);
                        carrierCur = Carriers.GetCarrier(insPlanCur.CarrierNum);
                        subscriber = Patients.GetPat(insSubCur.Subscriber);
                    }
                    SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName);
                    seg.SetField(0, hl7DefMessage.hl7DefSegments[i].SegmentName.ToString());
                    for (int f = 0; f < hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count; f++)
                    {
                        string fieldName = hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].FieldName;
                        if (fieldName == "")                       //If fixed text instead of field name just add text to segment
                        {
                            seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].OrdinalPos, hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].FixedText);
                        }
                        else
                        {
                            string fieldValue = "";
                            if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)
                            {
                                fieldValue = FieldConstructor.GenerateFieldIN1(hl7Def, fieldName, j + 1, patPlanCur, insSubCur, insPlanCur, carrierCur, listPatPlans.Count, subscriber);
                            }
                            else
                            {
                                fieldValue = FieldConstructor.GenerateField(hl7Def, fieldName, MessageTypeHL7.DFT, pat, prov, proc, guar, apt, j + 1, eventType,
                                                                            pdfDescription, pdfDataString, MessageStructureHL7.DFT_P03, seg.Name);
                            }
                            seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].OrdinalPos, fieldValue);
                        }
                    }
                    msgHl7.Segments.Add(seg);
                }
            }
            return(msgHl7);
        }
        ///<summary>Sends data for Patient.Cur to an export file and then launches an exe to notify PT.  If patient exists, this simply opens the patient.  If patient does not exist, then this triggers creation of the patient in PT Dental.  If isUpdate is true, then the export file and exe will have different names. In PT, update is a separate programlink with a separate button.</summary>
        public static void SendData(Program ProgramCur, Patient pat, bool isUpdate)
        {
            //ArrayList ForProgram=ProgramProperties.GetForProgram(ProgramCur.ProgramNum);
            //ProgramProperty PPCur=ProgramProperties.GetCur(ForProgram, "InfoFile path");
            //string infoFile=PPCur.PropertyValue;
            if (!Directory.Exists(dir))
            {
                MessageBox.Show(dir + " does not exist.  PT Dental doesn't seem to be properly installed on this computer.");
                return;
            }
            if (pat == null)
            {
                MessageBox.Show("No patient is selected.");
                return;
            }
            if (!File.Exists(dir + "\\" + exportAddExe))
            {
                MessageBox.Show(dir + "\\" + exportAddExe + " does not exist.  PT Dental doesn't seem to be properly installed on this computer.");
                return;
            }
            if (!File.Exists(dir + "\\" + exportUpdateExe))
            {
                MessageBox.Show(dir + "\\" + exportUpdateExe + " does not exist.  PT Dental doesn't seem to be properly installed on this computer.");
                return;
            }
            string filename = dir + "\\" + exportAddCsv;

            if (isUpdate)
            {
                filename = dir + "\\" + exportUpdateCsv;
            }
            using (StreamWriter sw = new StreamWriter(filename, false)){               //overwrites if it already exists.
                sw.WriteLine("PAT_PK,PAT_LOGFK,PAT_LANFK,PAT_TITLE,PAT_FNAME,PAT_MI,PAT_LNAME,PAT_CALLED,PAT_ADDR1,PAT_ADDR2,PAT_CITY,PAT_ST,PAT_ZIP,PAT_HPHN,PAT_WPHN,PAT_EXT,PAT_FAX,PAT_PAGER,PAT_CELL,PAT_EMAIL,PAT_SEX,PAT_EDOCS,PAT_STATUS,PAT_TYPE,PAT_BIRTH,PAT_SSN,PAT_NOCALL,PAT_NOCORR,PAT_DISRES,PAT_LSTUPD,PAT_INSNM,PAT_INSGPL,PAT_INSAD1,PAT_INSAD2,PAT_INSCIT,PAT_INSST,PAT_INSZIP,PAT_INSPHN,PAT_INSEXT,PAT_INSCON,PAT_INSGNO,PAT_EMPNM,PAT_EMPAD1,PAT_EMPAD2,PAT_EMPCIT,PAT_EMPST,PAT_EMPZIP,PAT_EMPPHN,PAT_REFLNM,PAT_REFFNM,PAT_REFMI,PAT_REFPHN,PAT_REFEML,PAT_REFSPE,PAT_NOTES,PAT_FPSCAN,PAT_PREMED,PAT_MEDS,PAT_FTSTUD,PAT_PTSTUD,PAT_COLLEG,PAT_CHRTNO,PAT_OTHID,PAT_RESPRT,PAT_POLHLD,PAT_CUSCD,PAT_PMPID");
                sw.Write(",");                                                         //PAT_PK  Primary key. Long alphanumeric. We do not use.
                sw.Write(",");                                                         //PAT_LOGFK Internal PT logical, it can be ignored.
                sw.Write(",");                                                         //PAT_LANFK Internal PT logical, it can be ignored.
                sw.Write(",");                                                         //PAT_TITLE We do not have this field yet
                sw.Write(Tidy(pat.FName) + ",");                                       //PAT_FNAME
                sw.Write(Tidy(pat.MiddleI) + ",");                                     //PAT_MI
                sw.Write(Tidy(pat.LName) + ",");                                       //PAT_LNAME
                sw.Write(Tidy(pat.Preferred) + ",");                                   //PAT_CALLED Nickname
                sw.Write(Tidy(pat.Address) + ",");                                     //PAT_ADDR1
                sw.Write(Tidy(pat.Address2) + ",");                                    //PAT_ADDR2
                sw.Write(Tidy(pat.City) + ",");                                        //PAT_CITY
                sw.Write(Tidy(pat.State) + ",");                                       //PAT_ST
                sw.Write(Tidy(pat.Zip) + ",");                                         //PAT_ZIP
                sw.Write(TelephoneNumbers.FormatNumbersOnly(pat.HmPhone) + ",");       //PAT_HPHN No punct
                sw.Write(TelephoneNumbers.FormatNumbersOnly(pat.WkPhone) + ",");       //PAT_WPHN
                sw.Write(",");                                                         //PAT_EXT
                sw.Write(",");                                                         //PAT_FAX
                sw.Write(",");                                                         //PAT_PAGER
                sw.Write(TelephoneNumbers.FormatNumbersOnly(pat.WirelessPhone) + ","); //PAT_CELL
                sw.Write(Tidy(pat.Email) + ",");                                       //PAT_EMAIL
                if (pat.Gender == PatientGender.Female)
                {
                    sw.Write("Female");
                }
                else if (pat.Gender == PatientGender.Male)
                {
                    sw.Write("Male");
                }
                sw.Write(",");                            //PAT_SEX might be blank if unknown
                sw.Write(",");                            //PAT_EDOCS Internal PT logical, it can be ignored.
                sw.Write(pat.PatStatus.ToString() + ","); //PAT_STATUS Any text allowed
                sw.Write(pat.Position.ToString() + ",");  //PAT_TYPE Any text allowed
                if (pat.Birthdate.Year > 1880)
                {
                    sw.Write(pat.Birthdate.ToString("MM/dd/yyyy"));                    //PAT_BIRTH MM/dd/yyyy
                }
                sw.Write(",");
                sw.Write(Tidy(pat.SSN) + ",");              //PAT_SSN No punct
                if (pat.PreferContactMethod == ContactMethod.DoNotCall ||
                    pat.PreferConfirmMethod == ContactMethod.DoNotCall ||
                    pat.PreferRecallMethod == ContactMethod.DoNotCall)
                {
                    sw.Write("1");
                }
                sw.Write(",");                //PAT_NOCALL T if no call
                sw.Write(",");                //PAT_NOCORR No correspondence HIPAA
                sw.Write(",");                //PAT_DISRES Internal PT logical, it can be ignored.
                sw.Write(",");                //PAT_LSTUPD Internal PT logical, it can be ignored.
                List <PatPlan> patPlanList = PatPlans.Refresh(pat.PatNum);
                Family         fam         = Patients.GetFamily(pat.PatNum);
                List <InsSub>  subList     = InsSubs.RefreshForFam(fam);
                List <InsPlan> planList    = InsPlans.RefreshForSubList(subList);
                PatPlan        patplan     = null;
                InsSub         sub         = null;
                InsPlan        plan        = null;
                Carrier        carrier     = null;
                Employer       emp         = null;
                if (patPlanList.Count > 0)
                {
                    patplan = patPlanList[0];
                    sub     = InsSubs.GetSub(patplan.InsSubNum, subList);
                    plan    = InsPlans.GetPlan(sub.PlanNum, planList);
                    carrier = Carriers.GetCarrier(plan.CarrierNum);
                    if (plan.EmployerNum != 0)
                    {
                        emp = Employers.GetEmployer(plan.EmployerNum);
                    }
                }
                if (plan == null)
                {
                    sw.Write(",");                    //PAT_INSNM
                    sw.Write(",");                    //PAT_INSGPL Ins group plan name
                    sw.Write(",");                    //PAT_INSAD1
                    sw.Write(",");                    //PAT_INSAD2
                    sw.Write(",");                    //PAT_INSCIT
                    sw.Write(",");                    //PAT_INSST
                    sw.Write(",");                    //PAT_INSZIP
                    sw.Write(",");                    //PAT_INSPHN
                }
                else
                {
                    sw.Write(Tidy(carrier.CarrierName) + ",");                         //PAT_INSNM
                    sw.Write(Tidy(plan.GroupName) + ",");                              //PAT_INSGPL Ins group plan name
                    sw.Write(Tidy(carrier.Address) + ",");                             //PAT_INSAD1
                    sw.Write(Tidy(carrier.Address2) + ",");                            //PAT_INSAD2
                    sw.Write(Tidy(carrier.City) + ",");                                //PAT_INSCIT
                    sw.Write(Tidy(carrier.State) + ",");                               //PAT_INSST
                    sw.Write(Tidy(carrier.Zip) + ",");                                 //PAT_INSZIP
                    sw.Write(TelephoneNumbers.FormatNumbersOnly(carrier.Phone) + ","); //PAT_INSPHN
                }
                sw.Write(",");                                                         //PAT_INSEXT
                sw.Write(",");                                                         //PAT_INSCON Ins contact person
                if (plan == null)
                {
                    sw.Write(",");
                }
                else
                {
                    sw.Write(Tidy(plan.GroupNum) + ",");                  //PAT_INSGNO Ins group number
                }
                if (emp == null)
                {
                    sw.Write(",");                    //PAT_EMPNM
                }
                else
                {
                    sw.Write(Tidy(emp.EmpName) + ","); //PAT_EMPNM
                }
                sw.Write(",");                         //PAT_EMPAD1
                sw.Write(",");                         //PAT_EMPAD2
                sw.Write(",");                         //PAT_EMPCIT
                sw.Write(",");                         //PAT_EMPST
                sw.Write(",");                         //PAT_EMPZIP
                sw.Write(",");                         //PAT_EMPPHN

                /*we don't support employer info yet.
                 * sw.Write(Tidy(emp.Address)+",");//PAT_EMPAD1
                 * sw.Write(Tidy(emp.Address2)+",");//PAT_EMPAD2
                 * sw.Write(Tidy(emp.City)+",");//PAT_EMPCIT
                 * sw.Write(Tidy(emp.State)+",");//PAT_EMPST
                 * sw.Write(Tidy(emp.State)+",");//PAT_EMPZIP
                 * sw.Write(TelephoneNumbers.FormatNumbersOnly(emp.Phone)+",");//PAT_EMPPHN*/
                Referral referral = Referrals.GetReferralForPat(pat.PatNum);              //could be null
                if (referral == null)
                {
                    sw.Write(",");                    //PAT_REFLNM
                    sw.Write(",");                    //PAT_REFFNM
                    sw.Write(",");                    //PAT_REFMI
                    sw.Write(",");                    //PAT_REFPHN
                    sw.Write(",");                    //PAT_REFEML Referral source email
                    sw.Write(",");                    //PAT_REFSPE Referral specialty. Customizable, so any allowed
                }
                else
                {
                    sw.Write(Tidy(referral.LName) + ",");                //PAT_REFLNM
                    sw.Write(Tidy(referral.FName) + ",");                //PAT_REFFNM
                    sw.Write(Tidy(referral.MName) + ",");                //PAT_REFMI
                    sw.Write(referral.Telephone + ",");                  //PAT_REFPHN
                    sw.Write(Tidy(referral.EMail) + ",");                //PAT_REFEML Referral source email
                    if (referral.PatNum == 0 && !referral.NotPerson)     //not a patient, and is a person
                    {
                        sw.Write(Defs.GetName(DefCat.ProviderSpecialties, referral.Specialty));
                    }
                    sw.Write(",");            //PAT_REFSPE Referral specialty. Customizable, so any allowed
                }
                sw.Write(",");                //PAT_NOTES No limits.  We won't use this right now for exports.
                //sw.Write(",");//PAT_NOTE1-PAT_NOTE10 skipped
                sw.Write(",");                //PAT_FPSCAN Internal PT logical, it can be ignored.
                if (pat.Premed)
                {
                    sw.Write("1");
                }
                else
                {
                    sw.Write("0");
                }
                sw.Write(",");                        //PAT_PREMED F or T
                sw.Write(Tidy(pat.MedUrgNote) + ","); //PAT_MEDS The meds that they must premedicate with.
                if (pat.StudentStatus == "F")         //fulltime
                {
                    sw.Write("1");
                }
                else
                {
                    sw.Write("0");
                }
                sw.Write(",");                //PAT_FTSTUD T/F
                if (pat.StudentStatus == "P") //parttime
                {
                    sw.Write("1");
                }
                else
                {
                    sw.Write("0");
                }
                sw.Write(",");                         //PAT_PTSTUD
                sw.Write(Tidy(pat.SchoolName) + ",");  //PAT_COLLEG Name of college
                sw.Write(Tidy(pat.ChartNumber) + ","); //PAT_CHRTNO
                sw.Write(pat.PatNum.ToString() + ","); //PAT_OTHID The primary key in Open Dental ************IMPORTANT***************
                if (pat.PatNum == pat.Guarantor)
                {
                    sw.Write("1");
                }
                else
                {
                    sw.Write("0");
                }
                sw.Write(",");                                    //PAT_RESPRT Responsible party checkbox T/F
                if (plan != null && pat.PatNum == sub.Subscriber) //if current patient is the subscriber on their primary plan
                {
                    sw.Write("1");
                }
                else
                {
                    sw.Write("0");
                }
                sw.Write(",");               //PAT_POLHLD Policy holder checkbox T/F
                sw.Write(",");               //PAT_CUSCD Web sync folder, used internally this can be ignored.
                sw.Write("");                //PAT_PMPID Practice Management Program ID. Can be ignored
                sw.WriteLine();
            }
            try{
                if (isUpdate)
                {
                    ODFileUtils.ProcessStart(dir + "\\" + exportUpdateExe);                //already validated to exist
                }
                else
                {
                    ODFileUtils.ProcessStart(dir + "\\" + exportAddExe);                //already validated to exist
                }
                //MessageBox.Show("done");
            }
            catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
        }
        ///<summary>Returns null if there is no HL7Def enabled or if there is no outbound ADT defined for the enabled HL7Def.</summary>
        public static MessageHL7 GenerateADT(Patient pat, Patient guar, EventTypeHL7 eventType)
        {
            HL7Def hl7Def = HL7Defs.GetOneDeepEnabled();

            if (hl7Def == null)
            {
                return(null);
            }
            //find an outbound ADT message in the def
            HL7DefMessage hl7DefMessage = null;

            for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++)
            {
                if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.ADT && hl7Def.hl7DefMessages[i].InOrOut == InOutHL7.Outgoing)
                {
                    hl7DefMessage = hl7Def.hl7DefMessages[i];
                    //continue;
                    break;
                }
            }
            if (hl7DefMessage == null)           //ADT message type is not defined so do nothing and return
            {
                return(null);
            }
            if (PrefC.GetBool(PrefName.ShowFeaturePatientClone))
            {
                pat = Patients.GetOriginalPatientForClone(pat);
            }
            MessageHL7     messageHL7   = new MessageHL7(MessageTypeHL7.ADT);
            Provider       prov         = Providers.GetProv(Patients.GetProvNum(pat));
            List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum);

            for (int i = 0; i < hl7DefMessage.hl7DefSegments.Count; i++)
            {
                int countRepeat = 1;
                //IN1 segment can repeat, get the number of current insurance plans attached to the patient
                if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)
                {
                    countRepeat = listPatPlans.Count;
                }
                //countRepeat is usually 1, but for repeatable/optional fields, it may be 0 or greater than 1
                //for example, countRepeat can be zero if the patient does not have any current insplans, in which case no IN1 segments will be included
                for (int j = 0; j < countRepeat; j++)           //IN1 is optional and can repeat so add as many as listPatplans
                {
                    PatPlan patplanCur = null;
                    InsPlan insplanCur = null;
                    InsSub  inssubCur  = null;
                    Carrier carrierCur = null;
                    Patient patSub     = null;
                    if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)                   //index repeat is guaranteed to be less than listPatplans.Count
                    {
                        patplanCur = listPatPlans[j];
                        inssubCur  = InsSubs.GetOne(patplanCur.InsSubNum);
                        insplanCur = InsPlans.RefreshOne(inssubCur.PlanNum);
                        carrierCur = Carriers.GetCarrier(insplanCur.CarrierNum);
                        if (pat.PatNum == inssubCur.Subscriber)
                        {
                            patSub = pat.Copy();
                        }
                        else
                        {
                            patSub = Patients.GetPat(inssubCur.Subscriber);
                        }
                    }
                    SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName);
                    seg.SetField(0, hl7DefMessage.hl7DefSegments[i].SegmentName.ToString());
                    for (int k = 0; k < hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count; k++)
                    {
                        string fieldName = hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FieldName;
                        if (fieldName == "")                       //If fixed text instead of field name just add text to segment
                        {
                            seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos, hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FixedText);
                        }
                        else
                        {
                            string fieldValue = "";
                            if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)
                            {
                                fieldValue = FieldConstructor.GenerateFieldIN1(hl7Def, fieldName, j + 1, patplanCur, inssubCur, insplanCur, carrierCur, listPatPlans.Count, patSub);
                            }
                            else
                            {
                                fieldValue = FieldConstructor.GenerateFieldADT(hl7Def, fieldName, pat, prov, guar, j + 1, eventType, seg.Name);
                            }
                            seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos, fieldValue);
                        }
                    }
                    messageHL7.Segments.Add(seg);
                }
            }
            return(messageHL7);
        }