Exemplo n.º 1
0
		///<summary></summary>
		public static long Insert(ClaimProc cp) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				cp.ClaimProcNum=Meth.GetLong(MethodBase.GetCurrentMethod(),cp);
				return cp.ClaimProcNum;
			}
			return Crud.ClaimProcCrud.Insert(cp);
		}
Exemplo n.º 2
0
		///<summary></summary>
		public static void Update(ClaimProc cp) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				Meth.GetVoid(MethodBase.GetCurrentMethod(),cp);
				return;
			}
			Crud.ClaimProcCrud.Update(cp);
		}
Exemplo n.º 3
0
        ///<summary>Users using the OpenDentalService to create claim snapshots only get primary claim snap shots created.</summary>
        private static void CreateClaimSnapShotService()
        {
            //No need to check RemotingRole; no call to db.
            List <Procedure> listCompletedProcs = Procedures.GetCompletedByDateCompleteForDateRange(DateTime.Today, DateTime.Today);
            List <ClaimProc> listClaimProcs     = ClaimProcs.GetForProcsWithOrdinal(listCompletedProcs.Select(x => x.ProcNum).ToList(), 1).Where(x => !x.Status.In(ClaimProcStatus.Preauth, ClaimProcStatus.Adjustment)).ToList();
            List <PatPlan>   listPatPlans       = PatPlans.GetListByInsSubNums(listClaimProcs.Select(x => x.InsSubNum).ToList());

            listClaimProcs = listClaimProcs
                             .OrderByDescending(x => x.ClaimNum)    //order by claim num
                             .ThenByDescending(x => x.SecDateEntry) //then by creation date
                                                                    //group by procnum and ordinal
                             .GroupBy(x => new { ProcNum = x.ProcNum, Ordinal = PatPlans.GetOrdinal(x.InsSubNum, listPatPlans.Where(y => y.PatNum == x.PatNum).ToList()) })
                             .Select(x => x.First())                //get the first for each group
                             .ToList();
            //Loop through all the claimprocs and create a claimsnapshot entry for each.
            for (int i = 0; i < listClaimProcs.Count; i++)
            {
                ClaimProc cpCur = listClaimProcs[i];
                if (cpCur.Status == ClaimProcStatus.CapClaim ||
                    cpCur.Status == ClaimProcStatus.CapComplete ||
                    cpCur.Status == ClaimProcStatus.CapEstimate ||
                    cpCur.Status == ClaimProcStatus.Preauth ||
                    cpCur.Status == ClaimProcStatus.Supplemental ||
                    cpCur.Status == ClaimProcStatus.InsHist)
                {
                    continue;
                }
                //get the procfee
                double    procFee = 0;
                Procedure procCur = listCompletedProcs.Find(x => x.ProcNum == cpCur.ProcNum);
                if (procCur != null)
                {
                    procFee = procCur.ProcFee;
                }
                //get the writeoff
                double writeoffAmt = cpCur.WriteOff;
                //For the Service, only use the WriteOff amount on the claimproc if the claimproc is associated to a claim,
                //as this means that value has been set.
                if (cpCur.Status != ClaimProcStatus.NotReceived && cpCur.Status != ClaimProcStatus.Received)
                {
                    if (cpCur.WriteOffEstOverride != -1)
                    {
                        writeoffAmt = cpCur.WriteOffEstOverride;
                    }
                    else
                    {
                        writeoffAmt = cpCur.WriteOffEst;
                    }
                }
                //create the snapshot
                ClaimSnapshot snapshot = new ClaimSnapshot();
                snapshot.ProcNum         = cpCur.ProcNum;
                snapshot.Writeoff        = writeoffAmt;
                snapshot.InsPayEst       = cpCur.InsEstTotal;
                snapshot.Fee             = procFee;
                snapshot.ClaimProcNum    = cpCur.ClaimProcNum;
                snapshot.SnapshotTrigger = ClaimSnapshotTrigger.Service;
                ClaimSnapshots.Insert(snapshot);
            }
        }
Exemplo n.º 4
0
 private static void SetSnapshotFields(ClaimSnapshot snapshot, ClaimProc cp, double procFee, ClaimSnapshotTrigger triggerType, string claimType)
 {
     snapshot.ProcNum         = cp.ProcNum;
     snapshot.Writeoff        = cp.WriteOff;
     snapshot.InsPayEst       = cp.InsEstTotal;
     snapshot.Fee             = procFee;
     snapshot.ClaimProcNum    = cp.ClaimProcNum;
     snapshot.SnapshotTrigger = triggerType;
     snapshot.ClaimType       = claimType;
 }
Exemplo n.º 5
0
		public static void AddInsUsedAdjustment(long patNum,long planNum,double amtPaid,long subNum,double dedApplied){
			ClaimProc cp=new ClaimProc();
			cp.PatNum=patNum;
			cp.PlanNum=planNum;
			cp.InsSubNum=subNum;
			cp.ProcDate=DateTime.Today;
			cp.Status=ClaimProcStatus.Adjustment;
			cp.InsPayAmt=amtPaid;
			cp.DedApplied=dedApplied;
			ClaimProcs.Insert(cp);
		}
Exemplo n.º 6
0
 public AccountEntry(ClaimProc claimProc)
 {
     Tag            = claimProc;
     Date           = claimProc.DateInsFinalized;
     PriKey         = claimProc.ClaimProcNum;
     AmountOriginal = 0 - (decimal)(claimProc.InsPayAmt + claimProc.WriteOff);
     AmountStart    = AmountOriginal;
     AmountEnd      = AmountOriginal;
     ProvNum        = claimProc.ProvNum;
     ClinicNum      = claimProc.ClinicNum;
     PatNum         = claimProc.PatNum;
 }
Exemplo n.º 7
0
		///<summary>This tells the calculating logic that insurance paid on a procedure.  It avoids the creation of an actual claim.</summary>
		public static void AddInsPaid(long patNum,long planNum,long procNum,double amtPaid,long subNum,double dedApplied,double writeOff) {
			ClaimProc cp=new ClaimProc();
			cp.ProcNum=procNum;
			cp.PatNum=patNum;
			cp.PlanNum=planNum;
			cp.InsSubNum=subNum;
			cp.InsPayAmt=amtPaid;
			cp.DedApplied=dedApplied;
			cp.WriteOff=writeOff;
			cp.Status=ClaimProcStatus.Received;
			cp.DateCP=DateTime.Today;
			cp.ProcDate=DateTime.Today;
			ClaimProcs.Insert(cp);
		}
Exemplo n.º 8
0
        public override bool Equals(object obj)
        {
            ClaimProc cp = (ClaimProc)obj;

            if (ClaimProcNum != cp.ClaimProcNum ||
                ProcNum != cp.ProcNum ||
                ClaimNum != cp.ClaimNum ||
                PatNum != cp.PatNum ||
                ProvNum != cp.ProvNum ||
                FeeBilled != cp.FeeBilled ||
                InsPayEst != cp.InsPayEst ||
                DedApplied != cp.DedApplied ||
                Status != cp.Status ||
                InsPayAmt != cp.InsPayAmt ||
                Remarks != cp.Remarks ||
                ClaimPaymentNum != cp.ClaimPaymentNum ||
                PlanNum != cp.PlanNum ||
                DateCP != cp.DateCP ||
                WriteOff != cp.WriteOff ||
                CodeSent != cp.CodeSent ||
                AllowedOverride != cp.AllowedOverride ||
                Percentage != cp.Percentage ||
                PercentOverride != cp.PercentOverride ||
                CopayAmt != cp.CopayAmt ||
                NoBillIns != cp.NoBillIns ||
                PaidOtherIns != cp.PaidOtherIns ||
                BaseEst != cp.BaseEst ||
                CopayOverride != cp.CopayOverride ||
                ProcDate != cp.ProcDate ||
                DateEntry != cp.DateEntry ||
                LineNumber != cp.LineNumber ||
                DedEst != cp.DedEst ||
                DedEstOverride != cp.DedEstOverride ||
                InsEstTotal != cp.InsEstTotal ||
                InsEstTotalOverride != cp.InsEstTotalOverride ||
                PaidOtherInsOverride != cp.PaidOtherInsOverride ||
                EstimateNote != cp.EstimateNote ||
                WriteOffEst != cp.WriteOffEst ||
                WriteOffEstOverride != cp.WriteOffEstOverride ||
                ClinicNum != cp.ClinicNum)
            {
                return(false);
            }
            return(true);
        }
Exemplo n.º 9
0
 ///<summary>Only for claimprocs with status NotReceived, Received, Supplemental, CapClaim.</summary>
 public AccountEntry(ClaimProc claimProc)
 {
     Tag    = claimProc;
     Date   = claimProc.DateCP;
     PriKey = claimProc.ClaimProcNum;
     if (claimProc.Status == ClaimProcStatus.NotReceived)
     {
         AmountOriginal = 0 - (decimal)(claimProc.InsPayEst + claimProc.WriteOff);
     }
     else              //Received, Supplemental, CapClaim
     {
         AmountOriginal = 0 - (decimal)(claimProc.InsPayAmt + claimProc.WriteOff);
     }
     AmountStart = AmountOriginal;
     AmountEnd   = AmountOriginal;
     ProvNum     = claimProc.ProvNum;
     ClinicNum   = claimProc.ClinicNum;
     PatNum      = claimProc.PatNum;
 }
Exemplo n.º 10
0
        ///<summary>Returns a copy of this ClaimProc.</summary>
        public ClaimProc Copy()
        {
            ClaimProc cp = new ClaimProc();

            cp.ClaimProcNum    = ClaimProcNum;
            cp.ProcNum         = ProcNum;
            cp.ClaimNum        = ClaimNum;
            cp.PatNum          = PatNum;
            cp.ProvNum         = ProvNum;
            cp.FeeBilled       = FeeBilled;
            cp.InsPayEst       = InsPayEst;
            cp.DedApplied      = DedApplied;
            cp.Status          = Status;
            cp.InsPayAmt       = InsPayAmt;
            cp.Remarks         = Remarks;
            cp.ClaimPaymentNum = ClaimPaymentNum;
            cp.PlanNum         = PlanNum;
            cp.DateCP          = DateCP;
            cp.WriteOff        = WriteOff;
            cp.CodeSent        = CodeSent;
            cp.AllowedAmt      = AllowedAmt;
            cp.Percentage      = Percentage;
            cp.PercentOverride = PercentOverride;
            cp.CopayAmt        = CopayAmt;
            cp.OverrideInsEst  = OverrideInsEst;
            cp.NoBillIns       = NoBillIns;
            cp.DedBeforePerc   = DedBeforePerc;
            cp.OverAnnualMax   = OverAnnualMax;
            cp.PaidOtherIns    = PaidOtherIns;
            cp.BaseEst         = BaseEst;
            cp.CopayOverride   = CopayOverride;
            cp.ProcDate        = ProcDate;
            cp.DateEntry       = DateEntry;
            cp.LineNumber      = LineNumber;
            return(cp);
        }
Exemplo n.º 11
0
 /*
 ///<summary>We don't care about a looplist because those would be for different procedures.  So this calculation really only makes sense when calculating secondary insurance in the claim edit window or when calculating secondary estimates in the TP module.  HistList will include actual payments and estimated pending payments for this proc, but it will not include primary estimates.  Estimates are not handled here, but are instead passed in to ComputeBaseEst</summary>
 private static double GetPaidOtherIns(ClaimProc cp,List<PatPlan> patPlanList,long patPlanNum,List<ClaimProcHist> histList) {
     if(cp.ProcNum==0) {
         return -1;
     }
     if(histList==null) {
         return -1;
     }
     PatPlan pp=PatPlans.GetFromList(patPlanList.ToArray(),patPlanNum);
     if(pp==null) {
         return -1;
     }
     int thisOrdinal=pp.Ordinal;
     if(thisOrdinal==1) {
         return -1;
     }
     double retVal=0;
     int ordinal;
     for(int i=0;i<histList.Count;i++) {
         ordinal=PatPlans.GetOrdinal(patPlanList,cp.PlanNum);
         if(ordinal >= thisOrdinal){
             continue;
         }
         retVal+=histList[i].Amount;
     }
     return retVal;
 }*/
 ///<summary>Only useful if secondary ins or greater.  For one procedure, it gets the sum of InsEstTotal/Override for other insurances with lower ordinals.  Either estimates or actual payments.  Will return 0 if ordinal of this claimproc is 1.</summary>
 public static double GetPaidOtherInsTotal(ClaimProc cp,List<PatPlan> patPlanList)
 {
     if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
         return Meth.GetObject<double>(MethodBase.GetCurrentMethod(),cp,patPlanList);
     }
     if(cp.ProcNum==0) {
         return 0;
     }
     int thisOrdinal=PatPlans.GetOrdinal(cp.InsSubNum,patPlanList);
     if(thisOrdinal==1) {
         return 0;
     }
     string command="SELECT InsSubNum,InsEstTotal,InsEstTotalOverride,InsPayAmt,Status FROM claimproc WHERE ProcNum="+POut.Long(cp.ProcNum);
     DataTable table=Db.GetTable(command);
     double retVal=0;
     long subNum;
     int ordinal;
     double insEstTotal;
     double insEstTotalOverride;
     double insPayAmt;
     ClaimProcStatus status;
     for(int i=0;i<table.Rows.Count;i++) {
         subNum=PIn.Long(table.Rows[i]["InsSubNum"].ToString());
         ordinal=PatPlans.GetOrdinal(subNum,patPlanList);
         if(ordinal >= thisOrdinal) {
             continue;
         }
         insEstTotal=PIn.Double(table.Rows[i]["InsEstTotal"].ToString());
         insEstTotalOverride=PIn.Double(table.Rows[i]["InsEstTotalOverride"].ToString());
         insPayAmt=PIn.Double(table.Rows[i]["InsPayAmt"].ToString());
         status=(ClaimProcStatus)PIn.Int(table.Rows[i]["Status"].ToString());
         if(status==ClaimProcStatus.Received || status==ClaimProcStatus.Supplemental)
         {
             retVal+=insPayAmt;
         }
         if(status==ClaimProcStatus.Estimate || status==ClaimProcStatus.NotReceived)
         {
             if(insEstTotalOverride != -1) {
                 retVal+=insEstTotalOverride;
             }
             else {
                 retVal+=insEstTotal;
             }
         }
     }
     return retVal;
 }
