context: using CodeBase;
  using System;
  using System.Data;
  using System.Diagnostics;
  using System.Collections;
  using System.Collections.Generic;
  using System.Reflection;
  
  namespace OpenDentBusiness {
  	///<summary></summary>
  	public class Benefits {
  		///<summary>Gets a list of all benefits for a given list of patplans for one patient.</summary>
  		public static List <Benefit> Refresh(List<PatPlan> listForPat,List<InsSub> subList) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				return Meth.GetObject<List<Benefit>>(MethodBase.GetCurrentMethod(),listForPat,subList);
  			} 
  			if(listForPat.Count==0) {
  				return new List <Benefit> ();
  			}
  			InsSub sub;
  			string s="";
  			for(int i=0;i<listForPat.Count;i++) {
  				if(i>0) {
  					s+=" OR";
  				}
  				sub=InsSubs.GetSub(listForPat[i].InsSubNum,subList);
  				s+=" PlanNum="+POut.Long(sub.PlanNum);
  				s+=" OR";
  				s+=" PatPlanNum="+POut.Long(listForPat[i].PatPlanNum);
  			}
  			string command="SELECT * FROM benefit"
  				+" WHERE"+s;
  			List<Benefit> list=Crud.BenefitCrud.SelectMany(command);
  			list.Sort(SortBenefits);
  			return list;
  		}
  
  		public static int SortBenefits(Benefit b1,Benefit b2){
  			return b1.ToString().CompareTo(b2.ToString());
  		}
  
  		///<summary>Used in the PlanEdit and FormClaimProc to get a list of benefits for specified plan and patPlan.  patPlanNum can be 0.</summary>
  		public static List<Benefit> RefreshForPlan(long planNum,long patPlanNum) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				return Meth.GetObject<List<Benefit>>(MethodBase.GetCurrentMethod(),planNum,patPlanNum);
  			}
  			string command="SELECT *"//,IFNULL(covcat.CovCatNum,0) AS covorder "
  				+" FROM benefit"
  				//+" LEFT JOIN covcat ON covcat.CovCatNum=benefit.CovCatNum"
  				+" WHERE PlanNum = "+POut.Long(planNum);
  			if(patPlanNum!=0) {
  				command+=" OR PatPlanNum = "+POut.Long(patPlanNum);
  			}
  			List<Benefit> list=Crud.BenefitCrud.SelectMany(command);
  			list.Sort(SortBenefits);
  			return list;
  		}
  
  		/*
  		///<summary>Used in the Plan edit window to get a typical list of benefits for all identical plans.  It used to exclude the supplied plan from the benefits, but no longer does that.  This behavior needs to be watched closely for possible bugs.</summary>
  		public static List<Benefit> RefreshForAll(InsPlan like) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				return Meth.GetObject<List<Benefit>>(MethodBase.GetCurrentMethod(),like);
  			}
  			if(like.CarrierNum==0){
  				return new List<Benefit>();
  			}
  			//We might try creating a temporary table out of the matched insurance plans, then join with
  			//the benefits table so that the query could be sped up.
  			//Get benefits for all identical plans
  			string command="SELECT b.BenefitNum,b.PlanNum,b.PatPlanNum,b.CovCatNum,b.BenefitType,"
  				+"b.Percent,b.MonetaryAmt,b.TimePeriod,b.QuantityQualifier,b.Quantity,b.CodeNum,b.CoverageLevel "
  				+"FROM insplan i,benefit b "
  				//+"WHERE PlanNum != "   +POut.PInt(like.PlanNum)+" "
  				+"WHERE i.PlanNum=b.PlanNum "
  				+"AND i.EmployerNum = '"+POut.Long(like.EmployerNum)+"' "
  				+"AND i.GroupName = '"+POut.String(like.GroupName)+"' "
  				+"AND i.GroupNum = '"+POut.String(like.GroupNum)+"' "
  				+"AND i.DivisionNo = '"+POut.String(like.DivisionNo)+"'"
  				+"AND i.CarrierNum = '"+POut.Long(like.CarrierNum)+"' "
  				+"AND i.IsMedical = '"+POut.Bool(like.IsMedical)+"' ";
  			Benefit[] benList=Crud.BenefitCrud.SelectMany(command).ToArray();
  			////Get planNums for all identical plans
  			//string command="SELECT PlanNum FROM insplan "
  			//  //+"WHERE PlanNum != "   +POut.PInt(like.PlanNum)+" "
  			//  +"WHERE EmployerNum = '" +POut.PLong(like.EmployerNum)+"' "
  			//  +"AND GroupName = '"   +POut.PString(like.GroupName)+"' "
  			//  +"AND GroupNum = '"    +POut.PString(like.GroupNum)+"' "
  			//  +"AND DivisionNo = '"  +POut.PString(like.DivisionNo)+"'"
  			//  +"AND CarrierNum = '"  +POut.PLong(like.CarrierNum)+"' "
  			//  +"AND IsMedical = '"   +POut.PBool(like.IsMedical)+"' ";
  			//DataTable table=Db.GetTable(command);
  			//string planNums="";
  			//for(int i=0;i<table.Rows.Count;i++) {
  			//  if(i>0) {
  			//    planNums+=" OR";
  			//  }
  			//  planNums+=" PlanNum="+table.Rows[i][0].ToString();
  			//}
  			//Benefit[] benList=new Benefit[0];
  			//if(table.Rows.Count>0){
  			//  //Get all benefits for all those plans
  			//  command="SELECT * FROM benefit WHERE"+planNums;
  			//  table=Db.GetTable(command);
  			//  benList=new Benefit[table.Rows.Count];
  			//  for(int i=0;i<table.Rows.Count;i++) {
  			//    benList[i]=new Benefit();
  			//    benList[i].BenefitNum       = PIn.PLong(table.Rows[i][0].ToString());
  			//    benList[i].PlanNum          = PIn.PLong(table.Rows[i][1].ToString());
  			//    benList[i].PatPlanNum       = PIn.PLong(table.Rows[i][2].ToString());
  			//    benList[i].CovCatNum        = PIn.PLong(table.Rows[i][3].ToString());
  			//    benList[i].BenefitType      = (InsBenefitType)PIn.PLong(table.Rows[i][4].ToString());
  			//    benList[i].Percent          = PIn.PInt(table.Rows[i][5].ToString());
  			//    benList[i].MonetaryAmt      = PIn.PDouble(table.Rows[i][6].ToString());
  			//    benList[i].TimePeriod       = (BenefitTimePeriod)PIn.PLong(table.Rows[i][7].ToString());
  			//    benList[i].QuantityQualifier= (BenefitQuantity)PIn.PLong(table.Rows[i][8].ToString());
  			//    benList[i].Quantity         = PIn.PInt(table.Rows[i][9].ToString());
  			//    benList[i].CodeNum          = PIn.PLong(table.Rows[i][10].ToString());
  			//    benList[i].CoverageLevel    = (BenefitCoverageLevel)PIn.PLong(table.Rows[i][11].ToString());
  			//  }
  			//}
  			//We could probably turn this last part into a group by within the query above in order to make this portion faster.
  			List<Benefit> retVal=new List<Benefit>();
  			//Loop through all benefits
  			bool matchFound;
  			for(int i=0;i<benList.Length;i++) {
  				//For each benefit, loop through retVal and compare.
  				matchFound=false;
  				for(int j=0;j<retVal.Count;j++) {
  					if(benList[i].CompareTo(retVal[j])==0) {//if the type is equal
  						matchFound=true;
  						break;
  					}
  				}
  				if(matchFound) {
  					continue;
  				}
  				//If no match found, then add it to the return list
  				retVal.Add(benList[i]);
  			}
  			for(int i=0;i<retVal.Count;i++) {
  				retVal[i].PlanNum=like.PlanNum;//change all the planNums to match the current plan
  				//all set to 0 if the plan IsForIdentical.
  			}
  			return retVal;
  		}*/
  	
  
  		///<summary></summary>
  		public static void Update(Benefit ben) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				Meth.GetVoid(MethodBase.GetCurrentMethod(),ben);
  				return;
  			}
  			Crud.BenefitCrud.Update(ben);
  		}
  
  		///<summary></summary>
  		public static long Insert(Benefit ben) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				ben.BenefitNum=Meth.GetLong(MethodBase.GetCurrentMethod(),ben);
  				return ben.BenefitNum;
  			}
  			return Crud.BenefitCrud.Insert(ben);
  		}
  
  		///<summary></summary>
  		public static void Delete(Benefit ben) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				Meth.GetVoid(MethodBase.GetCurrentMethod(),ben);
  				return;
  			}
  			string command="DELETE FROM benefit WHERE BenefitNum ="+POut.Long(ben.BenefitNum);
  			Db.NonQ(command);
  		}
  
  		///<summary>Only for display purposes rather than any calculations.  Gets an annual max from the supplied list of benefits.  Ignores benefits that do not match either the planNum or the patPlanNum.  Because it starts at the top of the benefit list, it will get the most general limitation first.  Returns -1 if none found.  Usually, set isFam to false unless we are specifically interested in that value.</summary>
  		public static double GetAnnualMaxDisplay(List<Benefit> benList,long planNum,long patPlanNum,bool isFam) {
  			//No need to check RemotingRole; no call to db.
  			List<Benefit> matchingBens=new List<Benefit>();
  			for(int i=0;i<benList.Count;i++) {
  				if(benList[i].PlanNum==0 && benList[i].PatPlanNum!=patPlanNum) {
  					continue;
  				}
  				if(benList[i].PatPlanNum==0 && benList[i].PlanNum!=planNum) {
  					continue;
  				}
  				if(benList[i].BenefitType!=InsBenefitType.Limitations) {
  					continue;
  				}
  				if(benList[i].QuantityQualifier!=BenefitQuantity.None) {
  					continue;
  				}
  				if(benList[i].TimePeriod!=BenefitTimePeriod.CalendarYear && benList[i].TimePeriod!=BenefitTimePeriod.ServiceYear) {
  					continue;
  				}
  				if(isFam){
  					if(benList[i].CoverageLevel!=BenefitCoverageLevel.Family){//individ or none
  						continue;
  					}
  				}
  				else{
  					if(benList[i].CoverageLevel==BenefitCoverageLevel.Family){
  						continue;
  					}
  				}
  				//coverage level?
  				if(benList[i].CodeNum != 0) {
  					continue;
  				}
  				if(benList[i].CovCatNum != 0) {
  					EbenefitCategory eben=CovCats.GetEbenCat(benList[i].CovCatNum);
  					if(eben != EbenefitCategory.General && eben != EbenefitCategory.None) {
  						continue;
  					}
  				}
  				matchingBens.Add(benList[i]);
  			}
  			if(matchingBens.Count==0) {
  				return -1;
  			}
  			if(matchingBens.Count==1) {
  				return matchingBens[0].MonetaryAmt;
  			}
  			double minBen;
  			minBen=matchingBens[0].MonetaryAmt;
  			for(int i=1;i<matchingBens.Count;i++) {//Start counting at 1 to compare to 0.
  				if(minBen>matchingBens[i].MonetaryAmt){
  					minBen=matchingBens[i].MonetaryAmt;
  				}
  			}
  			return minBen;
  		}
  
  		///<summary>Only for display purposes rather than any calculations.  Gets a general deductible from the supplied list of benefits.  Ignores benefits that do not match either the planNum or the patPlanNum.</summary>
  		public static double GetDeductGeneralDisplay(List<Benefit> benList,long planNum,long patPlanNum,BenefitCoverageLevel level) {
  			//No need to check RemotingRole; no call to db.
  			for(int i=0;i<benList.Count;i++) {
  
gt: 				if(benList[i].PlanNum==0 && benList[i].PatPlanNum!=patPlanNum) {