context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Data;
  using System.Reflection;
  
  namespace OpenDentBusiness{
  	///<summary></summary>
  	public class PatPlans {
  		///<summary>Gets a list of all patplans for a given patient</summary>
  		public static List<PatPlan> Refresh(long patNum) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				return Meth.GetObject<List<PatPlan>>(MethodBase.GetCurrentMethod(),patNum);
  			} 
  			string command="SELECT * from patplan"
  				+" WHERE PatNum = "+patNum.ToString()
  				+" ORDER BY Ordinal";
  			return Crud.PatPlanCrud.SelectMany(command);
  		}
  
  		///<summary></summary>
  		public static void Update(PatPlan patPlan) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				Meth.GetVoid(MethodBase.GetCurrentMethod(),patPlan);
  				return;
  			}
  			//ordinal was already set using SetOrdinal, but it's harmless to set it again.
  			Crud.PatPlanCrud.Update(patPlan);
  		}
  
  		///<summary></summary>
  		public static long Insert(PatPlan patPlan) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				patPlan.PatPlanNum=Meth.GetLong(MethodBase.GetCurrentMethod(),patPlan);
  				return patPlan.PatPlanNum;
  			}
  			//Cameron_ Possibly create outbound ADT message to update insurance info
  			long patPlanNum=Crud.PatPlanCrud.Insert(patPlan);
  			//Insert an InsVerify for the patplan to ensure that the patplan can be verified.
  			InsVerifies.InsertForPatPlanNum(patPlanNum);
  			return patPlanNum;
  		}
  
  		/*
  		///<summary>Supply a PatPlan list.  This function loops through the list and returns the plan num of the specified ordinal.  If ordinal not valid, then it returns 0.  The main purpose of this function is so we don't have to check the length of the list.</summary>
  		public static long GetPlanNum(List<PatPlan> list,int ordinal) {
  			//No need to check RemotingRole; no call to db.
  			for(int i=0;i<list.Count;i++){
  				if(list[i].Ordinal==ordinal){
  					return list[i].PlanNum;
  				}
  			}
  			return 0;
  		}*/
  
  		///<summary>Supply a PatPlan list.  This function loops through the list and returns the insSubNum of the specified ordinal.  If ordinal not valid, then it returns 0.  The main purpose of this function is so we don't have to check the length of the list.</summary>
  		public static long GetInsSubNum(List<PatPlan> list,int ordinal) {
  			//No need to check RemotingRole; no call to db.
  			for(int i=0;i<list.Count;i++) {
  				if(list[i].Ordinal==ordinal) {
  					return list[i].InsSubNum;
  				}
  			}
  			return 0;
  		}
  
          public static PatPlan GetByPatPlanNum(long patPlanNum) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				return Meth.GetObject<PatPlan>(MethodBase.GetCurrentMethod(),patPlanNum);
  			}
  			return Crud.PatPlanCrud.SelectOne(patPlanNum);
          }
  
          ///<summary>Supply a PatPlan list.  This function loops through the list and returns the relationship of the specified ordinal.  If ordinal not valid, then it returns self (0).</summary>
          public static Relat GetRelat(List <PatPlan> list,int ordinal) {
  			//No need to check RemotingRole; no call to db.
  			for(int i=0;i<list.Count;i++){
  				if(list[i].Ordinal==ordinal){
  					return list[i].Relationship;
  				}
  			}
  			return Relat.Self;
  		}
  
  		public static string GetPatID(long subNum,List<PatPlan> patPlans) {
  			//No need to check RemotingRole; no call to db.
  			for(int p=0;p<patPlans.Count;p++) {
  				if(patPlans[p].InsSubNum==subNum) {
  					return patPlans[p].PatID;
  				}
  			}
  			return "";
  		}
  
  		///<summary>Will return 1 for primary insurance, etc.  Will return 0 if planNum not found in the list.</summary>
  		public static int GetOrdinal(long subNum,List<PatPlan> patPlans) {
  			//No need to check RemotingRole; no call to db.
  			for(int p=0;p<patPlans.Count;p++) {
  				if(patPlans[p].InsSubNum==subNum) {
  					return patPlans[p].Ordinal;
  				}
  			}
  			return 0;
  		}
  
  		///<summary>Returns the ordinal (1-based) for the patplan matching the given PriSecMed. Returns 0 if no match.</summary>
  		public static int GetOrdinal(PriSecMed priSecMed,List<PatPlan> PatPlanList,List<InsPlan> planList,List<InsSub> subList) {
  			//No need to check RemotingRole; no call to db.
  			int dentalOrdinal=0;
  			for(int i=0;i<PatPlanList.Count;i++) {
  				InsSub sub=InsSubs.GetSub(PatPlanList[i].InsSubNum,subList);
  				InsPlan plan=InsPlans.GetPlan(sub.PlanNum,planList);
  				if(plan.IsMedical) {
  					if(priSecMed==PriSecMed.Medical) {
  						return PatPlanList[i].Ordinal;
  					}
  				}
  				else { //dental
  					dentalOrdinal++;
  					if(dentalOrdinal==1) {
  						if(priSecMed==PriSecMed.Primary) {
  							return PatPlanList[i].Ordinal;
  						}
  					}
  					else if(dentalOrdinal==2) {
  						if(priSecMed==PriSecMed.Secondary) {
  							return PatPlanList[i].Ordinal;
  						}
  					}
  				}
  			}
  			return 0;
  		}
  
  		///<summary>Will return null if subNum not found in the list.</summary>
  		public static PatPlan GetFromList(List<PatPlan> patPlans,long subNum) {
  			//No need to check RemotingRole; no call to db.
  			for(int p=0;p<patPlans.Count;p++) {
  				if(patPlans[p].InsSubNum==subNum) {
  					return patPlans[p];
  				}
  			}
  			return null;
  		}
  
  		///<summary>Sets the ordinal of the specified patPlan.  Rearranges the other patplans for the patient to keep the ordinal sequence contiguous.  Estimates must be recomputed after this.  FormInsPlan currently updates estimates every time it closes.  Only used in one place.  Returns the new ordinal.</summary>
  		public static int SetOrdinal(long patPlanNum,int newOrdinal) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				return Meth.GetInt(MethodBase.GetCurrentMethod(),patPlanNum,newOrdinal);
  			}
  			string command="SELECT PatNum FROM patplan WHERE PatPlanNum="+POut.Long(patPlanNum);
  			DataTable table=Db.GetTable(command);
  			if(table.Rows.Count==0){
  				return 1;
  			}
  			long patNum=PIn.Long(table.Rows[0][0].ToString());
  			List<PatPlan> patPlans=Refresh(patNum);
  			//int oldOrdinal=GetFromList(patPlans,patPlanNum).Ordinal;
  			if(newOrdinal>patPlans.Count){
  				newOrdinal=patPlans.Count;
  			}
  			if(newOrdinal<1){
  				newOrdinal=1;
  			}
  			int curOrdinal=1;
  			for(int i=0;i<patPlans.Count;i++){//Loop through each patPlan.
  				if(patPlans[i].PatPlanNum==patPlanNum){
  					continue;//the one we are setting will be handled later
  				}
  				if(curOrdinal==newOrdinal){
  					curOrdinal++;//skip the newOrdinal when setting the sequence for the others.
  				}
  				command="UPDATE patplan SET Ordinal="+POut.Long(curOrdinal)
  					+" WHERE PatPlanNum="+POut.Long(patPlans[i].PatPlanNum);
  				Db.NonQ(command);
  				curOrdinal++;
  			}
  			command="UPDATE patplan SET Ordinal="+POut.Long(newOrdinal)
  				+" WHERE PatPlanNum="+POut.Long(patPlanNum);
  			Db.NonQ(command);
  //Cameron_ Possibly create outbound ADT message to update insurance info
  			return newOrdinal;
  		}
  
  		///<summary>Loops through the supplied list to find the one patplan needed.</summary>
  		public static PatPlan GetFromList(PatPlan[] patPlans,long patPlanNum) {
  			//No need to check RemotingRole; no call to db.
  			for(int i=0;i<patPlans.Length;i++){
  				if(patPlans[i].PatPlanNum==patPlanNum){
  					return patPlans[i].Copy();
  				}
  			}
  			return null;
  		}
  
  		///<summary>Loops through the supplied list to find the one patplanNum needed based on the planNum.  Returns 0 if patient is not currently covered by the planNum supplied.</summary>
  		public static long GetPatPlanNum(long subNum,List<PatPlan> patPlanList) {
  			//No need to check RemotingRole; no call to db.
  			for(int i=0;i<patPlanList.Count;i++) {
  				if(patPlanList[i].InsSubNum==subNum) {
  					return patPlanList[i].PatPlanNum;
  				}
  			}
  			return 0;
  		}
  
  		/*Deprecated
  		///<summary>Gets one patPlanNum directly from database.  Only used once in FormClaimProc.</summary>
  		public static long GetPatPlanNum(long patNum,long planNum) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				return Meth.GetLong(MethodBase.GetCurrentMethod(),patNum,planNum);
  			}
  			string command="SELECT PatPlanNum FROM patplan WHERE PatNum="+POut.Long(patNum)+" AND PlanNum="+POut.Long(planNum);
  			return PIn.Long(Db.GetScalar(command));
  		}*/
  
  		///<summary>Gets directly from database.  Used by Trojan.</summary>
  		public static PatPlan[] GetByPlanNum(long planNum) {
  			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
  				return Meth.GetObject<PatPlan[]>(MethodBase.GetCurrentMethod(),planNum);
  			} 
  			//string command="SELECT * FROM patplan WHERE PlanNum='"+POut.Long(planNum)+"'";
  			//The left join will get extra info about each plan, namely the PlanNum.  No need for a GROUP BY.  The PlanNum is used to filter.
  
gt: 			string command=@"SELECT * FROM patplan 