Exemplo n.º 12
0
		private Claim CreateClaim(string claimType,List<PatPlan> patPlanList,List<InsPlan> planList,List<ClaimProc> claimProcList,Procedure proc,List<InsSub> subList) {
			long claimFormNum=0;
			InsPlan planCur=new InsPlan();
			InsSub subCur=new InsSub();
			Relat relatOther=Relat.Self;
			long clinicNum=proc.ClinicNum;
			PlaceOfService placeService=proc.PlaceService;
			switch(claimType) {
				case "P":
					subCur=InsSubs.GetSub(PatPlans.GetInsSubNum(patPlanList,PatPlans.GetOrdinal(PriSecMed.Primary,patPlanList,planList,subList)),subList);
					planCur=InsPlans.GetPlan(subCur.PlanNum,planList);
					break;
				case "S":
					subCur=InsSubs.GetSub(PatPlans.GetInsSubNum(patPlanList,PatPlans.GetOrdinal(PriSecMed.Secondary,patPlanList,planList,subList)),subList);
					planCur=InsPlans.GetPlan(subCur.PlanNum,planList);
					break;
				case "Med":
					//It's already been verified that a med plan exists
					subCur=InsSubs.GetSub(PatPlans.GetInsSubNum(patPlanList,PatPlans.GetOrdinal(PriSecMed.Medical,patPlanList,planList,subList)),subList);
					planCur=InsPlans.GetPlan(subCur.PlanNum,planList);
					break;
			}
			ClaimProc claimProcCur=Procedures.GetClaimProcEstimate(proc.ProcNum,claimProcList,planCur,subCur.InsSubNum);
			if(claimProcCur==null) {
				claimProcCur=new ClaimProc();
				ClaimProcs.CreateEst(claimProcCur,proc,planCur,subCur);
			}
			Claim claimCur=new Claim();
			claimCur.PatNum=proc.PatNum;
			claimCur.DateService=proc.ProcDate;
			claimCur.ClinicNum=proc.ClinicNum;
			claimCur.PlaceService=proc.PlaceService;
			claimCur.ClaimStatus="W";
			claimCur.DateSent=DateTimeOD.Today;
			claimCur.PlanNum=planCur.PlanNum;
			claimCur.InsSubNum=subCur.InsSubNum;
			InsSub sub;
			switch(claimType) {
				case "P":
					claimCur.PatRelat=PatPlans.GetRelat(patPlanList,PatPlans.GetOrdinal(PriSecMed.Primary,patPlanList,planList,subList));
					claimCur.ClaimType="P";
					claimCur.InsSubNum2=PatPlans.GetInsSubNum(patPlanList,PatPlans.GetOrdinal(PriSecMed.Secondary,patPlanList,planList,subList));
					sub=InsSubs.GetSub(claimCur.InsSubNum2,subList);
					if(sub.PlanNum>0 && InsPlans.RefreshOne(sub.PlanNum).IsMedical) {
						claimCur.PlanNum2=0;//no sec ins
						claimCur.PatRelat2=Relat.Self;
					}
					else {
						claimCur.PlanNum2=sub.PlanNum;//might be 0 if no sec ins
						claimCur.PatRelat2=PatPlans.GetRelat(patPlanList,PatPlans.GetOrdinal(PriSecMed.Secondary,patPlanList,planList,subList));
					}
					break;
				case "S":
					claimCur.PatRelat=PatPlans.GetRelat(patPlanList,PatPlans.GetOrdinal(PriSecMed.Secondary,patPlanList,planList,subList));
					claimCur.ClaimType="S";
					claimCur.InsSubNum2=PatPlans.GetInsSubNum(patPlanList,PatPlans.GetOrdinal(PriSecMed.Primary,patPlanList,planList,subList));
					sub=InsSubs.GetSub(claimCur.InsSubNum2,subList);
					claimCur.PlanNum2=sub.PlanNum;
					claimCur.PatRelat2=PatPlans.GetRelat(patPlanList,PatPlans.GetOrdinal(PriSecMed.Primary,patPlanList,planList,subList));
					break;
				case "Med":
					claimCur.PatRelat=PatPlans.GetFromList(patPlanList,subCur.InsSubNum).Relationship;
					claimCur.ClaimType="Other";
					if(PrefC.GetBool(PrefName.ClaimMedTypeIsInstWhenInsPlanIsMedical)){
						claimCur.MedType=EnumClaimMedType.Institutional;
					}
					else{
						claimCur.MedType=EnumClaimMedType.Medical;
					}
					break;
				case "Other":
					claimCur.PatRelat=relatOther;
					claimCur.ClaimType="Other";
					//plannum2 is not automatically filled in.
					claimCur.ClaimForm=claimFormNum;
					if(planCur.IsMedical){
						if(PrefC.GetBool(PrefName.ClaimMedTypeIsInstWhenInsPlanIsMedical)){
							claimCur.MedType=EnumClaimMedType.Institutional;
						}
						else{
							claimCur.MedType=EnumClaimMedType.Medical;
						}
					}
					break;
			}
			if(planCur.PlanType=="c"){//if capitation
				claimCur.ClaimType="Cap";
			}
			claimCur.ProvTreat=proc.ProvNum;
			if(Providers.GetIsSec(proc.ProvNum)) {
				claimCur.ProvTreat=Patients.GetPat(proc.PatNum).PriProv;
				//OK if zero, because auto select first in list when open claim
			}
			claimCur.IsProsthesis="N";
			claimCur.ProvBill=Providers.GetBillingProvNum(claimCur.ProvTreat,claimCur.ClinicNum);//OK if zero, because it will get fixed in claim
			claimCur.EmployRelated=YN.No;
			claimCur.ClaimForm=planCur.ClaimFormNum;
			Claims.Insert(claimCur);
			//attach procedure
			claimProcCur.ClaimNum=claimCur.ClaimNum;
			if(planCur.PlanType=="c") {//if capitation
				claimProcCur.Status=ClaimProcStatus.CapClaim;
			}
			else {
				claimProcCur.Status=ClaimProcStatus.NotReceived;
			}
			if(planCur.UseAltCode && (ProcedureCodes.GetProcCode(proc.CodeNum).AlternateCode1!="")) {
				claimProcCur.CodeSent=ProcedureCodes.GetProcCode(proc.CodeNum).AlternateCode1;
			}
			else if(planCur.IsMedical && proc.MedicalCode!="") {
				claimProcCur.CodeSent=proc.MedicalCode;
			}
			else {
				claimProcCur.CodeSent=ProcedureCodes.GetProcCode(proc.CodeNum).ProcCode;
				if(claimProcCur.CodeSent.Length>5 && claimProcCur.CodeSent.Substring(0,1)=="D") {
					claimProcCur.CodeSent=claimProcCur.CodeSent.Substring(0,5);
				}
				if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
					if(claimProcCur.CodeSent.Length>5) {//In Canadian e-claims, codes can contain letters or numbers and cannot be longer than 5 characters.
						claimProcCur.CodeSent=claimProcCur.CodeSent.Substring(0,5);
					}
				}
			}
			claimProcCur.LineNumber=(byte)1;
			ClaimProcs.Update(claimProcCur);
			return claimCur;
		}
Exemplo n.º 13
0
 ///<summary>Used once in Account on the Claim line.  The amount paid on a claim only by total, not including by procedure.  The list can be all ClaimProcs for patient, or just those for this claim.</summary>
 public static double ClaimByTotalOnly(ClaimProc[] List,long claimNum)
 {
     //No need to check RemotingRole; no call to db.
     double retVal=0;
     for(int i=0;i<List.Length;i++){
         if(List[i].ClaimNum==claimNum
             && List[i].ProcNum==0
             && List[i].Status!=ClaimProcStatus.Preauth){
             retVal+=List[i].InsPayAmt;
         }
     }
     return retVal;
 }
Exemplo n.º 14
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;
		}
Exemplo n.º 15
0
 private void FormClaimProc_FormClosing(object sender,FormClosingEventArgs e)
 {
     if(DialogResult==DialogResult.OK){
         return;
     }
     ClaimProcCur=ClaimProcOld.Copy();//revert back to the old ClaimProc.  Only important if not SaveToDb
 }
Exemplo n.º 16
0
 ///<summary></summary>
 public static string GetWriteOffEstimateDisplay(ClaimProc cp)
 {
     //No need to check RemotingRole; no call to db.
     if(cp.WriteOffEstOverride!=-1) {
         return cp.WriteOffEstOverride.ToString("f");
     }
     else if(cp.WriteOffEst!=-1) {
         return cp.WriteOffEst.ToString("f");
     }
     return "";
 }
Exemplo n.º 17
0
		private void ToolBarMainPreAuth_Click() {
			if(!CheckClearinghouseDefaults()) {
				return;
			}
			if(gridPlans.SelectedIndices[0]!=0){
				MsgBox.Show(this,"You can only send a preauth from the current TP, not a saved TP.");
				return;
			}
			if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canada
				int numLabProcsUnselected=0;
				List<int> selectedIndices=new List<int>(gridMain.SelectedIndices);
				for(int i=0;i<selectedIndices.Count;i++) {
					Procedure proc=((Procedure)gridMain.Rows[selectedIndices[i]].Tag);
					if(proc!=null) {
						ProcedureCode procCode=ProcedureCodes.GetProcCodeFromDb(proc.CodeNum);
						if(procCode.IsCanadianLab) {
							gridMain.SetSelected(selectedIndices[i],false);//deselect
							numLabProcsUnselected++;
						}
					}
				}
				if(numLabProcsUnselected>0) {
					MessageBox.Show(Lan.g(this,"Number of lab fee procedures unselected")+": "+numLabProcsUnselected.ToString());
				}
				if(gridMain.SelectedIndices.Length>7) {
					List <int> selectedIndicies=new List<int>(gridMain.SelectedIndices);
					selectedIndicies.Sort();
					for(int i=0;i<selectedIndicies.Count;i++) { //Unselect all but the first 7 procedures with the smallest index numbers.
						gridMain.SetSelected(selectedIndicies[i],(i<7));
					}
					MsgBox.Show(this,"Only the first 7 procedures will be selected.  You will need to create another preauth for the remaining procedures.");
				}
			}
			bool procsSelected=false;
			for(int i=0;i<gridMain.SelectedIndices.Length;i++){
				if(gridMain.Rows[gridMain.SelectedIndices[i]].Tag!=null){
					procsSelected=true;
				}
			}
			if(!procsSelected) {
				MessageBox.Show(Lan.g(this,"Please select procedures first."));
				return;
			}
			Claim ClaimCur=new Claim();
      FormInsPlanSelect FormIPS=new FormInsPlanSelect(PatCur.PatNum); 
			FormIPS.ViewRelat=true;
			FormIPS.ShowDialog();
			if(FormIPS.DialogResult!=DialogResult.OK) {
				return;
			}
			ClaimCur.PatNum=PatCur.PatNum;
			ClaimCur.ClaimStatus="W";
			ClaimCur.DateSent=DateTimeOD.Today;
			ClaimCur.PlanNum=FormIPS.SelectedPlan.PlanNum;
			ClaimCur.InsSubNum=FormIPS.SelectedSub.InsSubNum;
			ClaimCur.ProvTreat=0;
			for(int i=0;i<gridMain.SelectedIndices.Length;i++){
				if(gridMain.Rows[gridMain.SelectedIndices[i]].Tag==null){
					continue;//skip any hightlighted subtotal lines
				}
				if(ClaimCur.ProvTreat==0){//makes sure that at least one prov is set
					ClaimCur.ProvTreat=((Procedure)gridMain.Rows[gridMain.SelectedIndices[i]].Tag).ProvNum;
				}
				if(!Providers.GetIsSec(((Procedure)gridMain.Rows[gridMain.SelectedIndices[i]].Tag).ProvNum)){
					ClaimCur.ProvTreat=((Procedure)gridMain.Rows[gridMain.SelectedIndices[i]].Tag).ProvNum;
				}
			}
			ClaimCur.ClinicNum=PatCur.ClinicNum;
			if(Providers.GetIsSec(ClaimCur.ProvTreat)){
				ClaimCur.ProvTreat=PatCur.PriProv;
				//OK if 0, because auto select first in list when open claim
			}
			ClaimCur.ProvBill=Providers.GetBillingProvNum(ClaimCur.ProvTreat,ClaimCur.ClinicNum);
			ClaimCur.EmployRelated=YN.No;
      ClaimCur.ClaimType="PreAuth";
			//this could be a little better if we automate figuring out the patrelat
			//instead of making the user enter it:
			ClaimCur.PatRelat=FormIPS.PatRelat;
			Claims.Insert(ClaimCur);
			Procedure ProcCur;
			ClaimProc ClaimProcCur;
			ClaimProc cpExisting;
			for(int i=0;i<gridMain.SelectedIndices.Length;i++){
				if(gridMain.Rows[gridMain.SelectedIndices[i]].Tag==null) {
					continue;//skip any highlighted subtotal lines
				}
				ProcCur=(Procedure)gridMain.Rows[gridMain.SelectedIndices[i]].Tag;
        ClaimProcCur=new ClaimProc();
				ClaimProcCur.ProcNum=ProcCur.ProcNum;
        ClaimProcCur.ClaimNum=ClaimCur.ClaimNum;
        ClaimProcCur.PatNum=PatCur.PatNum;
        ClaimProcCur.ProvNum=ProcCur.ProvNum;
				ClaimProcCur.Status=ClaimProcStatus.Preauth;
				ClaimProcCur.FeeBilled=ProcCur.ProcFee;
				ClaimProcCur.PlanNum=FormIPS.SelectedPlan.PlanNum;
				ClaimProcCur.InsSubNum=FormIPS.SelectedSub.InsSubNum;
				cpExisting=ClaimProcs.GetEstimate(ClaimProcList,ProcCur.ProcNum,FormIPS.SelectedPlan.PlanNum,FormIPS.SelectedSub.InsSubNum);
				if(cpExisting!=null){
					ClaimProcCur.InsPayEst=cpExisting.InsPayEst;
				}
				if(FormIPS.SelectedPlan.UseAltCode && (ProcedureCodes.GetProcCode(ProcCur.CodeNum).AlternateCode1!="")){
					ClaimProcCur.CodeSent=ProcedureCodes.GetProcCode(ProcCur.CodeNum).AlternateCode1;
				}
				else if(FormIPS.SelectedPlan.IsMedical && ProcCur.MedicalCode!=""){
					ClaimProcCur.CodeSent=ProcCur.MedicalCode;
				}
				else{
					ClaimProcCur.CodeSent=ProcedureCodes.GetStringProcCode(ProcCur.CodeNum);
					if(ClaimProcCur.CodeSent.Length>5 && ClaimProcCur.CodeSent.Substring(0,1)=="D"){
						ClaimProcCur.CodeSent=ClaimProcCur.CodeSent.Substring(0,5);
					}
					if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
						if(ClaimProcCur.CodeSent.Length>5) { //In Canadian electronic claims, codes can contain letters or numbers and cannot be longer than 5 characters.
							ClaimProcCur.CodeSent=ClaimProcCur.CodeSent.Substring(0,5);
						}
					}
				}
				ClaimProcCur.LineNumber=(byte)(i+1);
        ClaimProcs.Insert(ClaimProcCur);
				//ProcCur.Update(ProcOld);
			}
			ProcList=Procedures.Refresh(PatCur.PatNum);
			//ClaimProcList=ClaimProcs.Refresh(PatCur.PatNum);
			ClaimL.CalculateAndUpdate(ProcList,InsPlanList,ClaimCur,PatPlanList,BenefitList,PatCur.Age,SubList);
			FormClaimEdit FormCE=new FormClaimEdit(ClaimCur,PatCur,FamCur);
			//FormCE.CalculateEstimates(
			FormCE.IsNew=true;//this causes it to delete the claim if cancelling.
			FormCE.ShowDialog();
			ModuleSelected(PatCur.PatNum);
		}
Exemplo n.º 18
0
 ///<summary>Calculates the Base estimate, InsEstTotal, and all the other insurance numbers for a single claimproc.  This is is not done on the fly.  Use Procedure.GetEst to later retrieve the estimate. This function replaces all of the upper estimating logic that was within FormClaimProc.  BaseEst=((fee or allowedOverride)-Copay) x (percentage or percentOverride).  The calling class must have already created the claimProc, and this function simply updates the BaseEst field of that claimproc. pst.Tot not used.  For Estimate and CapEstimate, all the estimate fields will be recalculated except the overrides.  histList and loopList can be null.  If so, then deductible and annual max will not be recalculated.  histList and loopList may only make sense in TP module and claimEdit.  loopList contains all claimprocs in the current list (TP or claim) that come before this procedure.  PaidOtherInsTot should only contain sum of InsEstTotal/Override, or paid, depending on the status.  PaidOtherInsBase also includes actual payments.</summary>
 public static void ComputeBaseEst(ClaimProc cp,double procFee,string toothNum,long codeNum,InsPlan plan,long patPlanNum,List<Benefit> benList,List<ClaimProcHist> histList,List<ClaimProcHist> loopList,List<PatPlan> patPlanList,double paidOtherInsTot,double paidOtherInsBase,int patientAge,double writeOffOtherIns)
 {
     //No need to check RemotingRole; no call to db.
     if(cp.Status==ClaimProcStatus.CapClaim
         || cp.Status==ClaimProcStatus.CapComplete
         || cp.Status==ClaimProcStatus.Preauth
         || cp.Status==ClaimProcStatus.Supplemental) {
         return;//never compute estimates for those types listed above.
     }
     if(plan.PlanType=="c"//if capitation plan
         && cp.Status==ClaimProcStatus.Estimate)//and ordinary estimate
     {
         cp.Status=ClaimProcStatus.CapEstimate;
     }
     if(plan.PlanType!="c"//if not capitation plan
         && cp.Status==ClaimProcStatus.CapEstimate)//and estimate is a capitation estimate
     {
         cp.Status=ClaimProcStatus.Estimate;
     }
     //NoBillIns is only calculated when creating the claimproc, even if resetAll is true.
     //If user then changes a procCode, it does not cause an update of all procedures with that code.
     if(cp.NoBillIns) {
         cp.AllowedOverride=-1;
         cp.CopayAmt=0;
         cp.CopayOverride=-1;
         cp.Percentage=-1;
         cp.PercentOverride=-1;
         cp.DedEst=-1;
         cp.DedEstOverride=-1;
         cp.PaidOtherIns=-1;
         cp.BaseEst=0;
         cp.InsEstTotal=0;
         cp.InsEstTotalOverride=-1;
         cp.WriteOff=0;
         cp.PaidOtherInsOverride=-1;
         cp.WriteOffEst=-1;
         cp.WriteOffEstOverride=-1;
         return;
     }
     cp.EstimateNote="";
     //This function is called every time a ProcFee is changed,
     //so the BaseEst does reflect the new ProcFee.
     //ProcFee----------------------------------------------------------------------------------------------
     cp.BaseEst=procFee;
     cp.InsEstTotal=procFee;
     //Allowed----------------------------------------------------------------------------------------------
     double allowed=procFee;//could be fee, or could be a little less.  Used further down in paidOtherIns.
     if(cp.AllowedOverride!=-1) {
         if(cp.AllowedOverride > procFee){
             cp.AllowedOverride=procFee;
         }
         allowed=cp.AllowedOverride;
         cp.BaseEst=cp.AllowedOverride;
         cp.InsEstTotal=cp.AllowedOverride;
     }
     else if(plan.PlanType=="c"){//capitation estimate.  No allowed fee sched.  No substitute codes.
         allowed=procFee;
         cp.BaseEst=procFee;
         cp.InsEstTotal=procFee;
     }
     else {
         //no point in wasting time calculating this unless it's needed.
         double carrierAllowed=InsPlans.GetAllowed(ProcedureCodes.GetProcCode(codeNum).ProcCode,plan.FeeSched,plan.AllowedFeeSched,
             plan.CodeSubstNone,plan.PlanType,toothNum,cp.ProvNum);
         if(carrierAllowed != -1) {
             if(carrierAllowed > procFee) {
                 allowed=procFee;
                 cp.BaseEst=procFee;
                 cp.InsEstTotal=procFee;
             }
             else {
                 allowed=carrierAllowed;
                 cp.BaseEst=carrierAllowed;
                 cp.InsEstTotal=carrierAllowed;
             }
         }
     }
     //Copay----------------------------------------------------------------------------------------------
     cp.CopayAmt=InsPlans.GetCopay(codeNum,plan.FeeSched,plan.CopayFeeSched);
     if(cp.CopayAmt > allowed) {//if the copay is greater than the allowed fee calculated above
         cp.CopayAmt=allowed;//reduce the copay
     }
     if(cp.CopayOverride > allowed) {//or if the copay override is greater than the allowed fee calculated above
         cp.CopayOverride=allowed;//reduce the override
     }
     if(cp.Status==ClaimProcStatus.CapEstimate) {
         //this does automate the Writeoff. If user does not want writeoff automated,
         //then they will have to complete the procedure first. (very rare)
         if(cp.CopayAmt==-1) {
             cp.CopayAmt=0;
         }
         if(cp.CopayOverride != -1) {//override the copay
             cp.WriteOffEst=cp.BaseEst-cp.CopayOverride;
         }
         else if(cp.CopayAmt!=-1) {//use the calculated copay
             cp.WriteOffEst=cp.BaseEst-cp.CopayAmt;
         }
         if(cp.WriteOffEst<0) {
             cp.WriteOffEst=0;
         }
         cp.WriteOff=cp.WriteOffEst;
         cp.DedApplied=0;
         cp.DedEst=0;
         cp.Percentage=-1;
         cp.PercentOverride=-1;
         cp.BaseEst=0;
         cp.InsEstTotal=0;
         return;
     }
     if(cp.CopayOverride != -1) {//subtract copay if override
         cp.BaseEst-=cp.CopayOverride;
         cp.InsEstTotal-=cp.CopayOverride;
     }
     else if(cp.CopayAmt != -1) {//otherwise subtract calculated copay
         cp.BaseEst-=cp.CopayAmt;
         cp.InsEstTotal-=cp.CopayAmt;
     }
     //Deductible----------------------------------------------------------------------------------------
     //The code below handles partial usage of available deductible.
     DateTime procDate;
     if(cp.Status==ClaimProcStatus.Estimate) {
         procDate=DateTime.Today;
     }
     else {
         procDate=cp.ProcDate;
     }
     if(loopList!=null && histList!=null) {
         cp.DedEst=Benefits.GetDeductibleByCode(benList,plan.PlanNum,patPlanNum,procDate,ProcedureCodes.GetStringProcCode(codeNum),histList,loopList,plan,cp.PatNum);
     }
     if(cp.DedEst > cp.InsEstTotal){//if the deductible is more than the fee
         cp.DedEst=cp.InsEstTotal;//reduce the deductible
     }
     if(cp.DedEstOverride > cp.InsEstTotal) {//if the deductible override is more than the fee
         cp.DedEstOverride=cp.InsEstTotal;//reduce the override.
     }
     if(cp.DedEstOverride != -1) {//use the override
         cp.InsEstTotal-=cp.DedEstOverride;//subtract
     }
     else if(cp.DedEst != -1){//use the calculated deductible
         cp.InsEstTotal-=cp.DedEst;
     }
     //Percentage----------------------------------------------------------------------------------------
     cp.Percentage=Benefits.GetPercent(ProcedureCodes.GetProcCode(codeNum).ProcCode,plan.PlanType,plan.PlanNum,patPlanNum,benList);//will never =-1
     if(cp.PercentOverride != -1) {//override, so use PercentOverride
         cp.BaseEst=cp.BaseEst*(double)cp.PercentOverride/100d;
         cp.InsEstTotal=cp.InsEstTotal*(double)cp.PercentOverride/100d;
     }
     else if(cp.Percentage != -1) {//use calculated Percentage
         cp.BaseEst=cp.BaseEst*(double)cp.Percentage/100d;
         cp.InsEstTotal=cp.InsEstTotal*(double)cp.Percentage/100d;
     }
     //PaidOtherIns----------------------------------------------------------------------------------------
     //double paidOtherInsActual=GetPaidOtherIns(cp,patPlanList,patPlanNum,histList);//can return -1 for primary
     PatPlan pp=PatPlans.GetFromList(patPlanList.ToArray(),patPlanNum);
     //if -1, that indicates primary ins, not a proc, or no histlist.  We should not alter it in this case.
     //if(paidOtherInsActual!=-1) {
     //An older restriction was that histList must not be null.  But since this is now straight from db, that's not restriction.
     if(pp==null) {
         //corruption.  Do nothing.
     }
     else if(pp.Ordinal==1 || cp.ProcNum==0){
         cp.PaidOtherIns=0;
     }
     else{//if secondary or greater
         //The normal calculation uses the InsEstTotal from the primary ins.
         //But in TP module, if not using max and deduct, then the amount estimated to be paid by primary will be different.
         //It will use the primary BaseEst instead of the primary InsEstTotal.
         //Since the only use of BaseEst here is to handle this alternate viewing in the TP,
         //the secondary BaseEst should use the primary BaseEst when calculating paidOtherIns.
         //The BaseEst will, however, use PaidOtherInsOverride, if user has entered one.
         //This calculation doesn't need to be accurate unless viewing TP,
         //so it's ok to pass in a dummy value, like paidOtherInsTotal.
         //We do InsEstTotal first
         //cp.PaidOtherIns=paidOtherInsActual+paidOtherInsEstTotal;
         cp.PaidOtherIns=paidOtherInsTot;
         double paidOtherInsTotTemp=cp.PaidOtherIns;
         if(cp.PaidOtherInsOverride != -1) {//use the override
             paidOtherInsTotTemp=cp.PaidOtherInsOverride;
         }
         //example: Fee:200, InsEstT:80, BaseEst:100, PaidOI:110.
         //So... MaxPtP:90.
         //Since InsEstT is not greater than MaxPtoP, no change.
         //Since BaseEst is greater than MaxPtoP, BaseEst changed to 90.
         if(paidOtherInsTotTemp != -1) {
             double maxPossibleToPay=0;
             if(plan.CobRule==EnumCobRule.Basic) {
                 maxPossibleToPay=allowed-paidOtherInsTotTemp;
             }
             else if(plan.CobRule==EnumCobRule.Standard) {
                 double patPortionTot=procFee - paidOtherInsTotTemp - writeOffOtherIns;//patPortion for InsEstTotal
                 maxPossibleToPay=Math.Min(cp.BaseEst,patPortionTot);//The lesser of what insurance would pay if they were primary, and the patient portion.
             }
             else{//plan.CobRule==EnumCobRule.CarveOut
                 maxPossibleToPay=cp.BaseEst - paidOtherInsTotTemp;
             }
             if(maxPossibleToPay<0) {
                 maxPossibleToPay=0;
             }
             if(cp.InsEstTotal > maxPossibleToPay) {
                 cp.InsEstTotal=maxPossibleToPay;//reduce the estimate
             }
         }
         //Then, we do BaseEst
         double paidOtherInsBaseTemp=paidOtherInsBase;//paidOtherInsActual+paidOtherInsBaseEst;
         if(cp.PaidOtherInsOverride != -1) {//use the override
             paidOtherInsBaseTemp=cp.PaidOtherInsOverride;
         }
         if(paidOtherInsBaseTemp != -1) {
             double maxPossibleToPay=0;
             if(plan.CobRule==EnumCobRule.Basic) {
                 maxPossibleToPay=allowed-paidOtherInsBaseTemp;
             }
             else if(plan.CobRule==EnumCobRule.Standard) {
                 double patPortionBase=procFee - paidOtherInsBaseTemp - writeOffOtherIns;//patPortion for BaseEst
                 maxPossibleToPay=Math.Min(cp.BaseEst,patPortionBase);
             }
             else {//plan.CobRule==EnumCobRule.CarveOut
                 maxPossibleToPay=cp.BaseEst - paidOtherInsBaseTemp;
             }
             if(maxPossibleToPay<0) {
                 maxPossibleToPay=0;
             }
             if(cp.BaseEst > maxPossibleToPay) {
                 cp.BaseEst=maxPossibleToPay;//reduce the base est
             }
         }
     }
     //Exclusions---------------------------------------------------------------------------------------
     //We are not going to consider date of proc.  Just simple exclusions
     if(Benefits.IsExcluded(ProcedureCodes.GetStringProcCode(codeNum),benList,plan.PlanNum,patPlanNum)) {
         cp.BaseEst=0;
         cp.InsEstTotal=0;
         if(cp.EstimateNote!="") {
             cp.EstimateNote+=", ";
         }
         cp.EstimateNote+=Lans.g("ClaimProcs","Exclusion");
     }
     //base estimate is now done and will not be altered further.  From here out, we are only altering insEstTotal
     //annual max and other limitations--------------------------------------------------------------------------------
     if(loopList!=null && histList!=null) {
         string note="";
         cp.InsEstTotal=Benefits.GetLimitationByCode(benList,plan.PlanNum,patPlanNum,procDate,ProcedureCodes.GetStringProcCode(codeNum),histList,loopList,plan,cp.PatNum,out note,cp.InsEstTotal,patientAge,cp.InsSubNum);
         if(note != "") {
             if(cp.EstimateNote != "") {
                 cp.EstimateNote+=", ";
             }
             cp.EstimateNote+=note;
         }
     }
     //procDate;//was already calculated in the deductible section.
     //Writeoff Estimate------------------------------------------------------------------------------------------
     if(plan.PlanType=="p") {//PPO
         //we can't use the allowed previously calculated, because it might be the allowed of a substituted code.
         //so we will calculate the allowed all over again, but this time, without using a substitution code.
         //AllowedFeeSched and toothNum do not need to be passed in.  codeSubstNone is set to true to not subst.
         double carrierAllowedNoSubst=InsPlans.GetAllowed(ProcedureCodes.GetProcCode(codeNum).ProcCode,plan.FeeSched,0,
             true,"p","",cp.ProvNum);
         double allowedNoSubst=procFee;
         if(carrierAllowedNoSubst != -1) {
             if(carrierAllowedNoSubst > procFee) {
                 allowedNoSubst=procFee;
             }
             else {
                 allowedNoSubst=carrierAllowedNoSubst;
             }
         }
         double normalWriteOff=procFee-allowedNoSubst;//This is what the normal writeoff would be if no other insurance was involved.
         if(normalWriteOff<0) {
             normalWriteOff=0;
         }
         double remainingWriteOff=procFee-paidOtherInsTot-writeOffOtherIns;//This is the fee minus whatever other ins has already paid or written off.
         if(remainingWriteOff<0) {
             remainingWriteOff=0;
         }
         if(writeOffOtherIns>0) {//no secondary writeoff estimates allowed
             cp.WriteOffEst=0;//The reasoning for this is covered in the manual under Unit Test #1 and COB.
         }
         //We can't go over either number.  We must use the smaller of the two.  If one of them is zero, then the writeoff is zero.
         else if(remainingWriteOff==0 || normalWriteOff==0) {
             cp.WriteOffEst=0;
         }
         else if(remainingWriteOff<=normalWriteOff) {
             cp.WriteOffEst=remainingWriteOff;
         }
         else {
             cp.WriteOffEst=normalWriteOff;
         }
     }
     //capitation calculation never makes it this far:
     //else if(plan.PlanType=="c") {//capitation
     //	cp.WriteOffEst=cp.WriteOff;//this probably needs to change
     //}
     else {
         cp.WriteOffEst=-1;
     }
 }
Exemplo n.º 19
0
		public static bool IsValidClaimAdj(ClaimProc claimProc,long procNum,long subNumExclude) {
			//No need to check RemotingRole; no call to db.
			if(claimProc.ProcNum!=procNum) {
				return false;
			}
			if(claimProc.InsSubNum==subNumExclude) {
				return false;
			}
			if(claimProc.Status==ClaimProcStatus.CapClaim 
				//|| claimProc.Status==ClaimProcStatus.NotReceived //7/9/2013 Was causing paid amounts to show on primary claims when the patient had secondary insurance, because this is the starting status of secondary claimprocs when the New Claim button is pressed.
				|| claimProc.Status==ClaimProcStatus.Received 
				|| claimProc.Status==ClaimProcStatus.Supplemental)
				//Adjustment never attached to proc. Preauth, CapEstimate, CapComplete, and Estimate never paid. 
			{
				return true;
			}
			else {
				return false;
			}
		}
Exemplo n.º 20
0
 public static bool IsValidClaimAdj(ClaimProc claimProc,long procNum,long subNumExclude)
 {
     //No need to check RemotingRole; no call to db.
     if(claimProc.ProcNum!=procNum) {
         return false;
     }
     if(claimProc.InsSubNum==subNumExclude) {
         return false;
     }
     if(claimProc.Status==ClaimProcStatus.CapClaim
         || claimProc.Status==ClaimProcStatus.NotReceived
         || claimProc.Status==ClaimProcStatus.Received
         || claimProc.Status==ClaimProcStatus.Supplemental)
         //Adjustment never attached to proc. Preauth, CapEstimate, CapComplete, and Estimate never paid.
     {
         return true;
     }
     else {
         return false;
     }
 }
Exemplo n.º 21
0
 ///<summary>Used once in Account.  The insurance estimate based on all claimprocs with this procNum that are attached to claims. Includes status of NotReceived,Received, and Supplemental. The list can be all ClaimProcs for patient, or just those for this procedure.</summary>
 public static string ProcDisplayInsEst(ClaimProc[] List,long procNum)
 {
     //No need to check RemotingRole; no call to db.
     double retVal=0;
     for(int i=0;i<List.Length;i++){
         if(List[i].ProcNum==procNum
             //adj ignored
             //capClaim has no insEst yet
             && (List[i].Status==ClaimProcStatus.NotReceived
             || List[i].Status==ClaimProcStatus.Received
             || List[i].Status==ClaimProcStatus.Supplemental)
             ){
             retVal+=List[i].InsPayEst;
         }
     }
     return retVal.ToString("F");
 }
Exemplo n.º 22
0
		///<summary></summary>
		public FormInsAdj(ClaimProc claimProcCur){
			ClaimProcCur=claimProcCur;
			InitializeComponent();
			Lan.F(this);
		}
Exemplo n.º 23
0
Arquivo: Canadian.cs Projeto: mnisl/OD
		///<summary>Called directly instead of from Eclaims.SendBatches.  Includes one claim.  Sets claim status internally if successfully sent.  Returns the EtransNum of the ack.  Includes various user interaction such as displaying of messages, printing, triggering of COB claims, etc.  For a normal claim, primaryEOB will be blank.  But if this is a COB(type7), then we need to embed the primary EOB by passing it in. The queueItem.ClearinghouseNum must refer to a valid Canadian clearinghouse.</summary>
		public static long SendClaim(ClaimSendQueueItem queueItem,bool doPrint){
			Clearinghouse clearhouse=Clearinghouses.GetClearinghouse(queueItem.ClearinghouseNum);
//Warning: this path is not handled properly if trailing slash is missing:
			string saveFolder=clearhouse.ExportPath;
			if(!Directory.Exists(saveFolder)) {
				throw new ApplicationException(saveFolder+" not found.");
			}
			Etrans etrans;
			Claim claim;
			Clinic clinic;
			Provider billProv;
			Provider treatProv;
			InsPlan insPlan;
			InsSub insSub;
			Carrier carrier;
			InsPlan insPlan2=null;
			InsSub insSub2=null;
			Carrier carrier2=null;
			List <PatPlan> patPlansForPatient;
			Patient patient;
			Patient subscriber;
			List<ClaimProc> claimProcList;//all claimProcs for a patient.
			List<ClaimProc> claimProcsClaim;
			List<Procedure> procListAll;
			List<Procedure> extracted;
			List<Procedure> procListLabForOne;//Lab fees for one procedure
			Patient subscriber2=null;
			Procedure proc;
			ProcedureCode procCode;
			StringBuilder strb;
			string primaryEOBResponse="";
			string primaryClaimRequestMessage="";
			claim=Claims.GetClaim(queueItem.ClaimNum);
			claimProcList=ClaimProcs.Refresh(claim.PatNum);
			claimProcsClaim=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
			long planNum=claim.PlanNum;
			long insSubNum=claim.InsSubNum;
			Relat patRelat=claim.PatRelat;
			long planNum2=claim.PlanNum2;
			long insSubNum2=claim.InsSubNum2;
			Relat patRelat2=claim.PatRelat2;
			if(claim.ClaimType=="PreAuth") {
				etrans=Etranss.SetClaimSentOrPrinted(queueItem.ClaimNum,queueItem.PatNum,clearhouse.ClearinghouseNum,EtransType.Predeterm_CA,0);
			}
			else if(claim.ClaimType=="S") {//Secondary
				//We first need to verify that the claimprocs on the secondary/cob claim are the same as the claimprocs on the primary claim.
				etrans=Etranss.SetClaimSentOrPrinted(queueItem.ClaimNum,queueItem.PatNum,clearhouse.ClearinghouseNum,EtransType.ClaimCOB_CA,0);
				long claimNumPrimary=0;
				for(int i=0;i<claimProcsClaim.Count;i++) {
					List<ClaimProc> claimProcsForProc=ClaimProcs.GetForProc(claimProcList,claimProcsClaim[i].ProcNum);
					bool matchingPrimaryProc=false;
					for(int j=0;j<claimProcsForProc.Count;j++) {
						if(claimProcsForProc[j].ClaimNum!=0 && claimProcsForProc[j].ClaimNum!=claim.ClaimNum && (claimNumPrimary==0 || claimNumPrimary==claimProcsForProc[j].ClaimNum)) {
							claimNumPrimary=claimProcsForProc[j].ClaimNum;
							matchingPrimaryProc=true;
							break;
						}
					}
					if(!matchingPrimaryProc) {
						throw new ApplicationException(Lan.g("Canadian","The procedures attached to this COB claim must be the same as the procedures attached to the primary claim."));
					}
				}
				if(ClaimProcs.GetForSendClaim(claimProcList,claimNumPrimary).Count!=claimProcsClaim.Count) {
					throw new ApplicationException(Lan.g("Canadian","The procedures attached to this COB claim must be the same as the procedures attached to the primary claim."));
				}
				//Now ensure that the primary claim recieved an EOB response, or else we cannot send a COB.
				List <Etrans> etransPrimary=Etranss.GetHistoryOneClaim(claimNumPrimary);
				for(int i=0;i<etransPrimary.Count;i++) {
					primaryClaimRequestMessage=EtransMessageTexts.GetMessageText(etransPrimary[i].EtransMessageTextNum);
					Etrans etransPrimaryAck=Etranss.GetEtrans(etransPrimary[i].AckEtransNum);
					if(etransPrimaryAck.AckCode.ToUpper()=="R") {
						continue;
					}
					if(etransPrimaryAck!=null) {
						primaryEOBResponse=EtransMessageTexts.GetMessageText(etransPrimaryAck.EtransMessageTextNum);
					}
					break;
				}
				if(primaryEOBResponse=="") {
					throw new ApplicationException(Lan.g("Canadian","Cannot send secondary claim electronically until primary EOB has been received electronically."));
				}
				else if(primaryEOBResponse.Length<22) {
					throw new ApplicationException(Lan.g("Canadian","Cannot send secondary claim electronically, because primary claim electronic response is malformed. Try sending the primary claim again."));
				}
				else {//primaryEOBResponse.Length>=22
					string messageVersion=primaryEOBResponse.Substring(18,2);//Field A03 always exists on all messages and is always in the same location.
					string messageType=primaryEOBResponse.Substring(20,2);//Field A04 always exists on all messages and is always in the same location.
					if(messageVersion!="04") {
						throw new ApplicationException(Lan.g("Canadian","Cannot send secondary claim electronically, because primary claim electronic response is in an older format. The secondary claim must be printed instead."));
					}
					if(messageType!="21") {//message type 21 is EOB
						throw new ApplicationException(Lan.g("Canadian","Cannot send secondary claim electronically until primary EOB has been received electronically. The existing primary claim electronic response is not an EOB."));
					}
				}
				Claim claimPrimary=Claims.GetClaim(claimNumPrimary);
				planNum=claimPrimary.PlanNum;
				insSubNum=claimPrimary.InsSubNum;
				patRelat=claimPrimary.PatRelat;
				planNum2=claimPrimary.PlanNum2;
				insSubNum2=claimPrimary.InsSubNum2;
				patRelat2=claimPrimary.PatRelat2;
			}
			else { //primary claim
				etrans=Etranss.SetClaimSentOrPrinted(queueItem.ClaimNum,queueItem.PatNum,clearhouse.ClearinghouseNum,EtransType.Claim_CA,0);
			}
			claim=Claims.GetClaim(claim.ClaimNum);//Refresh the claim since the status might have changed above.
			clinic=Clinics.GetClinic(claim.ClinicNum);
			billProv=ProviderC.ListLong[Providers.GetIndexLong(claim.ProvBill)];
			treatProv=ProviderC.ListLong[Providers.GetIndexLong(claim.ProvTreat)];
			insPlan=InsPlans.GetPlan(planNum,new List <InsPlan> ());
			insSub=InsSubs.GetSub(insSubNum,new List<InsSub>());
			if(planNum2>0) {
				insPlan2=InsPlans.GetPlan(planNum2,new List<InsPlan>());
				insSub2=InsSubs.GetSub(insSubNum2,new List<InsSub>());
				carrier2=Carriers.GetCarrier(insPlan2.CarrierNum);
				subscriber2=Patients.GetPat(insSub2.Subscriber);
			}
			if(claim.ClaimType=="S") {
				carrier=Carriers.GetCarrier(insPlan2.CarrierNum);
			}
			else {
				carrier=Carriers.GetCarrier(insPlan.CarrierNum);
			}
			CanadianNetwork network=CanadianNetworks.GetNetwork(carrier.CanadianNetworkNum);
			patPlansForPatient=PatPlans.Refresh(claim.PatNum);
			patient=Patients.GetPat(claim.PatNum);
			subscriber=Patients.GetPat(insSub.Subscriber);
			procListAll=Procedures.Refresh(claim.PatNum);
			extracted=Procedures.GetCanadianExtractedTeeth(procListAll);
			strb=new StringBuilder();
			//A01 transaction prefix 12 AN
			strb.Append(TidyAN(network.CanadianTransactionPrefix,12));
			//A02 office sequence number 6 N
			strb.Append(TidyN(etrans.OfficeSequenceNumber,6));
			//A03 format version number 2 N
			if(carrier.CDAnetVersion=="") {
				strb.Append("04");
			}
			else {
				strb.Append(carrier.CDAnetVersion);
			}
			//A04 transaction code 2 N
			if(claim.ClaimType=="PreAuth") {
				strb.Append("03");//Predetermination
			}
			else {
				if(claim.ClaimType=="S") {
					strb.Append("07");//cob
				}
				else {
					strb.Append("01");//claim
				}
			}
			//A05 carrier id number 6 N
			strb.Append(carrier.ElectID);//already validated as 6 digit number.
			//A06 software system id 3 AN
			strb.Append(SoftwareSystemId());
			if(carrier.CDAnetVersion!="02") { //version 04
				//A10 encryption method 1 N
				strb.Append(carrier.CanadianEncryptionMethod);//validated in UI
			}
			//A07 message length. 5 N in version 04, 4 N in version 02
			//We simply create a place holder here. We come back at the end of message construction and record the actual final message length.
			if(carrier.CDAnetVersion=="02") {
				strb.Append("0000");
			}
			else { //version 04
				strb.Append("00000");
			}
			if(carrier.CDAnetVersion=="02") {
				//A08 email flag 1 N
				if(claim.CanadianMaterialsForwarded=="") {
					strb.Append("0"); //no additional information
				}
				else if(claim.CanadianMaterialsForwarded.Contains("E")) {
					strb.Append("1"); //E-Mail to follow.
				}
				else {
					strb.Append("2"); //Letter to follow
				}
			}
			else { //version 04
				//A08 materials forwarded 1 AN
				strb.Append(GetMaterialsForwarded(claim.CanadianMaterialsForwarded));
			}
			if(carrier.CDAnetVersion!="02") { //version 04
				//A09 carrier transaction counter 5 N
#if DEBUG
				strb.Append("00001");
#else				
				strb.Append(TidyN(etrans.CarrierTransCounter,5));
#endif
			}
			//B01 CDA provider number 9 AN
			strb.Append(TidyAN(treatProv.NationalProvID,9));//already validated
			//B02 (treating) provider office number 4 AN
			strb.Append(TidyAN(treatProv.CanadianOfficeNum,4));//already validated	
			if(carrier.CDAnetVersion!="02") { //version 04
				//B03 billing provider number 9 AN
				//might need to account for possible 5 digit prov id assigned by carrier
				strb.Append(TidyAN(billProv.NationalProvID,9));//already validated
				//B04 billing provider office number 4 AN
				strb.Append(TidyAN(billProv.CanadianOfficeNum,4));//already validated	
				//B05 referring provider 10 AN
				strb.Append(TidyAN(claim.CanadianReferralProviderNum,10));
				//B06 referral reason 2 N
				strb.Append(TidyN(claim.CanadianReferralReason,2));
			}
			if(carrier.CDAnetVersion=="02") {
				//C01 primary policy/plan number 8 AN
				//only validated to ensure that it's not blank and is less than 8. Also that no spaces.
				strb.Append(TidyAN(insPlan.GroupNum,8));
			}
			else { //version 04
				//C01 primary policy/plan number 12 AN
				//only validated to ensure that it's not blank and is less than 12. Also that no spaces.
				strb.Append(TidyAN(insPlan.GroupNum,12));
			}
			//C11 primary division/section number 10 AN
			strb.Append(TidyAN(insPlan.DivisionNo,10));
			if(carrier.CDAnetVersion=="02") {
				//C02 subscriber id number 11 AN
				strb.Append(TidyAN(insSub.SubscriberID.Replace("-",""),11));//validated
			}
			else { //version 04
				//C02 subscriber id number 12 AN
				strb.Append(TidyAN(insSub.SubscriberID.Replace("-",""),12));//validated
			}
			if(carrier.CDAnetVersion!="02") { //version 04
				//C17 primary dependant code 2 N
				string patID="";
				for(int p=0;p<patPlansForPatient.Count;p++) {
					if(patPlansForPatient[p].InsSubNum==insSubNum) {
						patID=patPlansForPatient[p].PatID;
					}
				}
				strb.Append(TidyN(patID,2));
			}
			//C03 relationship code 1 N
			//User interface does not only show Canadian options, but all options are handled.
			strb.Append(GetRelationshipCode(patRelat));
			//C04 patient's sex 1 A
			//validated to not include "unknown"
			if(patient.Gender==PatientGender.Male){
				strb.Append("M");
			}
			else{
				strb.Append("F");
			}
			//C05 patient birthday 8 N
			strb.Append(patient.Birthdate.ToString("yyyyMMdd"));//validated
			if(carrier.CDAnetVersion=="02") {
				//C06 patient last name 25 A
				strb.Append(TidyA(patient.LName,25));//validated
			}
			else { //version 04
				//C06 patient last name 25 AE
				strb.Append(TidyAE(patient.LName,25,true));//validated
			}
			if(carrier.CDAnetVersion=="02") {
				//C07 patient first name 15 A
				strb.Append(TidyA(patient.FName,15));//validated
			}
			else { //version 04
				//C07 patient first name 15 AE
				strb.Append(TidyAE(patient.FName,15,true));//validated
			}
			if(carrier.CDAnetVersion=="02") {
				//C08 patient middle initial 1 A
				strb.Append(TidyA(patient.MiddleI,1));
			}
			else { //version 04
				//C08 patient middle initial 1 AE
				strb.Append(TidyAE(patient.MiddleI,1));
			}
			if(carrier.CDAnetVersion=="02") {
				//C09 eligibility exception code 1 N
				string exceptionCode=TidyN(patient.CanadianEligibilityCode,1);//Validated.
				if(exceptionCode=="4") {
					exceptionCode="0";//Code 4 in version 04 means "code not applicable", but in version 02, value 0 means "code not applicable".
				}
				strb.Append(exceptionCode);//validated
			}
			else { //version 04
				//C09 eligibility exception code 1 N
				strb.Append(TidyN((patient.CanadianEligibilityCode==0)?4:patient.CanadianEligibilityCode,1));//Validated. Use "code not applicable" when no value has been specified by the user.
			}
			if(carrier.CDAnetVersion=="02") {
				//C10 name of school 25 A
				//validated if patient 18yrs or older and full-time student (or disabled student)
				strb.Append(TidyA(patient.SchoolName,25));
			}
			else { //version 04
				//C10 name of school 25 AEN
				//validated if patient 18yrs or older and full-time student (or disabled student)
				strb.Append(TidyAEN(patient.SchoolName,25));
			}
			bool C19PlanRecordPresent=(insPlan.CanadianPlanFlag=="A" || insPlan.CanadianPlanFlag=="N" || insPlan.CanadianPlanFlag=="V");
			if(carrier.CDAnetVersion!="02") { //version 04
				//C12 plan flag 1 A
				strb.Append(Canadian.GetPlanFlag(insPlan.CanadianPlanFlag));
				//C18 plan record count 1 N
				if(C19PlanRecordPresent) {
					strb.Append("1");
				}
				else {
					strb.Append("0");
				}
			}
			CCDFieldInputter primaryClaimData=null;
			if(claim.ClaimType=="S") {
				primaryClaimData=new CCDFieldInputter(primaryClaimRequestMessage);
			}
			//D01 subscriber birthday 8 N
			strb.Append(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D01").valuestr:subscriber.Birthdate.ToString("yyyyMMdd"));//validated
			if(carrier.CDAnetVersion=="02") {
				//D02 subscriber last name 25 A
				strb.Append(TidyA(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D02").valuestr:subscriber.LName,25));//validated
			}
			else { //version 04
				//D02 subscriber last name 25 AE
				strb.Append(TidyAE(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D02").valuestr:subscriber.LName,25,true));//validated
			}
			if(carrier.CDAnetVersion=="02") {
				//D03 subscriber first name 15 A
				strb.Append(TidyA(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D03").valuestr:subscriber.FName,15));//validated
			}
			else { //version 04
				//D03 subscriber first name 15 AE
				strb.Append(TidyAE(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D03").valuestr:subscriber.FName,15,true));//validated
			}
			if(carrier.CDAnetVersion=="02") {
				//D04 subscriber middle initial 1 A
				strb.Append(TidyA(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D04").valuestr:subscriber.MiddleI,1));
			}
			else { //version 04
				//D04 subscriber middle initial 1 AE
				strb.Append(TidyAE(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D04").valuestr:subscriber.MiddleI,1));
			}
			if(carrier.CDAnetVersion=="02") {
				//D05 subscriber address line one 30 AN
				strb.Append(TidyAN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D05").valuestr:subscriber.Address,30,true));//validated
			}
			else { //version 04
				//D05 subscriber address line one 30 AEN
				strb.Append(TidyAEN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D05").valuestr:subscriber.Address,30,true));//validated
			}
			if(carrier.CDAnetVersion=="02") {
				//D06 subscriber address line two 30 AN
				strb.Append(TidyAN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D06").valuestr:subscriber.Address2,30,true));
			}
			else { //version 04
				//D06 subscriber address line two 30 AEN
				strb.Append(TidyAEN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D06").valuestr:subscriber.Address2,30,true));
			}
			if(carrier.CDAnetVersion=="02") {
				//D07 subscriber city 20 A
				strb.Append(TidyA(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D07").valuestr:subscriber.City,20));//validated
			}
			else { //version 04
				//D07 subscriber city 20 AEN
				strb.Append(TidyAEN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D07").valuestr:subscriber.City,20,true));//validated
			}
			//D08 subscriber province/state 2 A
			strb.Append(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D08").valuestr:subscriber.State);//very throroughly validated previously
			if(carrier.CDAnetVersion=="02") {
				//D09 subscriber postal/zip code 6 AN
				strb.Append(TidyAN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D09").valuestr:subscriber.Zip.Replace("-","").Replace(" ",""),6));//validated.
			}
			else { //version 04
				//D09 subscriber postal/zip code 9 AN
				strb.Append(TidyAN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D09").valuestr:subscriber.Zip.Replace("-","").Replace(" ",""),9));//validated.
			}
			//D10 language of insured 1 A
			strb.Append(claim.ClaimType=="S"?primaryClaimData.GetFieldById("D10").valuestr:(subscriber.Language=="fr"?"F":"E"));
			bool orthoRecordFlag=false;
			if(carrier.CDAnetVersion!="02") { //version 04
				//D11 card sequence/version number 2 N
				//Not validated against type of carrier yet. Might need to check if Dentaide.
				strb.Append(TidyN(insPlan.DentaideCardSequence,2));
				//E18 secondary coverage flag 1 A
				if(planNum2>0) {
					strb.Append("Y");
				}
				else {
					strb.Append("N");
				}
				//E20 secondary record count 1 N
				if(planNum2==0) {
					strb.Append("0");
				}
				else {
					strb.Append("1");
				}
				//F06 number of procedures performed 1 N. Must be between 1 and 7.  UI prevents attaching more than 7.
				strb.Append(TidyN(claimProcsClaim.Count,1));//number validated
				//F22 extracted teeth count 2 N
				strb.Append(TidyN(extracted.Count,2));//validated against matching prosthesis
				if(claim.ClaimType=="PreAuth") {
					orthoRecordFlag=(claim.CanadaEstTreatStartDate.Year>1880 || claim.CanadaInitialPayment!=0 || claim.CanadaPaymentMode!=0 ||
						claim.CanadaTreatDuration!=0 || claim.CanadaNumAnticipatedPayments!=0 || claim.CanadaAnticipatedPayAmount!=0);
					//F25 Orthodontic Record Flag 1 N
					if(orthoRecordFlag) {
						strb.Append("1");
					}
					else {
						strb.Append("0");
					}
				}
				if(claim.ClaimType=="S") { //cob
					//G39 Embedded Transaction Length N 4
					strb.Append(Canadian.TidyN(primaryEOBResponse.Length,4));
				}
			}
			//Secondary carrier fields (E19 to E07) ONLY included if E20=1----------------------------------------------------
			if(planNum2!=0) {
				if(carrier.CDAnetVersion!="02") { //version 04
					//E19 secondary carrier transaction number 6 N
					strb.Append(TidyN(etrans.CarrierTransCounter2,6));
				}
				//E01 sec carrier id number 6 N
				strb.Append(carrier2.ElectID);//already validated as 6 digit number.
				if(carrier.CDAnetVersion=="02") {
					//E02 sec carrier policy/plan num 8 AN
					//only validated to ensure that it's not blank and is less than 8. Also that no spaces.
					//We might later allow 999999 if sec carrier is unlisted or unknown.
					strb.Append(TidyAN(insPlan2.GroupNum,8));
				}
				else { //version 04
					//E02 sec carrier policy/plan num 12 AN
					//only validated to ensure that it's not blank and is less than 12. Also that no spaces.
					//We might later allow 999999 if sec carrier is unlisted or unknown.
					strb.Append(TidyAN(insPlan2.GroupNum,12));
				}
				//E05 sec division/section num 10 AN
				strb.Append(TidyAN(insPlan2.DivisionNo,10));
				if(carrier.CDAnetVersion=="02") {
					//E03 sec plan subscriber id 11 AN
					strb.Append(TidyAN(insSub2.SubscriberID.Replace("-",""),11));//validated
				}
				else { //version 04
					//E03 sec plan subscriber id 12 AN
					strb.Append(TidyAN(insSub2.SubscriberID.Replace("-",""),12));//validated
				}
				if(carrier.CDAnetVersion!="02") { //version 04
					//E17 sec dependent code 2 N
					string patID="";
					for(int p=0;p<patPlansForPatient.Count;p++) {
						if(patPlansForPatient[p].InsSubNum==insSubNum2) {
							patID=patPlansForPatient[p].PatID;
						}
					}
					strb.Append(TidyN(patID,2));
					//E06 sec relationship code 1 N
					//User interface does not only show Canadian options, but all options are handled.
					strb.Append(GetRelationshipCode(patRelat2));
				}
				//E04 sec subscriber birthday 8 N
				strb.Append(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E04").valuestr:subscriber2.Birthdate.ToString("yyyyMMdd"));//validated
				if(carrier.CDAnetVersion!="02") { //version 04
					//E08 sec subscriber last name 25 AE
					strb.Append(TidyAE(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E08").valuestr:subscriber2.LName,25,true));//validated
					//E09 sec subscriber first name 15 AE
					strb.Append(TidyAE(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E09").valuestr:subscriber2.FName,15,true));//validated
					//E10 sec subscriber middle initial 1 AE
					strb.Append(TidyAE(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E10").valuestr:subscriber2.MiddleI,1));
					//E11 sec subscriber address one 30 AEN
					strb.Append(TidyAEN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E11").valuestr:subscriber2.Address,30,true));//validated
					//E12 sec subscriber address two 30 AEN
					strb.Append(TidyAEN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E12").valuestr:subscriber2.Address2,30,true));
					//E13 sec subscriber city 20 AEN
					strb.Append(TidyAEN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E13").valuestr:subscriber2.City,20,true));//validated
					//E14 sec subscriber province/state 2 A
					strb.Append(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E14").valuestr:subscriber2.State);//very throroughly validated previously
					//E15 sec subscriber postal/zip code 9 AN
					strb.Append(TidyAN(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E15").valuestr:subscriber2.Zip.Replace("-","").Replace(" ",""),9));//validated
					//E16 sec language 1 A
					strb.Append(claim.ClaimType=="S"?primaryClaimData.GetFieldById("E16").valuestr:(subscriber2.Language=="fr"?"F":"E"));
					//E07 sec card sequence/version num 2 N
					//todo Not validated yet.
					strb.Append(TidyN(claim.ClaimType=="S"?PIn.Int(primaryClaimData.GetFieldById("E07").valuestr):insPlan2.DentaideCardSequence,2));
				}
				//End of secondary subscriber fields---------------------------------------------------------------------------
			}
			else { //There is no secondary plan.
				if(carrier.CDAnetVersion=="02") { 
					//Secondary subscriber fields are always available in version 2. Since there is no plan, put blank data as a filler.
					//E01 N 6
					strb.Append("000000");
					//E02 AN 8
					strb.Append("        ");
					//E05 AN 10
					strb.Append("          ");
					//E03 AN 11
					strb.Append("           ");
					//E04 N 8
					strb.Append("00000000");
				}
			}
			if(claim.ClaimType!="PreAuth") {
				//F01 payee code 1 N
				if((claim.ClaimType!="S" && insSub.AssignBen) || (claim.ClaimType=="S" && insSub2.AssignBen)) {
					if(carrier.CDAnetVersion=="02") {
						strb.Append("0");//pay dentist
					}
					else { //version 04
						strb.Append("4");//pay dentist
					}
				}
				else {
					strb.Append("1");//pay subscriber
				}
			}
			//F02 accident date 8 N
			if(claim.AccidentDate.Year>1900){//if accident related
				strb.Append(claim.AccidentDate.ToString("yyyyMMdd"));//validated
			}
			else{
				strb.Append(TidyN(0,8));
			}
			if(claim.ClaimType!="PreAuth") {
				//F03 predetermination number 14 AN
				strb.Append(TidyAN(claim.PreAuthString,14));
			}
			if(carrier.CDAnetVersion=="02") {
				//F15 Is this an Initial Replacement? A 1
				string initialPlacement="Y";
				DateTime initialPlacementDate=DateTime.MinValue;
				if(claim.CanadianIsInitialUpper=="Y"){
					initialPlacement="Y";
					initialPlacementDate=claim.CanadianDateInitialUpper;
				}
				else if(claim.CanadianIsInitialLower=="Y"){
					initialPlacement="Y";
					initialPlacementDate=claim.CanadianDateInitialLower;
				}
				else if(claim.CanadianIsInitialUpper=="N") {
					initialPlacement="N";
					initialPlacementDate=claim.CanadianDateInitialUpper;
				}
				else if(claim.CanadianIsInitialLower=="N"){
					initialPlacement="N";
					initialPlacementDate=claim.CanadianDateInitialLower;
				}
				strb.Append(initialPlacement);
				//F04 date of initial placement 8 N
				if(initialPlacementDate.Year>1900) {
					strb.Append(initialPlacementDate.ToString("yyyyMMdd"));
				}
				else {
					strb.Append("00000000");
				}
				//F05 tx req'd for ortho purposes 1 A
				if(claim.IsOrtho) {
					strb.Append("Y");
				}
				else {
					strb.Append("N");
				}
				//F06 number of procedures performed 1 N. Must be between 1 and 7.  UI prevents attaching more than 7.
				strb.Append(TidyN(claimProcsClaim.Count,1));//number validated
			}
			else { //version 04
				//F15 initial placement upper 1 A  Y or N or X
				strb.Append(Canadian.TidyA(claim.CanadianIsInitialUpper,1));//validated
				//F04 date of initial placement upper 8 N
				if(claim.CanadianDateInitialUpper.Year>1900) {
					strb.Append(claim.CanadianDateInitialUpper.ToString("yyyyMMdd"));
				}
				else {
					strb.Append("00000000");
				}
				//F18 initial placement lower 1 A
				strb.Append(Canadian.TidyA(claim.CanadianIsInitialLower,1));//validated
				//F19 date of initial placement lower 8 N
				if(claim.CanadianDateInitialLower.Year>1900) {
					strb.Append(claim.CanadianDateInitialLower.ToString("yyyyMMdd"));
				}
				else {
					strb.Append("00000000");
				}
				//F05 tx req'd for ortho purposes 1 A
				if(claim.IsOrtho) {
					strb.Append("Y");
				}
				else {
					strb.Append("N");
				}
				//F20 max prosth material 1 N
				if(claim.CanadianMaxProsthMaterial==7) {//our fake crown code
					strb.Append("0");
				}
				else {
					strb.Append(claim.CanadianMaxProsthMaterial.ToString());//validated
				}
				//F21 mand prosth material 1 N
				if(claim.CanadianMandProsthMaterial==7) {//our fake crown code
					strb.Append("0");
				}
				else {
					strb.Append(claim.CanadianMandProsthMaterial.ToString());//validated
				}
			}
			if(carrier.CDAnetVersion!="02") { //version 04
				//If F22 is non-zero. Repeat for the number of times specified by F22.----------------------------------------------
				for(int t=0;t<extracted.Count;t++) {
					//F23 extracted tooth num 2 N
					//todo: check validation
					strb.Append(TidyN(Tooth.ToInternat(extracted[t].ToothNum),2));//validated
					//F24 extraction date 8 N
					//todo: check validation
					strb.Append(extracted[t].ProcDate.ToString("yyyyMMdd"));//validated
				}
			}
			if(carrier.CDAnetVersion!="02") { //version 04
				if(claim.ClaimType=="PreAuth") {
#if DEBUG
					//We are required to test multi-page (up to 7 procs per page) predeterminations for certification. We do not actually do this in the real world.
					//We will use the claim.PreAuthString here to pass these useless numbers in for testing purposes, since this field is not used for predetermination claims for any other reason.
					int currentPredeterminationPageNumber=1;
					int lastPredeterminationPageNumber=1;
					if(claim.PreAuthString!="") {
						string[] predetermNums=claim.PreAuthString.Split(new char[] { ',' });
						currentPredeterminationPageNumber=PIn.Int(predetermNums[0]);
						lastPredeterminationPageNumber=PIn.Int(predetermNums[1]);
					}
					//G46 Current Predetermination Page Number N 1
					strb.Append(Canadian.TidyN(currentPredeterminationPageNumber,1));
					//G47 Last Predetermination Page Number N 1
					strb.Append(Canadian.TidyN(lastPredeterminationPageNumber,1));
#else
					//G46 Current Predetermination Page Number N 1
					strb.Append("1");//Always 1 page, because UI prevents attaching more than 7 procedures per claim in Canadian mode.
					//G47 Last Predetermination Page Number N 1
					strb.Append("1");//Always 1 page, because UI prevents attaching more than 7 procedures per claim in Canadian mode.
#endif
					if(orthoRecordFlag) { //F25 is set
						//F37 Estimated Treatment Starting Date N 8
						strb.Append(Canadian.TidyN(claim.CanadaEstTreatStartDate.ToString("yyyyMMdd"),8));
						double firstExamFee=0;
						double diagnosticPhaseFee=0;
#if DEBUG //Fields F26 and F27 are not required in the real world, but there are a few certification tests that require this information in order for the test to pass.
						if(claim.PreAuthString!="") {
							string[] preauthData=claim.PreAuthString.Split(new char[] { ',' });
							if(preauthData.Length>2) {
								firstExamFee=PIn.Double(preauthData[2]);
							}
							if(preauthData.Length>3) {
								diagnosticPhaseFee=PIn.Double(preauthData[3]);
							}
						}
#endif
						//F26 First Examination Fee D 6
						strb.Append(Canadian.TidyD(firstExamFee,6));//optional
						//F27 Diagnostic Phase Fee D 6
						strb.Append(Canadian.TidyD(diagnosticPhaseFee,6));//optional
						//F28 Initial Payment D 6
						strb.Append(Canadian.TidyD(claim.CanadaInitialPayment,6));
						//F29 Payment Mode N 1
						strb.Append(Canadian.TidyN(claim.CanadaPaymentMode,1));//Validated in UI.
						//F30 Treatment Duration N 2
						strb.Append(Canadian.TidyN(claim.CanadaTreatDuration,2));
						//F31 Number of Anticipated Payments N 2
						strb.Append(Canadian.TidyN(claim.CanadaNumAnticipatedPayments,2));
						//F32 Anticipated Payment Amount D 6
						strb.Append(Canadian.TidyD(claim.CanadaAnticipatedPayAmount,6));
					}
				}
			}
			//Procedures: Repeat for number of times specified by F06.----------------------------------------------------------
			for(int p=0;p<claimProcsClaim.Count;p++) {
				//claimProcsClaim already excludes any claimprocs with ProcNum=0, so no payments etc.
				proc=Procedures.GetProcFromList(procListAll,claimProcsClaim[p].ProcNum);
				procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
				procListLabForOne=Procedures.GetCanadianLabFees(proc.ProcNum,procListAll);
				//F07 proc line number 1 N
				strb.Append((p+1).ToString());
				if(carrier.CDAnetVersion=="02") {
					//F08 procedure code 5 N
					strb.Append(TidyN(claimProcsClaim[p].CodeSent,5).Trim().PadLeft(5,'0'));
				}
				else { //version 04
					//F08 procedure code 5 AN
					strb.Append(TidyAN(claimProcsClaim[p].CodeSent,5).Trim().PadLeft(5,'0'));
				}
				if(claim.ClaimType!="PreAuth") {
					//F09 date of service 8 N
					strb.Append(claimProcsClaim[p].ProcDate.ToString("yyyyMMdd"));//validated
				}
				//F10 international tooth, sextant, quad, or arch 2 N
				strb.Append(GetToothQuadOrArch(proc,procCode));
				//F11 tooth surface 5 A
				//the SurfTidy function is very thorough, so it's OK to use TidyAN
				if(procCode.TreatArea==TreatmentArea.Surf) {
#if DEBUG
					//since the scripts use impossible surfaces, we need to just use raw database here
					strb.Append(TidyAN(proc.Surf,5));
#else
					strb.Append(TidyAN(Tooth.SurfTidyForClaims(proc.Surf,proc.ToothNum),5));
#endif
				}
				else {
					strb.Append("     ");
				}
				//F12 dentist's fee claimed 6 D
				strb.Append(TidyD(claimProcsClaim[p].FeeBilled,6));
				if(carrier.CDAnetVersion!="02") { //version 04
					//F34 lab procedure code #1 5 AN
					if(procListLabForOne.Count>0) {
						strb.Append(TidyAN(ProcedureCodes.GetProcCode(procListLabForOne[0].CodeNum).ProcCode,5).Trim().PadLeft(5,'0'));
					}
					else {
						strb.Append("     ");
					}
				}
				//F13 lab procedure fee #1 6 D
				if(procListLabForOne.Count>0){
					strb.Append(TidyD(procListLabForOne[0].ProcFee,6));
				}
				else{
					strb.Append("000000");
				}
				if(carrier.CDAnetVersion=="02") {
					//F14 Unit of Time D 4
					//This is a somewhat deprecated field becacuse it no longer exists in version 04. Some carriers reject claims 
					//if there is a time specified for a procedure that does not require a time. It is safest for now to just set
					//this value to zero always.
					double procHours=0;
					//procHours=(PrefC.GetInt(PrefName.AppointmentTimeIncrement)*procCode.ProcTime.Length)/60.0;
					strb.Append(TidyD(procHours,4));
				}
				else { //version 04
					//F35 lab procedure code #2 5 AN
					if(procListLabForOne.Count>1) {
						strb.Append(TidyAN(ProcedureCodes.GetProcCode(procListLabForOne[1].CodeNum).ProcCode,5).Trim().PadLeft(5,'0'));
					}
					else {
						strb.Append("     ");
					}
					//F36 lab procedure fee #2 6 D
					if(procListLabForOne.Count>1) {
						strb.Append(TidyD(procListLabForOne[1].ProcFee,6));
					}
					else {
						strb.Append("000000");
					}
					//F16 procedure type codes 5 A
					strb.Append(TidyA((proc.CanadianTypeCodes==null || proc.CanadianTypeCodes=="")?"X":proc.CanadianTypeCodes,5));
					//F17 remarks code 2 N
					//optional.  PMP field.  See C12. Zeros when not used.
					strb.Append("00");
				}
			}
			if(carrier.CDAnetVersion!="02") { //version 04
				//C19 plan record 30 AN
				if(C19PlanRecordPresent) {
					if(insPlan.CanadianPlanFlag=="A") {
						//insPlan.CanadianDiagnosticCode and insPlan.CanadianInstitutionCode are validated in the UI.
						strb.Append(Canadian.TidyAN(Canadian.TidyAN(insPlan.CanadianDiagnosticCode,6,true)+Canadian.TidyAN(insPlan.CanadianInstitutionCode,6,true),30,true));
					}
					else { //N or V. These two plan flags are not yet in use. Presumably, for future use.
						strb.Append(Canadian.TidyAN("",30));
					}
				}
			}
			//We are required to append the primary EOB. This is not a data dictionary field.
			if(claim.ClaimType=="S") {
				strb.Append(ConvertEOBVersion(primaryEOBResponse,carrier.CDAnetVersion));
			}
			//Now we go back and fill in the actual message length now that we know the number for sure.
			if(carrier.CDAnetVersion=="02") {
				strb.Replace("0000",Canadian.TidyN(strb.Length,4),31,4);
			}
			else { //version 04
				strb.Replace("00000",Canadian.TidyN(strb.Length,5),32,5);
			}
			//end of creating the message
			//this is where we attempt the actual sending:
			string result="";
			bool resultIsError=false;
			try{
#if DEBUG
				if(claim.ClaimType=="PreAuth") { //Predeterminations
					if(testNumber==3) { //Predetermination test #3
						strb.Replace("Y","N",563,1);//We use claim.IsOrtho for fields F05 and F25, but for some reason in this example the values expected are opposite. We think this is a problem with the CDANet test.
						strb.Replace("00000000","35000025",577,8);//These are optional fields (F26 and F27), so we have not implemented them, but the test does not work without them for some reason.
					}
				}
#endif
				result=PassToIca(strb.ToString(),clearhouse);
			}
			catch(ApplicationException ex) {
				result=ex.Message;
				resultIsError=true;
			}
			//Attach an ack to the etrans
			Etrans etransAck=new Etrans();
			etransAck.PatNum=etrans.PatNum;
			etransAck.PlanNum=etrans.PlanNum;
			etransAck.InsSubNum=etrans.InsSubNum;
			etransAck.CarrierNum=etrans.CarrierNum;
			etransAck.ClaimNum=etrans.ClaimNum;
			etransAck.DateTimeTrans=DateTime.Now;
			CCDFieldInputter fieldInputter=null;
			if(resultIsError){
				etransAck.Etype=EtransType.AckError;
				etrans.Note="failed";
			}
			else{
				fieldInputter=new CCDFieldInputter(result);
				CCDField fieldG05=fieldInputter.GetFieldById("G05");
				if(fieldG05!=null) {
					etransAck.AckCode=fieldG05.valuestr;
					if(etransAck.AckCode=="M") { //Manually print the claim form.
						PrintCdaClaimForm(claim);
					}
				}
				etransAck.Etype=fieldInputter.GetEtransType();
			}
			Etranss.Insert(etransAck);
			Etranss.SetMessage(etransAck.EtransNum,result);
			etrans.AckEtransNum=etransAck.EtransNum;
			Etranss.Update(etrans);
			Etranss.SetMessage(etrans.EtransNum,strb.ToString());
			if(resultIsError) {
				throw new ApplicationException(result);
			}
			if(claim.ClaimType!="PreAuth") {
				Claims.SetCanadianClaimSent(queueItem.ClaimNum);//when called from ClaimEdit, that window will close immediately, so we're directly changing the db.
				CCDField fieldTransRefNum=fieldInputter.GetFieldById("G01");
				if(fieldTransRefNum!=null) {
					if(etransAck.AckCode!="R") {
						claim.CanadaTransRefNum=fieldTransRefNum.valuestr;
						Claims.Update(claim);
					}
				}
			}
			if(doPrint) {
				new FormCCDPrint(etrans,result,true);//Physically print the form.
			}
			if(claim.ClaimType!="PreAuth" && claim.ClaimType!="S" && etransAck.Etype==EtransType.ClaimEOB_CA && planNum2>0) {//if an eob was returned and patient has secondary insurance.
				//if an EOB is returned, there are two possibilities.
				//1. The EOB contains an embedded EOB because the same carrier is both pri and sec.  Both got printed above.
				//2. The EOB does not contain an embedded EOB, indicating that a COB claim needs to be created and sent.
				//That is done here, automatically.
				//UI already prevents the initial automatic creation of the secondary claim for Canada.
				string embeddedLength=fieldInputter.GetValue("G39");
				if(embeddedLength=="" || embeddedLength=="0000") {//no embedded message
					Claim claim2=new Claim();
					claim2.PatNum=claim.PatNum;
					claim2.DateService=claim.DateService;
					claim2.DateSent=DateTime.Today;
					claim2.ClaimStatus="W";
					claim2.PlanNum=planNum2;
					claim2.InsSubNum=insSubNum2;
					claim2.PatRelat=patRelat2;
					claim2.PlanNum2=planNum;
					claim2.InsSubNum2=insSubNum;
					claim2.PatRelat2=patRelat;
					claim2.ClaimType="S";
					claim2.ProvTreat=claim.ProvTreat;
					claim2.IsProsthesis="N";
					claim2.ProvBill=claim.ProvBill;
					claim2.EmployRelated=YN.No;
					claim2.AccidentDate=claim.AccidentDate;
					claim2.IsOrtho=claim.IsOrtho;
					claim2.CanadianDateInitialLower=claim.CanadianDateInitialLower;
					claim2.CanadianDateInitialUpper=claim.CanadianDateInitialUpper;
					claim2.CanadianIsInitialLower=claim.CanadianIsInitialLower;
					claim2.CanadianIsInitialUpper=claim.CanadianIsInitialUpper;
					claim2.CanadianMandProsthMaterial=claim.CanadianMandProsthMaterial;
					claim2.CanadianMaterialsForwarded=claim.CanadianMaterialsForwarded;
					claim2.CanadianMaxProsthMaterial=claim.CanadianMaxProsthMaterial;
					claim2.CanadianReferralProviderNum=claim.CanadianReferralProviderNum;
					claim2.CanadianReferralReason=claim.CanadianReferralReason;
					Claims.Insert(claim2);//to retreive a key for new Claim.ClaimNum
					ClaimProc[] claimProcsClaim2=new ClaimProc[claimProcsClaim.Count];
					long procNum;
					for(int i=0;i<claimProcsClaim.Count;i++) {//loop through the procs from claim 1
						//and try to find an estimate that can be used
						procNum=claimProcsClaim[i].ProcNum;
						claimProcsClaim2[i]=Procedures.GetClaimProcEstimate(procNum,claimProcList,insPlan2,claim2.InsSubNum2);
					}
					for(int i=0;i<claimProcsClaim2.Length;i++) {//loop through each claimProc
						//and create any missing estimates just in case
						if(claimProcsClaim2[i]==null) {
							claimProcsClaim2[i]=new ClaimProc();
							//claimProcsClaim and claimProcsClaim2 already exclude any claimprocs with ProcNum=0, so no payments etc.
							proc=Procedures.GetProcFromList(procListAll,claimProcsClaim[i].ProcNum);
							ClaimProcs.CreateEst(claimProcsClaim2[i],proc,insPlan2,insSub2);
						}
					}
					for(int i=0;i<claimProcsClaim2.Length;i++) {
						//claimProcsClaim and claimProcsClaim2 already exclude any claimprocs with ProcNum=0, so no payments etc.
						proc=Procedures.GetProcFromList(procListAll,claimProcsClaim2[i].ProcNum);//1:1
						claimProcsClaim2[i].ClaimNum=claim2.ClaimNum;
						claimProcsClaim2[i].Status=ClaimProcStatus.NotReceived;
						claimProcsClaim2[i].CodeSent=claimProcsClaim[i].CodeSent;
						claimProcsClaim2[i].LineNumber=(byte)(i+1);
						ClaimProcs.Update(claimProcsClaim2[i]);
					}
					claimProcList=ClaimProcs.Refresh(claim2.PatNum);
					Family fam=Patients.GetFamily(claim2.PatNum);
					List<InsSub> subList=InsSubs.RefreshForFam(fam);
					List<InsPlan> planList=InsPlans.RefreshForSubList(subList);
					List<Benefit> benefitList=Benefits.Refresh(patPlansForPatient,subList);
					ClaimL.CalculateAndUpdate(procListAll,planList,claim2,patPlansForPatient,benefitList,patient.Age,subList);
					ClaimSendQueueItem queueItem2=Claims.GetQueueList(claim2.ClaimNum,claim2.ClinicNum,0)[0];
					string responseMessageVersion=result.Substring(18,2);//Field A03 always exists on all messages and is always in the same location.
					//ok to skip validation
					//We can only send an electronic secondary claim when the EOB received from the primary insurance is a version 04 message and when
					//the secondary carrier accepts secondary claims electronically (COBs). Otherwise, the user must send the claim by paper.
					if(responseMessageVersion!="02" && (carrier2.CanadianSupportedTypes&CanSupTransTypes.CobClaimTransaction_07)==CanSupTransTypes.CobClaimTransaction_07) {
						long etransNum=SendClaim(queueItem2,doPrint);//recursive
						return etransNum;//for now, we'll return the etransnum of the secondary ack.
					}
					//The secondary carrier does not support COB claim transactions. We must print a manual claim form.
					if(doPrint) {
						PrintCdaClaimForm(claim2);
					}
				}
				else {//an embedded message exists
					//string embeddedMsg=fieldInputter.GetValue("G40");
					//MsgBoxCopyPaste msgbox=new MsgBoxCopyPaste(embeddedMsg);
					//msgbox.Show();
					//actually, nothing to do here because already printed above.
				}
			}
			return etransAck.EtransNum;
		}
Exemplo n.º 24
0
		///<summary>Surround with try/catch.  If there are any dependencies, then this will throw an exception.  This is currently only called from FormClaimProc.</summary>
		public static void DeleteAfterValidating(ClaimProc cp) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				Meth.GetVoid(MethodBase.GetCurrentMethod(),cp);
				return;
			}
			string command;
			//Validate: make sure this is not the last claimproc on the claim.  If cp is not attached to a claim no need to validate.
			if(cp.ClaimNum!=0) {
				command="SELECT COUNT(*) FROM claimproc WHERE ClaimNum= "+POut.Long(cp.ClaimNum)+" AND ClaimProcNum!= "+POut.Long(cp.ClaimProcNum);
				long remainingCP=PIn.Long(Db.GetCount(command));
				if(remainingCP==0) {
					throw new ApplicationException(Lans.g("ClaimProcs","Not allowed to delete the last procedure from a claim.  The entire claim would have to be deleted."));
				}
			}
			//end of validation
			command= "DELETE FROM claimproc WHERE ClaimProcNum = "+POut.Long(cp.ClaimProcNum);
			Db.NonQ(command);
		}
Exemplo n.º 25
0
 public static string GetPercentageDisplay(ClaimProc cp)
 {
     //No need to check RemotingRole; no call to db.
     if(cp.Status==ClaimProcStatus.CapEstimate || cp.Status==ClaimProcStatus.CapComplete) {
         return "";
     }
     if(cp.PercentOverride!=-1) {
         return cp.PercentOverride.ToString();
     }
     else if(cp.Percentage!=-1) {
         return cp.Percentage.ToString();
     }
     return "";
 }
Exemplo n.º 26
0
 ///<summary></summary>
 public static void Delete(ClaimProc cp)
 {
     if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
         Meth.GetVoid(MethodBase.GetCurrentMethod(),cp);
         return;
     }
     string command= "DELETE FROM claimproc WHERE ClaimProcNum = "+POut.Long(cp.ClaimProcNum);
     Db.NonQ(command);
 }
Exemplo n.º 27
0
 ///<summary>Gets either the override or the calculated writeoff estimate.  Or zero if neither.</summary>
 public static double GetWriteOffEstimate(ClaimProc cp)
 {
     //No need to check RemotingRole; no call to db.
     if(cp.WriteOffEstOverride!=-1) {
         return cp.WriteOffEstOverride;
     }
     else if(cp.WriteOffEst!=-1) {
         return cp.WriteOffEst;
     }
     return 0;
 }
Exemplo n.º 28
0
 public static string GetCopayDisplay(ClaimProc cp)
 {
     //No need to check RemotingRole; no call to db.
     if(cp.CopayOverride!=-1) {
         return cp.CopayOverride.ToString("f");
     }
     else if(cp.CopayAmt!=-1) {
         return cp.CopayAmt.ToString("f");
     }
     return "";
 }
Exemplo n.º 29
0
		private void butAddEstimate_Click(object sender, System.EventArgs e) {
			FormInsPlanSelect FormIS=new FormInsPlanSelect(PatCur.PatNum);
			FormIS.ShowDialog();
			if(FormIS.DialogResult==DialogResult.Cancel){
				return;
			}
			InsPlan plan=FormIS.SelectedPlan;
			InsSub sub=FormIS.SelectedSub;
			List <Benefit> benList=Benefits.Refresh(PatPlanList,SubList);
			ClaimProc cp=new ClaimProc();
			ClaimProcs.CreateEst(cp,ProcCur,plan,sub);
			if(plan.PlanType=="c") {//capitation
				double allowed=PIn.Double(textProcFee.Text);
				cp.BaseEst=allowed;
				cp.InsEstTotal=allowed;
				cp.CopayAmt=InsPlans.GetCopay(ProcCur.CodeNum,plan.FeeSched,plan.CopayFeeSched,plan.CodeSubstNone,ProcCur.ToothNum);
				if(cp.CopayAmt > allowed) {//if the copay is greater than the allowed fee calculated above
					cp.CopayAmt=allowed;//reduce the copay
				}
				if(cp.CopayAmt==-1) {
					cp.CopayAmt=0;
				}
				cp.WriteOffEst=cp.BaseEst-cp.CopayAmt;
				if(cp.WriteOffEst<0) {
					cp.WriteOffEst=0;
				}
				cp.WriteOff=cp.WriteOffEst;
				ClaimProcs.Update(cp);
			}
			long patPlanNum=PatPlans.GetPatPlanNum(sub.InsSubNum,PatPlanList);
			if(patPlanNum > 0){
				double paidOtherInsTotal=ClaimProcs.GetPaidOtherInsTotal(cp,PatPlanList);
				double writeOffOtherIns=ClaimProcs.GetWriteOffOtherIns(cp,PatPlanList);
				ClaimProcs.ComputeBaseEst(cp,ProcCur.ProcFee,ProcCur.ToothNum,ProcCur.CodeNum,plan,patPlanNum,benList,
					HistList,LoopList,PatPlanList,paidOtherInsTotal,paidOtherInsTotal,PatCur.Age,writeOffOtherIns);	
			}
			FormClaimProc FormC=new FormClaimProc(cp,ProcCur,FamCur,PatCur,PlanList,HistList,ref LoopList,PatPlanList,true,SubList);
			//FormC.NoPermission not needed because butAddEstimate not enabled
			FormC.ShowDialog();
			if(FormC.DialogResult==DialogResult.Cancel){
				ClaimProcs.Delete(cp);
			}
			FillIns();
		}
Exemplo n.º 30
0
 ///<summary>Returns 0 or -1 if no deduct.</summary>
 public static double GetDeductibleDisplay(ClaimProc cp)
 {
     //No need to check RemotingRole; no call to db.
     if(cp.Status==ClaimProcStatus.CapEstimate || cp.Status==ClaimProcStatus.CapComplete) {
         return -1;
     }
     if(cp.Status==ClaimProcStatus.Estimate) {
         if(cp.DedEstOverride != -1) {
             return cp.DedEstOverride;
         }
         //else if(cp.DedEst > 0) {
             return cp.DedEst;//could be -1
         //}
         //else {
         //	return "";
         //}
     }
     return cp.DedApplied;
 }
Exemplo n.º 31
0
Arquivo: ClaimT.cs Projeto: mnisl/OD
		/// <summary>claimType="P" or "S".</summary>
		public static Claim CreateClaim(string claimType,List<PatPlan> PatPlanList,List<InsPlan> InsPlanList,List<ClaimProc> ClaimProcList,List<Procedure> procsForPat,Patient pat,List<Procedure> procsForClaim,List<Benefit> benefitList,List<InsSub> SubList){
			//Claim ClaimCur=CreateClaim("P",PatPlanList,InsPlanList,ClaimProcList,procsForPat);
			long claimFormNum = 0;
			EtransType eFormat = 0;
			InsPlan PlanCur1=new InsPlan();
			InsSub SubCur1=new InsSub();
			InsPlan PlanCur2=new InsPlan();
			InsSub SubCur2=new InsSub();
			Relat relatOther=Relat.Self;
			switch(claimType) {
				case "P":
					SubCur1=InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList,1),SubList);
					PlanCur1=InsPlans.GetPlan(SubCur1.PlanNum,InsPlanList);
					SubCur2=InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList,2),SubList);
					//PlanCur2=InsPlans.GetPlan(SubCur.PlanNum,InsPlanList);//can end up null
					break;
				case "S":
					SubCur1=InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList,2),SubList);
					PlanCur1=InsPlans.GetPlan(SubCur1.PlanNum,InsPlanList);
					SubCur2=InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList,1),SubList);
					//PlanCur2=InsPlans.GetPlan(SubCur.PlanNum,InsPlanList);//can end up null
					break;
			}
			//DataTable table=DataSetMain.Tables["account"];
			Procedure proc;
			//proc=Procedures.GetProcFromList(procsForPat,PIn.Long(table.Rows[gridAccount.SelectedIndices[0]]["ProcNum"].ToString()));
			//long clinicNum=proc.ClinicNum;
			ClaimProc[] claimProcs=new ClaimProc[procsForClaim.Count];//1:1 with procs
			long procNum;
			for(int i=0;i<procsForClaim.Count;i++) {//loop through selected procs
				//and try to find an estimate that can be used
				procNum=procsForClaim[i].ProcNum;
				claimProcs[i]=Procedures.GetClaimProcEstimate(procNum,ClaimProcList,PlanCur1,SubCur1.InsSubNum);
			}
			for(int i=0;i<claimProcs.Length;i++) {//loop through each claimProc
				//and create any missing estimates. This handles claims to 3rd and 4th ins co's.
				if(claimProcs[i]==null) {
					claimProcs[i]=new ClaimProc();
					proc=procsForClaim[i];
					ClaimProcs.CreateEst(claimProcs[i],proc,PlanCur1,SubCur1);
				}
			}
			Claim claim=new Claim();
			Claims.Insert(claim);//to retreive a key for new Claim.ClaimNum
			claim.PatNum=pat.PatNum;
			claim.DateService=claimProcs[claimProcs.Length-1].ProcDate;
			claim.ClinicNum=procsForClaim[0].ClinicNum;
			claim.DateSent=DateTime.Today;
			claim.ClaimStatus="S";
			//datereceived
			switch(claimType) {
				case "P":
					claim.PlanNum=SubCur1.PlanNum;
					claim.InsSubNum=PatPlans.GetInsSubNum(PatPlanList,1);
					claim.PatRelat=PatPlans.GetRelat(PatPlanList,1);
					claim.ClaimType="P";
					claim.PlanNum2=SubCur2.PlanNum;//might be 0 if no sec ins
					claim.InsSubNum2=PatPlans.GetInsSubNum(PatPlanList,2);
					claim.PatRelat2=PatPlans.GetRelat(PatPlanList,2);
					break;
				case "S":
					claim.PlanNum=SubCur1.PlanNum;
					claim.InsSubNum=PatPlans.GetInsSubNum(PatPlanList,2);
					claim.PatRelat=PatPlans.GetRelat(PatPlanList,2);
					claim.ClaimType="S";
					claim.PlanNum2=SubCur2.PlanNum;
					claim.InsSubNum2=PatPlans.GetInsSubNum(PatPlanList,1);
					claim.PatRelat2=PatPlans.GetRelat(PatPlanList,1);
					break;
			}
			claim.ProvTreat=procsForClaim[0].ProvNum;
			claim.IsProsthesis="I";
			claim.ProvBill=Providers.GetBillingProvNum(claim.ProvTreat,claim.ClinicNum);
			claim.EmployRelated=YN.No;
			//attach procedures
			Procedure ProcCur;
			for(int i=0;i<claimProcs.Length;i++) {
				ProcCur=procsForClaim[i];
				claimProcs[i].ClaimNum=claim.ClaimNum;
				claimProcs[i].Status=ClaimProcStatus.NotReceived;//status for claims unsent or sent.
				//writeoff handled in ClaimL.CalculateAndUpdate()
				claimProcs[i].CodeSent=ProcedureCodes.GetProcCode(ProcCur.CodeNum).ProcCode;
				if(claimProcs[i].CodeSent.Length>5 && claimProcs[i].CodeSent.Substring(0,1)=="D") {
					claimProcs[i].CodeSent=claimProcs[i].CodeSent.Substring(0,5);
				}
				claimProcs[i].LineNumber=(byte)(i+1);
				ClaimProcs.Update(claimProcs[i]);
			}
			ClaimProcList=ClaimProcs.Refresh(pat.PatNum);
			ClaimL.CalculateAndUpdate(procsForPat,InsPlanList,claim,PatPlanList,benefitList,pat.Age,SubList);
			return claim;
		}
Exemplo n.º 32
0
 public static string GetEstimateDisplay(ClaimProc cp)
 {
     //No need to check RemotingRole; no call to db.
     if(cp.Status==ClaimProcStatus.CapEstimate || cp.Status==ClaimProcStatus.CapComplete) {
         return "";
     }
     if(cp.Status==ClaimProcStatus.Estimate) {
         if(cp.InsEstTotalOverride!=-1) {
             return cp.InsEstTotalOverride.ToString("f");
         }
         else{//shows even if 0.
             return cp.InsEstTotal.ToString("f");
         }
     }
     return cp.InsPayEst.ToString("f");
 }
Exemplo n.º 33
0
 ///<summary>procCur can be null if not editing from within an actual procedure.  If the save is to happen within this window, then set saveToDb true.  If the object is to be altered here, but saved in a different window, then saveToDb=false.</summary>
 public FormClaimProc(ClaimProc claimProcCur,Procedure procCur,Family famCur,Patient patCur,List<InsPlan> planList,List<ClaimProcHist> histList,ref List<ClaimProcHist> loopList,List<PatPlan> patPlanList,bool saveToDb,List<InsSub> subList)
 {
     ClaimProcCur=claimProcCur;//always work directly with the original object.  Revert if we change our mind.
     ClaimProcOld=ClaimProcCur.Copy();
     proc=procCur;
     FamCur=famCur;
     PatCur=patCur;
     PlanList=planList;
     SubList=subList;
     HistList=histList;
     LoopList=loopList;
     PatPlanList=patPlanList;
     SaveToDb=saveToDb;
     InitializeComponent();// Required for Windows Form Designer support
     //can't use Lan.F because of complexity of label use
     Lan.C(this, new System.Windows.Forms.Control[]
         {
             this,
             this.label1,
             this.label9,
             this.label30,
             this.labelProcDate,
             this.label28,
             this.label29,
             this.groupClaim,
             this.radioEstimate,
             this.radioClaim,
             this.labelCodeSent,
             this.labelFeeBilled,
             this.labelRemarks,
             this.labelNotInClaim,
             this.checkNoBillIns,
             this.labelFee,
             this.labelCopayAmt,
             this.label4,
             this.groupClaimInfo,
             this.labelDedApplied,
             this.labelPaidOtherIns,
             this.labelInsPayEst,
             this.labelInsPayAmt,
             this.labelWriteOff,
             this.labelDateEntry
             //this.butRecalc
     });
     Lan.C("All", new System.Windows.Forms.Control[] {
         butOK,
         butCancel,
         butDelete,
     });
 }
Exemplo n.º 34
0
 /////<summary>Only useful if secondary ins or greater.  For one procedure, it gets the sum of WriteOffEstimates/Override for other insurances with lower ordinals.  Either estimates or actual writeoffs.  Will return 0 if ordinal of this claimproc is 1.</summary>
 //public static double GetDeductibleOtherIns(ClaimProc cp,List<PatPlan> patPlanList) {
 //  if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
 //    return Meth.GetObject<double>(MethodBase.GetCurrentMethod(),cp,patPlanList);
 //  }
 //  if(cp.ProcNum==0) {
 //    return 0;
 //  }
 //  int thisOrdinal=PatPlans.GetOrdinal(cp.InsSubNum,patPlanList);
 //  if(thisOrdinal==1) {
 //    return 0;
 //  }
 //  string command="SELECT InsSubNum,DedEst,DedEstOverride,DedApplied,Status FROM claimproc WHERE ProcNum="+POut.Long(cp.ProcNum);
 //  DataTable table=Db.GetTable(command);
 //  double retVal=0;
 //  long subNum;
 //  int ordinal;
 //  double dedEst;
 //  double dedEstOverride;
 //  double dedApplied;
 //  ClaimProcStatus status;
 //  for(int i=0;i<table.Rows.Count;i++) {
 //    subNum=PIn.Long(table.Rows[i]["InsSubNum"].ToString());
 //    ordinal=PatPlans.GetOrdinal(subNum,patPlanList);
 //    if(ordinal >= thisOrdinal) {
 //      continue;
 //    }
 //    dedEst=PIn.Double(table.Rows[i]["DedEst"].ToString());
 //    dedEstOverride=PIn.Double(table.Rows[i]["DedEstOverride"].ToString());
 //    dedApplied=PIn.Double(table.Rows[i]["DedApplied"].ToString());
 //    status=(ClaimProcStatus)PIn.Int(table.Rows[i]["Status"].ToString());
 //    if(status==ClaimProcStatus.Received || status==ClaimProcStatus.Supplemental) {
 //      retVal+=dedApplied;
 //    }
 //    if(status==ClaimProcStatus.Estimate || status==ClaimProcStatus.NotReceived) {
 //      if(dedEstOverride != -1) {
 //        retVal+=dedEst;
 //      }
 //      else if(dedEst !=-1){
 //        retVal+=dedEst;
 //      }
 //    }
 //  }
 //  return retVal;
 //}
 ///<summary>Simply gets insEstTotal or its override if applicable.</summary>
 public static double GetInsEstTotal(ClaimProc cp)
 {
     //No need to check RemotingRole; no call to db.
     if(cp.InsEstTotalOverride!=-1) {
         return cp.InsEstTotalOverride;
     }
     return cp.InsEstTotal;
 }
Exemplo n.º 35
0
 ///<summary>Used when creating a claim to create any missing claimProcs. Also used in FormProcEdit if click button to add Estimate.  Inserts it into db. It will still be altered after this to fill in the fields that actually attach it to the claim.</summary>
 public static void CreateEst(ClaimProc cp, Procedure proc, InsPlan plan,InsSub sub)
 {
     //No need to check RemotingRole; no call to db.
     cp.ProcNum=proc.ProcNum;
     //claimnum
     cp.PatNum=proc.PatNum;
     cp.ProvNum=proc.ProvNum;
     if(plan.PlanType=="c") {//capitation
         if(proc.ProcStatus==ProcStat.C) {//complete
             cp.Status=ClaimProcStatus.CapComplete;//in this case, a copy will be made later.
         }
         else {//usually TP status
             cp.Status=ClaimProcStatus.CapEstimate;
         }
     }
     else {
         cp.Status=ClaimProcStatus.Estimate;
     }
     cp.PlanNum=plan.PlanNum;
     cp.InsSubNum=sub.InsSubNum;
     cp.DateCP=proc.ProcDate;
     //Writeoff=0
     cp.AllowedOverride=-1;
     cp.Percentage=-1;
     cp.PercentOverride=-1;
     cp.CopayAmt=-1;
     cp.NoBillIns=false;
     cp.PaidOtherIns=-1;
     cp.BaseEst=0;
     cp.DedEst=-1;
     cp.DedEstOverride=-1;
     cp.InsEstTotal=0;
     cp.InsEstTotalOverride=-1;
     cp.CopayOverride=-1;
     cp.PaidOtherInsOverride=-1;
     cp.ProcDate=proc.ProcDate;
     cp.WriteOffEst=-1;
     cp.WriteOffEstOverride=-1;
     cp.ClinicNum=proc.ClinicNum;
     Insert(cp);
 }
Exemplo n.º 36
0
		private void butPayTotal_Click(object sender, System.EventArgs e) {
			if(!Security.IsAuthorized(Permissions.InsPayCreate)){//date not checked here, but it will be checked when actually creating the check
				return;
			}
			//preauths are only allowed "payment" entry by procedure since a total would be meaningless
			if(ClaimCur.ClaimType=="PreAuth"){
				MessageBox.Show(Lan.g(this,"PreAuthorizations can only be entered by procedure."));
				return;
			}
			if(ClaimCur.ClaimType=="Cap"){
				if(MessageBox.Show(Lan.g(this,"If you enter by total, the insurance payment will affect the patient balance.  It is recommended to enter by procedure instead.  Continue anyway?"),"",MessageBoxButtons.OKCancel)!=DialogResult.OK)
				return;
			}
			Double dedEst=0;
			Double payEst=0;
			for(int i=0;i<ClaimProcsForClaim.Count;i++){
				if(ClaimProcsForClaim[i].Status!=ClaimProcStatus.NotReceived){
					continue;
				}
				if(ClaimProcsForClaim[i].ProcNum==0){
					continue;//also ignore non-procedures.
				}
				//ClaimProcs.Cur=ClaimProcs.ForClaim[i];
				dedEst+=ClaimProcsForClaim[i].DedApplied;
				payEst+=ClaimProcsForClaim[i].InsPayEst;
			}
			ClaimProc ClaimProcCur=new ClaimProc();
			//ClaimProcs.Cur.ProcNum 
			ClaimProcCur.ClaimNum=ClaimCur.ClaimNum;
			ClaimProcCur.PatNum=ClaimCur.PatNum;
			ClaimProcCur.ProvNum=ClaimCur.ProvTreat;
			//ClaimProcs.Cur.FeeBilled
			//ClaimProcs.Cur.InsPayEst
			ClaimProcCur.DedApplied=dedEst;
			ClaimProcCur.Status=ClaimProcStatus.Received;
			ClaimProcCur.InsPayAmt=payEst;
			//remarks
			//ClaimProcs.Cur.ClaimPaymentNum
			ClaimProcCur.PlanNum=ClaimCur.PlanNum;
			ClaimProcCur.InsSubNum=ClaimCur.InsSubNum;
			ClaimProcCur.DateCP=DateTimeOD.Today;
			ClaimProcCur.ProcDate=ClaimCur.DateService;
			ClaimProcCur.DateEntry=DateTime.Now;//will get set anyway
			ClaimProcCur.ClinicNum=ClaimCur.ClinicNum;
			ClaimProcs.Insert(ClaimProcCur);
			List<ClaimProcHist> loopList=null;
			FormClaimProc FormCP=new FormClaimProc(ClaimProcCur,null,FamCur,PatCur,PlanList,null,ref loopList,PatPlanList,true,SubList);
			FormCP.IsInClaim=true;
			FormCP.ShowDialog();
			if(FormCP.DialogResult!=DialogResult.OK){
				ClaimProcs.Delete(ClaimProcCur);
			}
			else{
				for(int i=0;i<ClaimProcsForClaim.Count;i++){
					if(ClaimProcsForClaim[i].Status!=ClaimProcStatus.NotReceived){
						continue;
					}
					//ClaimProcs.Cur=ClaimProcs.ForClaim[i];
					ClaimProcsForClaim[i].Status=ClaimProcStatus.Received;
					if(ClaimProcsForClaim[i].DedApplied>0){
						ClaimProcsForClaim[i].InsPayEst+=ClaimProcsForClaim[i].DedApplied;
						ClaimProcsForClaim[i].DedApplied=0;//because ded will show as part of payment now.
					}
					ClaimProcsForClaim[i].DateEntry=DateTime.Now;//the date is was switched to rec'd
					ClaimProcs.Update(ClaimProcsForClaim[i]);
				}
			}
			comboClaimStatus.SelectedIndex=5;//Received
			if(textDateRec.Text==""){
				textDateRec.Text=DateTime.Today.ToShortDateString();
			}
			ClaimProcList=ClaimProcs.Refresh(PatCur.PatNum);
			FillGrids();
		}