Exemple #1
0
 ///<summary>Fills the missing data field on the queueItem that was passed in.  This contains all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.</summary>
 public static void GetMissingData(ClaimSendQueueItem queueItem)
 {
     //, out string warnings){
     queueItem.Warnings="";
     queueItem.MissingData="";
     Clearinghouse clearhouse=ClearinghouseL.GetClearinghouse(queueItem.ClearinghouseNum,true);//Suppress error message in case no default medical clearinghouse set.
     //this is usually just the default clearinghouse or the clearinghouse for the PayorID.
     if(clearhouse==null){
         return;
     }
     if(clearhouse.Eformat==ElectronicClaimFormat.x837D_4010){
         X837_4010.Validate(queueItem);//,out warnings);
         //return;
     }
     else if(clearhouse.Eformat==ElectronicClaimFormat.x837D_5010_dental
         || clearhouse.Eformat==ElectronicClaimFormat.x837_5010_med_inst)
     {
         X837_5010.Validate(queueItem);//,out warnings);
         //return;
     }
     else if(clearhouse.Eformat==ElectronicClaimFormat.Renaissance){
         queueItem.MissingData=Renaissance.GetMissingData(queueItem);
         //return;
     }
     else if(clearhouse.Eformat==ElectronicClaimFormat.Canadian) {
         queueItem.MissingData=Canadian.GetMissingData(queueItem);
         //return;
     }
     else if(clearhouse.Eformat==ElectronicClaimFormat.Dutch) {
         Dutch.GetMissingData(queueItem);//,out warnings);
         //return;
     }
     //return "";
 }
Exemple #2
0
        ///<summary>Called from claimsend window and from Claim edit window.  Use 0 to get all waiting claims, or an actual claimnum to get just one claim.</summary>
        public static ClaimSendQueueItem[] GetQueueList(long claimNum, long clinicNum, long customTracking)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <ClaimSendQueueItem[]>(MethodBase.GetCurrentMethod(), claimNum, clinicNum, customTracking));
            }
            string command =
                "SELECT claim.ClaimNum,carrier.NoSendElect"
                + ",CONCAT(CONCAT(CONCAT(concat(patient.LName,', '),patient.FName),' '),patient.MiddleI)"
                + ",claim.ClaimStatus,carrier.CarrierName,patient.PatNum,carrier.ElectID,MedType,claim.DateService,claim.ClinicNum "
                + "FROM claim "
                + "Left join insplan on claim.PlanNum = insplan.PlanNum "
                + "Left join carrier on insplan.CarrierNum = carrier.CarrierNum "
                + "Left join patient on patient.PatNum = claim.PatNum ";

            if (claimNum == 0)
            {
                command += "WHERE (claim.ClaimStatus = 'W' OR claim.ClaimStatus = 'P') ";
            }
            else
            {
                command += "WHERE claim.ClaimNum=" + POut.Long(claimNum) + " ";
            }
            if (clinicNum > 0)
            {
                command += "AND claim.ClinicNum=" + POut.Long(clinicNum) + " ";
            }
            if (customTracking > 0)
            {
                command += "AND claim.CustomTracking=" + POut.Long(customTracking) + " ";
            }
            command += "ORDER BY claim.DateService,patient.LName";
            DataTable table = Db.GetTable(command);

            ClaimSendQueueItem[] listQueue = new ClaimSendQueueItem[table.Rows.Count];
            for (int i = 0; i < table.Rows.Count; i++)
            {
                listQueue[i]             = new ClaimSendQueueItem();
                listQueue[i].ClaimNum    = PIn.Long(table.Rows[i][0].ToString());
                listQueue[i].NoSendElect = PIn.Bool(table.Rows[i][1].ToString());
                listQueue[i].PatName     = PIn.String(table.Rows[i][2].ToString());
                listQueue[i].ClaimStatus = PIn.String(table.Rows[i][3].ToString());
                listQueue[i].Carrier     = PIn.String(table.Rows[i][4].ToString());
                listQueue[i].PatNum      = PIn.Long(table.Rows[i][5].ToString());
                string           payorID = PIn.String(table.Rows[i]["ElectID"].ToString());
                EnumClaimMedType medType = (EnumClaimMedType)PIn.Int(table.Rows[i]["MedType"].ToString());
                listQueue[i].ClearinghouseNum = Clearinghouses.AutomateClearinghouseSelection(payorID, medType);
                listQueue[i].MedType          = medType;
                listQueue[i].DateService      = PIn.Date(table.Rows[i]["DateService"].ToString());
                listQueue[i].ClinicNum        = PIn.Long(table.Rows[i]["ClinicNum"].ToString());
            }
            return(listQueue);
        }
Exemple #3
0
		///<summary>Called once for each claim to be created.  For claims with a lot of procedures, this may actually create multiple claims.  Normally returns empty string unless something went wrong.</summary>
		public static bool CreateClaim(ClaimSendQueueItem queueItem,int batchNum) {
			StringBuilder strb=new StringBuilder();
			string t="\t";
			strb.Append("110\t111\t112\t118\t203/403\tF108/204/404\t205/405\t206\t207\t208\t209\t210\t211\t212\t215\t217\t219\t406\t408\t409\t410\t411\t413\t414\t415\t416\t418\t419\t420\t421\t422\t423\t424\t425\t426\t428\t429\t430\t432\t433\r\n");
			Clearinghouse clearhouse=ClearinghouseL.GetClearinghouse(queueItem.ClearinghouseNum);
			Claim claim=Claims.GetClaim(queueItem.ClaimNum);
			Provider provBill=Providers.GetProv(claim.ProvBill);
			Patient pat=Patients.GetPat(claim.PatNum);
			InsPlan insplan=InsPlans.GetPlan(claim.PlanNum,new List<InsPlan>());
			InsSub insSub=InsSubs.GetSub(claim.InsSubNum,new List<InsSub>());
			Carrier carrier=Carriers.GetCarrier(insplan.CarrierNum);
			List<ClaimProc> claimProcList=ClaimProcs.Refresh(pat.PatNum);
			List<ClaimProc> claimProcsForClaim=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
			List<Procedure> procList=Procedures.Refresh(claim.PatNum);
			Procedure proc;
			ProcedureCode procCode;
			//ProcedureCode procCode;
			for(int i=0;i<claimProcsForClaim.Count;i++) {
				//claimProcsForClaim already excludes any claimprocs with ProcNum=0, so no payments etc.
				proc=Procedures.GetProcFromList(procList,claimProcsForClaim[i].ProcNum);
				//procCode=Pro
				strb.Append(provBill.SSN+t);//110
				strb.Append(provBill.MedicaidID+t);//111
				strb.Append(t);//112
				strb.Append(t);//118
				strb.Append(pat.SSN+t);//203/403
				strb.Append(carrier.CarrierName+t);//carrier name?
				strb.Append(insSub.SubscriberID+t);
				strb.Append(pat.PatNum.ToString()+t);
				strb.Append(pat.Birthdate.ToString("dd-MM-yyyy")+t);
				if(pat.Gender==PatientGender.Female) {
					strb.Append("2"+t);//"V"+t);
				}
				else {
					strb.Append("1"+t);//M"+t);
				}
				strb.Append("1"+t);
				strb.Append(DutchLName(pat.LName)+t);//last name without prefix
				strb.Append(DutchLNamePrefix(pat.LName)+t);//prefix
				strb.Append("2"+t);
				strb.Append(DutchInitials(pat)+t);//215. initials
				strb.Append(pat.Zip+t);
				strb.Append(DutchAddressNumber(pat.Address)+t);//219 house number.  Already validated.
				strb.Append(t);
				strb.Append(proc.ProcDate.ToString("dd-MM-yyyy")+t);//procDate
				procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
				string strProcCode=procCode.ProcCode;
				if(strProcCode.EndsWith("00")) {//ending with 00 indicates it's a lab code.
					strb.Append("02"+t);
				}
				else {
					strb.Append("01"+t);//409. Procedure code (01) or lab costs (02)
				}
				strb.Append(t);
				strb.Append(t);
				strb.Append(strProcCode+t);
				strb.Append(GetUL(proc,procCode)+t);//414. U/L.
				strb.Append(Tooth.ToInternat(proc.ToothNum)+t);
				strb.Append(Tooth.SurfTidyForClaims(proc.Surf,proc.ToothNum)+t);//needs validation
				strb.Append(t);
				if(claim.AccidentRelated=="") {//not accident
					strb.Append("N"+t);
				}
				else {
					strb.Append("J"+t);
				}
				strb.Append(pat.SSN+t);
				strb.Append(t);
				strb.Append(t);
				strb.Append(t);
				strb.Append(proc.ProcFee.ToString("F")+t);
				strb.Append("1"+t);
				strb.Append(proc.ProcFee.ToString("F")+t);
				strb.Append(t);
				strb.Append(t);
				strb.Append(proc.ProcFee.ToString("F")+t);
				strb.Append(t);
				strb.Append(t);
				strb.Append("\r\n");
			}
			string saveFolder=clearhouse.ExportPath;
			if(!Directory.Exists(saveFolder)) {
				MessageBox.Show(saveFolder+" "+Lan.g("Dutch","not found."));
				return false;
			}
			string saveFile=ODFileUtils.CombinePaths(saveFolder,"claims"+claim.ClaimNum.ToString()+".txt");
			File.WriteAllText(saveFile,strb.ToString());
			//MessageBox.Show(strb.ToString());
			return true;
		}
Exemple #4
0
		///<summary>Returns a string describing all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.  There is also an out parameter containing any warnings.  Warnings will not block sending.</summary>
		public static void GetMissingData(ClaimSendQueueItem queueItem){//,out string warning) {
			StringBuilder strb=new StringBuilder();
			string warning="";
			Claim claim=Claims.GetClaim(queueItem.ClaimNum);
			Patient pat=Patients.GetPat(claim.PatNum);
			if(!Regex.IsMatch(pat.Address,@"^[a-zA-Z ]+[0-9]+")) {//format must be streetname, then some numbers, then anything else.
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Patient address format");
			}
			//return strb.ToString();
			queueItem.MissingData=strb.ToString();
			queueItem.Warnings=warning;
		}
Exemple #5
0
		///<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;
		}
Exemple #6
0
		///<summary>Returns a string describing all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.</summary>
		public static string GetMissingData(ClaimSendQueueItem queueItem) {
			string retVal="";
			Clearinghouse clearhouse=ClearinghouseL.GetClearinghouse(queueItem.ClearinghouseNum);
			Claim claim=Claims.GetClaim(queueItem.ClaimNum);
			Clinic clinic=Clinics.GetClinic(claim.ClinicNum);
			Provider billProv=ProviderC.ListLong[Providers.GetIndexLong(claim.ProvBill)];
			Provider treatProv=ProviderC.ListLong[Providers.GetIndexLong(claim.ProvTreat)];
			InsSub insSub=InsSubs.GetSub(claim.InsSubNum,new List<InsSub>());
			InsPlan insPlan=InsPlans.GetPlan(claim.PlanNum,new List <InsPlan> ());
			Carrier carrier=Carriers.GetCarrier(insPlan.CarrierNum);
			if(carrier.CanadianNetworkNum==0) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Primary carrier network not set";
			}
			if(carrier.CDAnetVersion!="02") {
				if(carrier.CDAnetVersion!="04") {
					if(retVal!="")
						retVal+=", ";
					retVal+="Primary carrier CDANet version must be 02 or 04";
				}
				if(carrier.CanadianEncryptionMethod!=1 && carrier.CanadianEncryptionMethod!=2 && carrier.CanadianEncryptionMethod!=3) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Primary carrier encryption method must be 1, 2 or 3";
				}
			}
			InsSub insSub2=null;
			InsPlan insPlan2=null;
			Carrier carrier2=null;
			Patient subscriber2=null;
			if(claim.ClaimType!="S" && claim.PlanNum2>0) {
				insSub2=InsSubs.GetSub(claim.InsSubNum2,new List<InsSub>());
				insPlan2=InsPlans.GetPlan(claim.PlanNum2,new List <InsPlan> ());
				carrier2=Carriers.GetCarrier(insPlan2.CarrierNum);
				if(carrier2.CanadianNetworkNum==0) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Secondary carrier network not set";
				}
				if(carrier2.CDAnetVersion!="02") {
					if(carrier2.CDAnetVersion!="04") {
						if(retVal!="")
							retVal+=", ";
						retVal+="Secondary carrier CDANet version must be 02 or 04";
					}
					if(carrier2.CanadianEncryptionMethod!=1 && carrier2.CanadianEncryptionMethod!=2 && carrier2.CanadianEncryptionMethod!=3) {
						if(retVal!="")
							retVal+=", ";
						retVal+="Secondary carrier encryption method must be 1, 2 or 3";
					}
				}
				subscriber2=Patients.GetPat(insSub2.Subscriber);
			}
			Patient patient=Patients.GetPat(claim.PatNum);
			Patient subscriber=Patients.GetPat(insSub.Subscriber);
			List<ClaimProc> claimProcList=ClaimProcs.Refresh(patient.PatNum);//all claimProcs for a patient.
			List<ClaimProc> claimProcsClaim=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
			List<Procedure> procListAll=Procedures.Refresh(claim.PatNum);
			Procedure proc;
			ProcedureCode procCode;
			List<Procedure> extracted=Procedures.GetCanadianExtractedTeeth(procListAll);
			if(!Regex.IsMatch(carrier.ElectID,@"^[0-9]{6}$")) {
				if(retVal!="")
					retVal+=", ";
				retVal+="CarrierId 6 digits";
			}
			if(treatProv.NationalProvID.Length!=9) {
				if(retVal!="")
					retVal+=", ";
				retVal+="TreatingProv CDA num 9 digits";
			}
			if(treatProv.CanadianOfficeNum.Length!=4) {
				if(retVal!="")
					retVal+=", ";
				retVal+="TreatingProv office num 4 char";
			}
			if(billProv.NationalProvID.Length!=9) {
				if(retVal!="")
					retVal+=", ";
				retVal+="BillingProv CDA num 9 digits";
			}
			if(billProv.CanadianOfficeNum.Length!=4) {
				if(retVal!="")
					retVal+=", ";
				retVal+="BillingProv office num 4 char";
			}
			if(insPlan.GroupNum.Length==0 || insPlan.GroupNum.Length>12 || insPlan.GroupNum.Contains(" ")) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Plan Number";
			}
			if(insSub.SubscriberID=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="SubscriberID";
			}
			if(claim.PatNum != insSub.Subscriber//if patient is not subscriber
				&& claim.PatRelat==Relat.Self) {//and relat is self
				if(retVal!="")
					retVal+=", ";
				retVal+="Claim Relationship";
			}
			if(patient.Gender==PatientGender.Unknown) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Patient gender";
			}
			if(patient.Birthdate.Year<1880 || patient.Birthdate>DateTime.Today) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Patient birthdate";
			}
			if(patient.LName=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="Patient lastname";
			}
			if(patient.FName=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="Patient firstname";
			}
			if(patient.Age>=18 && patient.CanadianEligibilityCode==1){//fulltimeStudent
				if(patient.SchoolName=="") {
					if(retVal!="")
						retVal+=", ";
					retVal+="Patient school name";
				}
			}
			if(subscriber.Birthdate.Year<1880 || subscriber.Birthdate>DateTime.Today) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Subscriber birthdate";
			}
			if(subscriber.LName=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="Subscriber lastname";
			}
			if(subscriber.FName=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="Subscriber firstname";
			}
			if(subscriber.Address=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="Subscriber address";
			}
			if(subscriber.City=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="Subscriber city";
			}
			if(!IsValidST(subscriber.State)) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Subscriber Province";
			}
			if(!IsValidZip(subscriber.Zip)) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Subscriber Postalcode";
			}
			if(claimProcsClaim.Count>7) {//user interface enforces prevention of claim with 0 procs.
				if(retVal!="")
					retVal+=", ";
				retVal+="Over 7 procs";
			}
//incomplete. Also duplicate for max
			//user interface also needs to be improved to prompt and remind about extracted teeth
			/*if(isInitialLowerProsth && MandProsthMaterial!=0 && CountLower(extracted.Count)==0){
				if(retVal!="")
					retVal+=",";
				retVal+="Missing teeth not entered";
			}*/
			if(carrier.ElectID=="000064") { //Checks for Pacific Blue Cross (PBC) for primary as required for certification.
				List<PatPlan> patPlansForPatient=PatPlans.Refresh(claim.PatNum);
				for(int p=0;p<patPlansForPatient.Count;p++) {
					if(patPlansForPatient[p].InsSubNum==claim.InsSubNum) {
						retVal+=GetMissingDataForPatPlanPacificBlueCross(patPlansForPatient[p],insPlan);
						break;
					}
				}
			}
			if(carrier2!=null && carrier2.ElectID=="000064") { //Checks for Pacific Blue Cross (PBC) for secondary as required for certification.
				List<PatPlan> patPlansForPatient=PatPlans.Refresh(claim.PatNum);
				for(int p=0;p<patPlansForPatient.Count;p++) {
					if(patPlansForPatient[p].InsSubNum==claim.InsSubNum2) {
						retVal+=GetMissingDataForPatPlanPacificBlueCross(patPlansForPatient[p],insPlan2);
						break;
					}
				}
			}
			if(claim.ClaimType!="S" && claim.PlanNum2>0){
				if(!Regex.IsMatch(carrier2.ElectID,@"^[0-9]{6}$")) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec CarrierId 6 digits";
				}
				if(insPlan2.GroupNum.Length==0 || insPlan2.GroupNum.Length>12 || insPlan2.GroupNum.Contains(" ")) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Plan Number";
				}
				if(insSub2.SubscriberID=="") {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec SubscriberID";
				}
				if(claim.PatNum != insSub2.Subscriber//if patient is not subscriber
					&& claim.PatRelat2==Relat.Self) {//and relat is self
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Relationship";
				}
				if(subscriber2.Birthdate.Year<1880 || subscriber2.Birthdate>DateTime.Today) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Subscriber birthdate";
				}
				if(subscriber2.LName=="") {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Subscriber lastname";
				}
				if(subscriber2.FName=="") {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Subscriber firstname";
				}
				if(subscriber2.Address=="") {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Subscriber address";
				}
				if(subscriber2.City=="") {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Subscriber city";
				}
				if(!IsValidST(subscriber2.State)) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Subscriber Province";
				}
				if(!IsValidZip(subscriber2.Zip)) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Sec Subscriber Postalcode";
				}
			}
			if(claim.CanadianReferralProviderNum!="" && claim.CanadianReferralReason==0) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Referral reason";
			}
			if(claim.CanadianReferralProviderNum=="" && claim.CanadianReferralReason!=0) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Referral provider";
			}
			//Max Prosth--------------------------------------------------------------------------------------------------
			if(claim.CanadianIsInitialUpper=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="Max prosth";
			}
			if(claim.CanadianDateInitialUpper>DateTime.MinValue) {
				if(claim.CanadianDateInitialUpper.Year<1900 || claim.CanadianDateInitialUpper>=DateTime.Today) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Date initial upper";
				}
			}
			if(claim.CanadianIsInitialUpper=="N" && claim.CanadianDateInitialUpper.Year<1900) {//missing date
				if(retVal!="")
					retVal+=", ";
				retVal+="Date initial upper";
			}
			if(claim.CanadianIsInitialUpper=="N" && claim.CanadianMaxProsthMaterial==0) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Max prosth material";
			}
			if(claim.CanadianIsInitialUpper=="X" && claim.CanadianMaxProsthMaterial!=0) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Max prosth material";
			}
			//Mand prosth--------------------------------------------------------------------------------------------------
			if(claim.CanadianIsInitialLower=="") {
				if(retVal!="")
					retVal+=", ";
				retVal+="Mand prosth";
			}
			if(claim.CanadianDateInitialLower>DateTime.MinValue) {
				if(claim.CanadianDateInitialLower.Year<1900 || claim.CanadianDateInitialLower>=DateTime.Today) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Date initial lower";
				}
			}
			if(claim.CanadianIsInitialLower=="N" && claim.CanadianDateInitialLower.Year<1900) {//missing date
				if(retVal!="")
					retVal+=", ";
				retVal+="Date initial lower";
			}
			if(claim.CanadianIsInitialLower=="N" && claim.CanadianMandProsthMaterial==0) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Mand prosth material";
			}
			if(claim.CanadianIsInitialLower=="X" && claim.CanadianMandProsthMaterial!=0) {
				if(retVal!="")
					retVal+=", ";
				retVal+="Mand prosth material";
			}
			//missing teeth---------------------------------------------------------------------------------------------------
			/*Can't do this because extracted teeth count is allowed to be zero
			if(claim.CanadianIsInitialLower=="Y" && claim.CanadianMandProsthMaterial!=7) {//initial lower, but not crown
				if(extracted.Count==0) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Missing teeth not entered";
				}
			}
			if(claim.CanadianIsInitialUpper=="Y" && claim.CanadianMaxProsthMaterial!=7) {//initial upper, but not crown
				if(extracted.Count==0) {
					if(retVal!="")
						retVal+=", ";
					retVal+="Missing teeth not entered";
				}
			}
			*/			
			if(claim.AccidentDate>DateTime.MinValue){
				if(claim.AccidentDate.Year<1900 || claim.AccidentDate>DateTime.Today){
					if(retVal!="")
						retVal+=",";
					retVal+="Accident date";
				}
			}
			if(!billProv.IsCDAnet) {
				retVal+="Billing provider is not setup as a CDANet provider.";
			}
			if(!treatProv.IsCDAnet) {
				retVal+="Treating provider is not setup as a CDANet provider.";
			}
			for(int i=0;i<claimProcsClaim.Count;i++) {
				//claimProcsClaim already excludes any claimprocs with ProcNum=0, so no payments etc.
				proc=Procedures.GetProcFromList(procListAll,claimProcsClaim[i].ProcNum);
				procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
				//Procedure dates are not included in predetermination requests so we do not need to check the dates for claimtype 'PreAuth'.
				if(claim.ClaimType!="PreAuth") {
					if(claimProcsClaim[i].ProcDate.Year<1970 || claimProcsClaim[i].ProcDate>DateTime.Today) {
						if(retVal!="") {
							retVal+=", ";
						}
						retVal+="proc "+procCode.ProcCode+" procedure date";
					}
				}
				if(procCode.TreatArea==TreatmentArea.Arch && proc.Surf==""){
					if(retVal!="") {
						retVal+=", ";
					}
					retVal+="proc "+procCode.ProcCode+" missing arch";
				}
				if(procCode.TreatArea==TreatmentArea.ToothRange && proc.ToothRange==""){
					if(retVal!="") {
						retVal+=", ";
					}
					retVal+="proc "+procCode.ProcCode+" tooth range";
				}
				if((procCode.TreatArea==TreatmentArea.Tooth || procCode.TreatArea==TreatmentArea.Surf)
					&& !Tooth.IsValidDB(proc.ToothNum)) {
					if(retVal!="") {
						retVal+=", ";
					}
					retVal+="proc "+procCode.ProcCode+" tooth number";
				}
				if(claim.ClaimType!="PreAuth") {
					List<Procedure> labFeesForProc=Procedures.GetCanadianLabFees(proc.ProcNum,procListAll);
					for(int j=0;j<labFeesForProc.Count;j++) {
						if(labFeesForProc[j].ProcStatus!=ProcStat.C) {
							ProcedureCode procCodeLab=ProcedureCodes.GetProcCode(labFeesForProc[j].CodeNum);
							if(retVal!="") {
								retVal+=", ";
							}
							retVal+="proc "+procCode.ProcCode+" lab fee "+procCodeLab.ProcCode+" not complete";
						}
					}
				}
			}
			for(int i=0;i<extracted.Count;i++) {
				if(extracted[i].ProcDate.Date>DateTime.Today) {
					retVal+="extraction date in future";
				}
			}
			return retVal;
		}
Exemple #7
0
		///<summary>Called from claimsend window and from Claim edit window.  Use 0 to get all waiting claims, or an actual claimnum to get just one claim.</summary>
		public static ClaimSendQueueItem[] GetQueueList(long claimNum,long clinicNum,long customTracking) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				return Meth.GetObject<ClaimSendQueueItem[]>(MethodBase.GetCurrentMethod(),claimNum,clinicNum,customTracking);
			}
			string command=
				"SELECT claim.ClaimNum,carrier.NoSendElect"
				+",CONCAT(CONCAT(CONCAT(concat(patient.LName,', '),patient.FName),' '),patient.MiddleI)"
				+",claim.ClaimStatus,carrier.CarrierName,patient.PatNum,carrier.ElectID,MedType,claim.DateService,claim.ClinicNum,claim.CustomTracking "
				+"FROM claim "
				+"Left join insplan on claim.PlanNum = insplan.PlanNum "
				+"Left join carrier on insplan.CarrierNum = carrier.CarrierNum "
				+"Left join patient on patient.PatNum = claim.PatNum ";
			if(claimNum==0){
				command+="WHERE (claim.ClaimStatus = 'W' OR claim.ClaimStatus = 'P') ";
			}
			else{
				command+="WHERE claim.ClaimNum="+POut.Long(claimNum)+" ";
			}
			if(clinicNum>0) {
				command+="AND claim.ClinicNum="+POut.Long(clinicNum)+" ";
			}
			if(customTracking>0) {
				command+="AND claim.CustomTracking="+POut.Long(customTracking)+" ";
			}
			command+="ORDER BY claim.DateService,patient.LName";
			DataTable table=Db.GetTable(command);
			ClaimSendQueueItem[] listQueue=new ClaimSendQueueItem[table.Rows.Count];
			for(int i=0;i<table.Rows.Count;i++){
				listQueue[i]=new ClaimSendQueueItem();
				listQueue[i].ClaimNum        = PIn.Long  (table.Rows[i][0].ToString());
				listQueue[i].NoSendElect     = PIn.Bool  (table.Rows[i][1].ToString());
				listQueue[i].PatName         = PIn.String(table.Rows[i][2].ToString());
				listQueue[i].ClaimStatus     = PIn.String(table.Rows[i][3].ToString());
				listQueue[i].Carrier         = PIn.String(table.Rows[i][4].ToString());
				listQueue[i].PatNum          = PIn.Long  (table.Rows[i][5].ToString());
				string payorID=PIn.String(table.Rows[i]["ElectID"].ToString());
				EnumClaimMedType medType=(EnumClaimMedType)PIn.Int(table.Rows[i]["MedType"].ToString());
				listQueue[i].ClearinghouseNum=Clearinghouses.AutomateClearinghouseSelection(payorID,medType);
				listQueue[i].MedType=medType;
				listQueue[i].DateService     = PIn.Date  (table.Rows[i]["DateService"].ToString());
				listQueue[i].ClinicNum		 = PIn.Long	 (table.Rows[i]["ClinicNum"].ToString());
				listQueue[i].CustomTracking		= PIn.Long (table.Rows[i]["CustomTracking"].ToString());
			}
			return listQueue;
		}
		///<summary>Returns a string describing all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.  There is also an out parameter containing any warnings.  Warnings will not block sending.</summary>
		public static void Validate(ClaimSendQueueItem queueItem){//,out string warning) {
			StringBuilder strb=new StringBuilder();
			string warning="";
			Clearinghouse clearhouse=null;//ClearinghouseL.GetClearinghouse(queueItem.ClearinghouseNum);
			for(int i=0;i<Clearinghouses.Listt.Length;i++) {
				if(Clearinghouses.Listt[i].ClearinghouseNum==queueItem.ClearinghouseNum) {
					clearhouse= Clearinghouses.Listt[i];
				}
			}
			if(clearhouse==null) {
				throw new ApplicationException("Error. Could not locate Clearinghouse.");
			}
			Claim claim=Claims.GetClaim(queueItem.ClaimNum);
			Clinic clinic=Clinics.GetClinic(claim.ClinicNum);
			//if(clearhouse.Eformat==ElectronicClaimFormat.X12){//not needed since this is always true
			X12Validate.ISA(clearhouse,strb);
			if(clearhouse.GS03.Length<2) {
				Comma(strb);
				strb.Append("Clearinghouse GS03");
			}
			List<X12TransactionItem> claimItems=Claims.GetX12TransactionInfo(((ClaimSendQueueItem)queueItem).ClaimNum);//just to get prov. Needs work.
			Provider billProv=ProviderC.ListLong[Providers.GetIndexLong(claimItems[0].ProvBill1)];
			Provider treatProv=ProviderC.ListLong[Providers.GetIndexLong(claim.ProvTreat)];
			Referral referral=Referrals.GetReferral(claim.ReferringProv);
			InsPlan insPlan=InsPlans.GetPlan(claim.PlanNum,null);
			InsSub sub=InsSubs.GetSub(claim.InsSubNum,null);
			List<PatPlan> patPlans=PatPlans.Refresh(claim.PatNum);
			if(claim.MedType==EnumClaimMedType.Medical) {
				if(referral!=null && referral.IsDoctor && referral.NotPerson) {
					Comma(strb);
					strb.Append("Referring Prov must be a person.");
				}
			}
			else if(claim.MedType==EnumClaimMedType.Institutional) {
				if(referral!=null && referral.IsDoctor && referral.NotPerson && claim.ReferringProv!=claim.ProvTreat) {
					Comma(strb);
					strb.Append("Referring Prov must be a person.");
				}
				if(!billProv.IsNotPerson) {
					Comma(strb);
					strb.Append("Billing Prov cannot be a person.");
				}
			}
			else if(claim.MedType==EnumClaimMedType.Dental) {
				if(referral!=null && referral.IsDoctor && referral.NotPerson) {
					Comma(strb);
					strb.Append("Referring Prov must be a person.");
				}
			}
			//billProv
			X12Validate.BillProv(billProv,strb);
			if(IsEmdeonMedical(clearhouse)) {//The X12 standard has a basic character set, but Emdeon Medical only allows a subset of the basic character set, as seen in error messages within their interface.
				if(!billProv.IsNotPerson && !Regex.IsMatch(billProv.FName,"^[A-Za-z ']+$")) {//If not a person, then X12 generation will leave this blank, regardless of what user entered.
					Comma(strb);
					strb.Append("Billing Prov FName may contain letters spaces and apostrophes only");
				}
				if(!Regex.IsMatch(billProv.LName,"^[A-Za-z ']+$")) {
					Comma(strb);
					strb.Append("Billing Prov LName may contain letters spaces and apostrophes only");
				}
				if(!billProv.IsNotPerson && !Regex.IsMatch(billProv.MI,"^[A-Za-z ']*$")) {//If not a person, then X12 generation will leave this blank, regardless of what user entered.
					Comma(strb);
					strb.Append("Billing Prov Middle Name may contain letters spaces and apostrophes only");
				}
			}
			if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
				X12Validate.BillingAddress(strb);
				string zip=PrefC.GetString(PrefName.PracticeBillingZip);
				if(!Regex.IsMatch(zip,"^[0-9]{5}\\-?[0-9]{4}$")) {
					Comma(strb);
					strb.Append("Practice billing zip must contain nine digits");//this is more restrictive than in the check above.
				}
				if(Regex.IsMatch(PrefC.GetString(PrefName.PracticeBillingAddress),".*P\\.?O\\.? .*",RegexOptions.IgnoreCase)) {
					Comma(strb);
					strb.Append("Practice billing address cannot be a P.O. BOX when used for e-claims.");
				}
			}
			else if(clinic==null) {
				X12Validate.PracticeAddress(strb);
				string zip=PrefC.GetString(PrefName.PracticeZip);
				if(!Regex.IsMatch(zip,"^[0-9]{5}\\-?[0-9]{4}$")) {
					Comma(strb);
					strb.Append("Practice zip must contain nine digits");
				}
				if(Regex.IsMatch(PrefC.GetString(PrefName.PracticeAddress),".*P\\.?O\\.? .*",RegexOptions.IgnoreCase)) {
					Comma(strb);
					strb.Append("Practice address cannot be a P.O. BOX when used for e-claims.");
				}
			}
			else {
				X12Validate.Clinic(clinic,strb);
				string zip=clinic.Zip;
				if(!Regex.IsMatch(zip,"^[0-9]{5}\\-?[0-9]{4}$")) {
					Comma(strb);
					strb.Append("Clinic zip must contain nine digits");
				}
				if(Regex.IsMatch(clinic.Address,".*P\\.?O\\.? .*",RegexOptions.IgnoreCase)) {
					Comma(strb);
					strb.Append("Clinic address cannot be a P.O. BOX when used for e-claims.");
				}
			}
			//treatProv
			if(treatProv.LName=="") {
				Comma(strb);
				strb.Append("Treating Prov LName");
			}
			if(treatProv.FName=="" && !treatProv.IsNotPerson) {
				Comma(strb);
				strb.Append("Treating Prov FName");
			}
			if(treatProv.NationalProvID.Length<2) {
				Comma(strb);
				strb.Append("Treating Prov NPI");
			}
			if(treatProv.TaxonomyCodeOverride.Length>0 && treatProv.TaxonomyCodeOverride.Length!=10) {
				Comma(strb);
				strb.Append("Treating Prov Taxonomy Code must be 10 characters");
			}
			//Treating prov SSN/TIN is not sent on paper or eclaims. Do not verify or block.
			if(!Regex.IsMatch(treatProv.NationalProvID,"^(80840)?[0-9]{10}$")) {
				Comma(strb);
				strb.Append("Treating Prov NPI for claim must be a 10 digit number with an optional prefix of 80840");
			}
			//facility provider, used for facility name and facility NPI
			Provider facilityProv=billProv;
			if(claim.MedType==EnumClaimMedType.Dental) {
				if(claim.PlaceService!=PlaceOfService.Office) {
					//Only specific clearinghouses want the facility information.
					if(IsClaimConnect(clearhouse)) {
						if(!facilityProv.IsNotPerson) {//In medical, institutional and dental, the facility provider must be a non-person.
							Comma(strb);
							strb.Append("Billing/Facility Prov cannot be a person when claim Place of Service is not Office");
						}
					}
				}
			}
			//Addresses
			if(PrefC.GetString(PrefName.PracticeTitle)=="") {
				Comma(strb);
				strb.Append("Practice Title");
			}
			if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
				X12Validate.BillingAddress(strb);
			}
			else if(clinic==null) {
				X12Validate.PracticeAddress(strb);
			}
			else {
				X12Validate.Clinic(clinic,strb);
			}
			if(!sub.ReleaseInfo) {
				Comma(strb);
				strb.Append("InsPlan Release of Info");
			}
			Carrier carrier=Carriers.GetCarrier(insPlan.CarrierNum);
			PatPlan patPlan=PatPlans.GetFromList(patPlans,claim.InsSubNum);//can be null
			if(patPlan!=null && patPlan.PatID!="") {
				Comma(strb);
				strb.Append("Create a new insurance plan instead of using the optional patient ID");
			}
			if(IsDentiCal(clearhouse)) {
				if(GetFilingCode(insPlan)!="MC") {
					Comma(strb);
					strb.Append("InsPlan Filing Code must be Medicaid for Denti-Cal");
				}
				if(sub.Subscriber!=claim.PatNum) {
					Comma(strb);
					strb.Append("Subscriber must be the same as the patient for Denti-Cal");//for everyone, we also check patplan.PatID.
				}
				if(claim.PatRelat!=Relat.Self) {
					Comma(strb);
					strb.Append("Insurance relationship must be self for Denti-Cal");
				}
				//We cannot perform this check, because the user must enter this ID in the carrier payor id box before this block is even triggered, defeating the purpose of this check.
				//if(carrier.ElectID!="94146") {
				//  Comma(strb);
				//  strb.Append("Carrier ID must be set to 94146 for Denti-Cal.");
				//}
			}
			X12Validate.Carrier(carrier,strb);
			ElectID electID=ElectIDs.GetID(carrier.ElectID);
			if(electID!=null && electID.IsMedicaid && billProv.MedicaidID=="") {
				Comma(strb);
				strb.Append("BillProv Medicaid ID");
			}
			Patient patient=Patients.GetPat(claim.PatNum);
			if(claim.PlanNum2>0) {
				InsPlan insPlan2=InsPlans.GetPlan(claim.PlanNum2,new List<InsPlan>());
				InsSub sub2=InsSubs.GetSub(claim.InsSubNum2,null);
				if(sub2.SubscriberID.Length<2) {
					Comma(strb);
					strb.Append("Secondary SubscriberID");
				}
				Patient subscriber2=Patients.GetPat(sub2.Subscriber); //Always exists because validated in UI.
				if(subscriber2.PatNum!=patient.PatNum) {//Patient address is validated below, so we only need to check if subscriber is not the patient.
					X12Validate.Subscriber2(subscriber2,strb);
				}
				if(subscriber2.Birthdate.Year<1880) {
					Comma(strb);
					strb.Append("Secondary Subscriber Birthdate");
				}
				Carrier carrier2=Carriers.GetCarrier(insPlan2.CarrierNum);
				if(carrier2.Address.Trim()=="") {
					Comma(strb);
					strb.Append("Secondary Carrier Address");
				}
				if(carrier2.City.Trim().Length<2) {
					Comma(strb);
					strb.Append("Secondary Carrier City");
				}
				if(carrier2.State.Trim().Length!=2) {
					Comma(strb);
					strb.Append("Secondary Carrier State(2 char)");
				}
				if(carrier2.Zip.Trim().Length<3) {
					Comma(strb);
					strb.Append("Secondary Carrier Zip");
				}
				if(claim.PatNum != sub2.Subscriber//if patient is not subscriber
					&& claim.PatRelat2==Relat.Self) {//and relat is self
					Comma(strb);
					strb.Append("Secondary Relationship");
				}
				PatPlan patPlan2=PatPlans.GetFromList(patPlans,claim.InsSubNum2);//can be null
				if(patPlan2!=null && patPlan2.PatID!="") {
					Comma(strb);
					strb.Append("Create a new insurance plan instead of using the optional patient ID for the other insurance plan");
				}
			}
			else { //other insurance not specified
				if(claim.ClaimType=="S") {
					Comma(strb);
					strb.Append("Secondary claim missing other insurance");
				}
			}
			//Provider Idents:
			/*ProviderSupplementalID[] providerIdents=ElectIDs.GetRequiredIdents(carrier.ElectID);
				//No longer any required supplemental IDs
			for(int i=0;i<providerIdents.Length;i++){
				if(!ProviderIdents.IdentExists(providerIdents[i],billProv.ProvNum,carrier.ElectID)){
					if(retVal!="")
						strb.Append(",";
					strb.Append("Billing Prov Supplemental ID:"+providerIdents[i].ToString();
				}
			}*/
			if(sub.SubscriberID.Length<2) {
				Comma(strb);
				strb.Append("SubscriberID");
			}
			Patient subscriber=Patients.GetPat(sub.Subscriber);
			if(subscriber.PatNum!=patient.PatNum) {//Patient address is validated below, so we only need to check if subscriber is not the patient.
				X12Validate.Subscriber(subscriber,strb);
			}
			if(subscriber.Birthdate.Year<1880) {
				Comma(strb);
				strb.Append("Subscriber Birthdate");
			}
			if(claim.PatNum != sub.Subscriber//if patient is not subscriber
				&& claim.PatRelat==Relat.Self) {//and relat is self
				Comma(strb);
				strb.Append("Claim Relationship");
			}
			if(patient.Address.Trim()=="") {
				Comma(strb);
				strb.Append("Patient Address");
			}
			if(patient.City.Trim().Length<2) {
				Comma(strb);
				strb.Append("Patient City");
			}
			if(patient.State.Trim().Length!=2) {
				Comma(strb);
				strb.Append("Patient State");
			}
			if(patient.Zip.Trim().Length<3) {
				Comma(strb);
				strb.Append("Patient Zip");
			}
			if(patient.Birthdate.Year<1880) {
				Comma(strb);
				strb.Append("Patient Birthdate");
			}
			if(claim.AccidentRelated=="A" && claim.AccidentST.Length!=2) {//auto accident with no state
				Comma(strb);
				strb.Append("Auto accident State");
			}
			/*if(IsTesia(clearhouse) && claim.Attachments.Count>0) {//If Tesia and has attachments
				string storedFile;
				for(int c=0;c<claim.Attachments.Count;c++) {
					storedFile=ODFileUtils.CombinePaths(FormEmailMessageEdit.GetAttachPath(),claim.Attachments[c].ActualFileName);
					if(!File.Exists(storedFile)){
						if(retVal!="")
							strb.Append(",";
						strb.Append("attachments missing";
						break;
					}
				}
			}*/
			//Warning if attachments are listed as Mail even though we are sending electronically.
			bool pwkNeeded=false;
			if(claim.AttachedFlags!="Mail") {//in other words, if there are additional flags.
				pwkNeeded=true;
			}
			if(claim.Radiographs>0 || claim.AttachedImages>0 || claim.AttachedModels>0) {
				pwkNeeded=true;
			}
			if(claim.AttachedFlags.Contains("Mail") && pwkNeeded) {
				if(warning!="")
					warning+=",";
				warning+="Attachments set to Mail";
			}
			//Warning if any PWK segments are needed, and there is no ID code.
			if(pwkNeeded && claim.AttachmentID=="") {
				if(warning!="")
					warning+=",";
				warning+="Attachment ID missing";
			}
			//If Attachment ID # is present but no attachment flag, then sending is blocked.
			if(!pwkNeeded && claim.AttachmentID!="") {
				Comma(strb);
				strb.Append("Attachment type missing");
			}
			if(claim.MedType==EnumClaimMedType.Institutional) {
				if(claim.UniformBillType.Length!=3) {
					Comma(strb);
					strb.Append("BillType");
				}
				if(claim.AdmissionTypeCode.Length!=1) {
					Comma(strb);
					strb.Append("AdmissionType");
				}
				if(claim.AdmissionSourceCode.Length!=1) {
					Comma(strb);
					strb.Append("AdmissionSource");
				}
				if(claim.PatientStatusCode.Length!=2) {
					Comma(strb);
					strb.Append("PatientStatusCode");
				}
			}
			if(claim.ClaimType!="PreAuth") {
				if(claim.DateService.Year<1880) {
					Comma(strb);
					strb.Append("DateService");
				}
			}
			if(claim.MedType==EnumClaimMedType.Institutional
				|| claim.MedType==EnumClaimMedType.Medical) 
			{
				if(claim.PreAuthString!="") {
					Comma(strb);
					strb.Append("Predeterm number not allowed");
				}
			}
			if((claim.CorrectionType!=ClaimCorrectionType.Original)
				&& claim.OrigRefNum.Trim()=="") {
				Comma(strb);
				strb.Append("Original reference num needed when correction type is not set to original");
			}
			if(claim.UniformBillType.Length>2 
				&& (claim.UniformBillType.Substring(2,1)=="6" || claim.UniformBillType.Substring(2,1)=="7" || claim.UniformBillType.Substring(2,1)=="8")//correction, replacement, void
				&& claim.OrigRefNum.Trim()=="") {
				Comma(strb);
				strb.Append("Original reference num needed when type of bill ends in 6, 7 or 8");
			}
			if(claim.ClaimIdentifier.Trim()=="") {
				Comma(strb);
				strb.Append("Claim identifier missing");
			}
			else if(Claims.ClaimIdentifierInUse(claim.ClaimIdentifier,claim.ClaimNum)) {
				Comma(strb);
				strb.Append("Claim identifier already in use for another claim");
			}
			List<ClaimProc> claimProcList=ClaimProcs.RefreshForClaim(claim.ClaimNum);
			List<ClaimProc> claimProcs=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
			if(claimProcs.Count==0) {
				Comma(strb);
				strb.Append("No procedures attached please recreate claim");
			}
			List<Procedure> procList=Procedures.GetProcsFromClaimProcs(claimProcs);
			Procedure proc;
			ProcedureCode procCode;
			bool princDiagExists=false;
			for(int i=0;i<claimProcs.Count;i++) {
				string p="proc"+(i+1).ToString()+"-";
				proc=Procedures.GetProcFromList(procList,claimProcs[i].ProcNum);
				procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
				if(claim.MedType==EnumClaimMedType.Medical) {
					if(proc.DiagnosticCode=="") {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+"Procedure Diagnosis");
					}
					if(proc.IsPrincDiag && proc.DiagnosticCode!="") {
						princDiagExists=true;
					}
					if(proc.CodeMod1.Length!=0 && proc.CodeMod1.Length!=2) {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" mod1");
					}
					if(proc.CodeMod2.Length!=0 && proc.CodeMod2.Length!=2) {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" mod2");
					}
					if(proc.CodeMod3.Length!=0 && proc.CodeMod3.Length!=2) {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" mod3");
					}
					if(proc.CodeMod4.Length!=0 && proc.CodeMod4.Length!=2) {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" mod4");
					}
					if(Regex.IsMatch(claimProcs[i].CodeSent,"^[0-9]{3}99$") && proc.ClaimNote.Trim()=="") { //CPT codes ending in 99.
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" proc e-claim note missing");
					}
				}
				else if(claim.MedType==EnumClaimMedType.Institutional) {
					if(proc.RevCode==""){
						Comma(strb);
						strb.Append(p+"RevenueCode");
					}
					if(proc.CodeMod1.Length!=0 && proc.CodeMod1.Length!=2){
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" mod1");
					}
					if(proc.CodeMod2.Length!=0 && proc.CodeMod2.Length!=2){
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" mod2");
					}
					if(proc.CodeMod3.Length!=0 && proc.CodeMod3.Length!=2){
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" mod3");
					}
					if(proc.CodeMod4.Length!=0 && proc.CodeMod4.Length!=2){
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" mod4");
					}
					if(procCode.DrugNDC!="" && proc.DrugQty>0){
						if(proc.DrugUnit==EnumProcDrugUnit.None){
							Comma(strb);
							strb.Append(procCode.AbbrDesc+" drug unit");
						}
					}
				}
				else if(claim.MedType==EnumClaimMedType.Dental) {
					if(procCode.TreatArea==TreatmentArea.Arch && proc.Surf=="") {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" missing arch");
					}
					if(procCode.TreatArea==TreatmentArea.ToothRange && proc.ToothRange=="") {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" tooth range");
					}
					if(procCode.TreatArea==TreatmentArea.ToothRange && proc.UnitQty>1) {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" unit quantity must be 1 since area is tooth range");
					}
					if((procCode.TreatArea==TreatmentArea.Tooth || procCode.TreatArea==TreatmentArea.Surf)
						&& !Tooth.IsValidDB(proc.ToothNum)) 
					{
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" tooth number");
					}
					if(procCode.TreatArea==TreatmentArea.Surf && proc.Surf=="") {
						Comma(strb);
						strb.Append(procCode.AbbrDesc+" surface missing");
					}
					if(procCode.IsProsth) {
						if(proc.Prosthesis=="") {//they didn't enter whether Initial or Replacement
							Comma(strb);
							strb.Append(procCode.AbbrDesc+" Prosthesis");
						}
						if(proc.Prosthesis=="R"	&& proc.DateOriginalProsth.Year<1880) {//if a replacement, they didn't enter a date
							Comma(strb);
							strb.Append(procCode.AbbrDesc+" Prosth Date");
						}
					}
				}
				//if(proc.PlaceService!=claim.PlaceService) {
				//  Comma(strb);
				//  strb.Append("Proc place of service does not match claim "+procCode.ProcCode);
				//}
				//Providers
				if(claim.ProvTreat!=proc.ProvNum && PrefC.GetBool(PrefName.EclaimsSeparateTreatProv)) {
					treatProv=ProviderC.ListLong[Providers.GetIndexLong(proc.ProvNum)];
					if(treatProv.LName=="") {
						Comma(strb);
						strb.Append("Treat Prov LName for proc "+procCode.ProcCode);
					}
					if(treatProv.FName=="" && !treatProv.IsNotPerson) {
						Comma(strb);
						strb.Append("Treat Prov FName for proc "+procCode.ProcCode);
					}
					if(treatProv.NationalProvID.Length<2) {
						Comma(strb);
						strb.Append("Treat Prov NPI for proc "+procCode.ProcCode);
					}
					if(claim.MedType!=EnumClaimMedType.Institutional) { //Medical and Dental only. No where to send taxonomy code for instituational procedures.
						if(treatProv.TaxonomyCodeOverride.Length>0 && treatProv.TaxonomyCodeOverride.Length!=10) {
							Comma(strb);
							strb.Append("Treating Prov Taxonomy Code for proc "+procCode.ProcCode+" must be 10 characters");
						}
					}
					//Treating prov SSN/TIN is not sent on paper or eclaims. Do not verify or block.
					if(!Regex.IsMatch(treatProv.NationalProvID,"^(80840)?[0-9]{10}$")) {
						Comma(strb);
						strb.Append("Treat Prov NPI for proc "+procCode.ProcCode+" must be a 10 digit number with an optional prefix of 80840");
					}
					//will add any other checks as needed. Can't think of any others at the moment.
				}
			}//for int i claimProcs
			if(claim.MedType==EnumClaimMedType.Medical && !princDiagExists) {
				Comma(strb);
				strb.Append("Princ Diagnosis");
			}
			queueItem.Warnings=warning;
			queueItem.MissingData=strb.ToString();
		}
		///<summary>Returns a string describing all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.</summary>
		public static string GetMissingData(ClaimSendQueueItem queueItem){
			//Our support for Renaissance is minimal, because they do not use the X12 format and we do not recommend that our customers use it.
			//Thus, we do not perform validation.
			return "";
		}
Exemple #10
0
 ///<summary>Returns a string describing all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.  There is also an out parameter containing any warnings.  Warnings will not block sending.</summary>
 public static void Validate(ClaimSendQueueItem queueItem)
 {
     //,out string warning) {
     StringBuilder strb=new StringBuilder();
     string warning="";
     Clearinghouse clearhouse=null;//ClearinghouseL.GetClearinghouse(queueItem.ClearinghouseNum);
     for(int i=0;i<Clearinghouses.Listt.Length;i++) {
         if(Clearinghouses.Listt[i].ClearinghouseNum==queueItem.ClearinghouseNum) {
             clearhouse= Clearinghouses.Listt[i];
         }
     }
     if(clearhouse==null) {
         throw new ApplicationException("Error. Could not locate Clearinghouse.");
     }
     Claim claim=Claims.GetClaim(queueItem.ClaimNum);
     Clinic clinic=Clinics.GetClinic(claim.ClinicNum);
     //if(clearhouse.Eformat==ElectronicClaimFormat.X12){//not needed since this is always true
     X12Validate.ISA(clearhouse,strb);
     if(clearhouse.GS03.Length<2) {
         Comma(strb);
         strb.Append("Clearinghouse GS03");
     }
     List<X12TransactionItem> claimItems=Claims.GetX12TransactionInfo(((ClaimSendQueueItem)queueItem).ClaimNum);//just to get prov. Needs work.
     Provider billProv=ProviderC.ListLong[Providers.GetIndexLong(claimItems[0].ProvBill1)];
     Provider treatProv=ProviderC.ListLong[Providers.GetIndexLong(claim.ProvTreat)];
     Referral referral=Referrals.GetReferral(claim.ReferringProv);
     InsPlan insPlan=InsPlans.GetPlan(claim.PlanNum,null);
     InsSub sub=InsSubs.GetSub(claim.InsSubNum,null);
     if(claim.MedType==EnumClaimMedType.Medical) {
         if(referral!=null && referral.IsDoctor && referral.NotPerson) {
             Comma(strb);
             strb.Append("Referring Prov must be a person.");
         }
         if(treatProv.IsNotPerson && claim.ProvTreat!=claim.ProvBill) {
             Comma(strb);
             strb.Append("Treat Prov must be a person.");
         }
     }
     else if(claim.MedType==EnumClaimMedType.Institutional) {
         if(referral!=null && referral.IsDoctor && referral.NotPerson && claim.ReferringProv!=claim.ProvTreat) {
             Comma(strb);
             strb.Append("Referring Prov must be a person.");
         }
         if(!billProv.IsNotPerson) {
             Comma(strb);
             strb.Append("Billing Prov cannot be a person.");
         }
         if(treatProv.IsNotPerson) {
             Comma(strb);
             strb.Append("Treat Prov must be a person.");
         }
     }
     else if(claim.MedType==EnumClaimMedType.Dental) {
         if(referral!=null && referral.IsDoctor && referral.NotPerson) {
             Comma(strb);
             strb.Append("Referring Prov must be a person.");
         }
     }
     //billProv
     if(billProv.LName=="") {
         Comma(strb);
         strb.Append("Billing Prov LName");
     }
     if(billProv.FName=="" && !billProv.IsNotPerson) {//this is allowed to be blank if it's a non-person.
         Comma(strb);
         strb.Append("Billing Prov FName");
     }
     if(billProv.SSN.Length<2) {
         Comma(strb);
         strb.Append("Billing Prov SSN");
     }
     if(billProv.NationalProvID.Length<2) {
         Comma(strb);
         strb.Append("Billing Prov NPI");
     }
     if(CultureInfo.CurrentCulture.Name.EndsWith("US")) {//United States
         if(!Regex.IsMatch(billProv.SSN,"^[0-9]{9}$")) {
             Comma(strb);
             strb.Append("Billing Prov SSN/TIN must be a 9 digit number");
         }
         if(!Regex.IsMatch(billProv.NationalProvID,"^(80840)?[0-9]{10}$")) {
             Comma(strb);
             strb.Append("Billing Prov NPI must be a 10 digit number with an optional prefix of 80840");
         }
     }
     if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
         string zip=PrefC.GetString(PrefName.PracticeBillingZip);
         if(!Regex.IsMatch(zip,"^[0-9]{5}\\-?[0-9]{4}$")) {
             Comma(strb);
             strb.Append("Practice billing zip must contain nine digits");
         }
         if(Regex.IsMatch(PrefC.GetString(PrefName.PracticeBillingAddress),".*P\\.?O\\.? .*",RegexOptions.IgnoreCase)) {
             Comma(strb);
             strb.Append("Practice billing address cannot be a P.O. BOX when used for e-claims.");
         }
     }
     else if(clinic==null) {
         string zip=PrefC.GetString(PrefName.PracticeZip);
         if(!Regex.IsMatch(zip,"^[0-9]{5}\\-?[0-9]{4}$")) {
             Comma(strb);
             strb.Append("Practice zip must contain nine digits");
         }
         if(Regex.IsMatch(PrefC.GetString(PrefName.PracticeAddress),".*P\\.?O\\.? .*",RegexOptions.IgnoreCase)) {
             Comma(strb);
             strb.Append("Practice address cannot be a P.O. BOX when used for e-claims.");
         }
     }
     else {
         string zip=clinic.Zip;
         if(!Regex.IsMatch(zip,"^[0-9]{5}\\-?[0-9]{4}$")) {
             Comma(strb);
             strb.Append("Clinic zip must contain nine digits");
         }
         if(Regex.IsMatch(clinic.Address,".*P\\.?O\\.? .*",RegexOptions.IgnoreCase)) {
             Comma(strb);
             strb.Append("Clinic address cannot be a P.O. BOX when used for e-claims.");
         }
     }
     //treatProv
     if(treatProv.LName=="") {
         Comma(strb);
         strb.Append("Treating Prov LName");
     }
     if(treatProv.FName=="" && !treatProv.IsNotPerson) {
         Comma(strb);
         strb.Append("Treating Prov FName");
     }
     if(treatProv.SSN.Length<2) {
         Comma(strb);
         strb.Append("Treating Prov SSN/TIN");
     }
     if(treatProv.NationalProvID.Length<2) {
         Comma(strb);
         strb.Append("Treating Prov NPI");
     }
     if(CultureInfo.CurrentCulture.Name.EndsWith("US")) {//United States
         if(!Regex.IsMatch(treatProv.SSN,"^[0-9]{9}$")) {
             Comma(strb);
             strb.Append("Treating Prov SSN/TIN for claim must be a 9 digit number");
         }
         if(!Regex.IsMatch(treatProv.NationalProvID,"^(80840)?[0-9]{10}$")) {
             Comma(strb);
             strb.Append("Treating Prov NPI for claim must be a 10 digit number with an optional prefix of 80840");
         }
     }
     if(PrefC.GetString(PrefName.PracticeTitle)=="") {
         Comma(strb);
         strb.Append("Practice Title");
     }
     if(clinic==null) {
         X12Validate.PracticeAddress(strb);
     }
     else {
         X12Validate.Clinic(clinic,strb);
     }
     if(!sub.ReleaseInfo) {
         Comma(strb);
         strb.Append("InsPlan Release of Info");
     }
     Carrier carrier=Carriers.GetCarrier(insPlan.CarrierNum);
     if(IsDentiCal(clearhouse)) {
         if(GetFilingCode(insPlan)!="MC") {
             Comma(strb);
             strb.Append("InsPlan Filing Code must be Medicaid for Denti-Cal.");
         }
         //We cannot perform this check, because the user must enter this ID in the carrier payor id box before this block is even triggered, defeating the purpose of this check.
         //if(carrier.ElectID!="94146") {
         //  Comma(strb);
         //  strb.Append("Carrier ID must be set to 94146 for Denti-Cal.");
         //}
     }
     X12Validate.Carrier(carrier,strb);
     ElectID electID=ElectIDs.GetID(carrier.ElectID);
     if(electID!=null && electID.IsMedicaid && billProv.MedicaidID=="") {
         Comma(strb);
         strb.Append("BillProv Medicaid ID");
     }
     if(claim.PlanNum2>0) {
         InsPlan insPlan2=InsPlans.GetPlan(claim.PlanNum2,new List<InsPlan>());
         InsSub sub2=InsSubs.GetSub(claim.InsSubNum2,null);
         Carrier carrier2=Carriers.GetCarrier(insPlan2.CarrierNum);
         if(carrier2.Address=="") {
             Comma(strb);
             strb.Append("Secondary Carrier Address");
         }
         if(carrier2.City.Length<2) {
             Comma(strb);
             strb.Append("Secondary Carrier City");
         }
         if(carrier2.State.Length!=2) {
             Comma(strb);
             strb.Append("Secondary Carrier State(2 char)");
         }
         if(carrier2.Zip.Length<3) {
             Comma(strb);
             strb.Append("Secondary Carrier Zip");
         }
         if(claim.PatNum != sub2.Subscriber//if patient is not subscriber
             && claim.PatRelat2==Relat.Self) {//and relat is self
             Comma(strb);
             strb.Append("Secondary Relationship");
         }
     }
     //Provider Idents:
     /*ProviderSupplementalID[] providerIdents=ElectIDs.GetRequiredIdents(carrier.ElectID);
         //No longer any required supplemental IDs
     for(int i=0;i<providerIdents.Length;i++){
         if(!ProviderIdents.IdentExists(providerIdents[i],billProv.ProvNum,carrier.ElectID)){
             if(retVal!="")
                 strb.Append(",";
             strb.Append("Billing Prov Supplemental ID:"+providerIdents[i].ToString();
         }
     }*/
     if(sub.SubscriberID.Length<2) {
         Comma(strb);
         strb.Append("SubscriberID");
     }
     Patient patient=Patients.GetPat(claim.PatNum);
     Patient subscriber=Patients.GetPat(sub.Subscriber);
     if(claim.PatNum != sub.Subscriber//if patient is not subscriber
         && claim.PatRelat==Relat.Self) {//and relat is self
         Comma(strb);
         strb.Append("Claim Relationship");
     }
     if(patient.Address=="") {
         Comma(strb);
         strb.Append("Patient Address");
     }
     if(patient.City.Length<2) {
         Comma(strb);
         strb.Append("Patient City");
     }
     if(patient.State.Length!=2) {
         Comma(strb);
         strb.Append("Patient State");
     }
     if(patient.Zip.Length<3) {
         Comma(strb);
         strb.Append("Patient Zip");
     }
     if(patient.Birthdate.Year<1880) {
         Comma(strb);
         strb.Append("Patient Birthdate");
     }
     if(claim.AccidentRelated=="A" && claim.AccidentST.Length!=2) {//auto accident with no state
         Comma(strb);
         strb.Append("Auto accident State");
     }
     /*if(IsTesia(clearhouse) && claim.Attachments.Count>0) {//If Tesia and has attachments
         string storedFile;
         for(int c=0;c<claim.Attachments.Count;c++) {
             storedFile=ODFileUtils.CombinePaths(FormEmailMessageEdit.GetAttachPath(),claim.Attachments[c].ActualFileName);
             if(!File.Exists(storedFile)){
                 if(retVal!="")
                     strb.Append(",";
                 strb.Append("attachments missing";
                 break;
             }
         }
     }*/
     //Warning if attachments are listed as Mail even though we are sending electronically.
     bool pwkNeeded=false;
     if(claim.AttachedFlags!="Mail") {//in other words, if there are additional flags.
         pwkNeeded=true;
     }
     if(claim.Radiographs>0 || claim.AttachedImages>0 || claim.AttachedModels>0) {
         pwkNeeded=true;
     }
     if(claim.AttachedFlags.Contains("Mail") && pwkNeeded) {
         if(warning!="")
             warning+=",";
         warning+="Attachments set to Mail";
     }
     //Warning if any PWK segments are needed, and there is no ID code.
     if(pwkNeeded && claim.AttachmentID=="") {
         if(warning!="")
             warning+=",";
         warning+="Attachment ID missing";
     }
     if(claim.MedType==EnumClaimMedType.Institutional) {
         if(claim.UniformBillType.Length!=3) {
             Comma(strb);
             strb.Append("BillType");
         }
         if(claim.AdmissionTypeCode.Length!=1) {
             Comma(strb);
             strb.Append("AdmissionType");
         }
         if(claim.AdmissionSourceCode.Length!=1) {
             Comma(strb);
             strb.Append("AdmissionSource");
         }
         if(claim.PatientStatusCode.Length!=2) {
             Comma(strb);
             strb.Append("PatientStatusCode");
         }
     }
     if(claim.ClaimType!="PreAuth") {
         if(claim.DateService.Year<1880) {
             Comma(strb);
             strb.Append("DateService");
         }
     }
     if(claim.MedType==EnumClaimMedType.Institutional
         || claim.MedType==EnumClaimMedType.Medical)
     {
         if(claim.PreAuthString!="") {
             Comma(strb);
             strb.Append("Predeterm number not allowed");
         }
     }
     List<ClaimProc> claimProcList=ClaimProcs.RefreshForClaim(claim.ClaimNum);
     List<ClaimProc> claimProcs=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
     List<Procedure> procList=Procedures.GetProcsFromClaimProcs(claimProcs);
     Procedure proc;
     ProcedureCode procCode;
     bool princDiagExists=false;
     for(int i=0;i<claimProcs.Count;i++) {
         string p="proc"+(i+1).ToString()+"-";
         proc=Procedures.GetProcFromList(procList,claimProcs[i].ProcNum);
         procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
         if(claim.MedType==EnumClaimMedType.Medical) {
             if(proc.DiagnosticCode=="") {
                 Comma(strb);
                 strb.Append(procCode.AbbrDesc+"Procedure Diagnosis");
             }
             if(proc.IsPrincDiag && proc.DiagnosticCode!="") {
                 princDiagExists=true;
             }
         }
         else if(claim.MedType==EnumClaimMedType.Institutional) {
             if(proc.RevCode==""){
                 Comma(strb);
                 strb.Append(p+"RevenueCode");
             }
             if(proc.CodeMod1.Length!=0 && proc.CodeMod1.Length!=2){
                 Comma(strb);
                 strb.Append(procCode.AbbrDesc+" mod1");
             }
             if(proc.CodeMod2.Length!=0 && proc.CodeMod2.Length!=2){
                 Comma(strb);
                 strb.Append(procCode.AbbrDesc+" mod2");
             }
             if(proc.CodeMod3.Length!=0 && proc.CodeMod3.Length!=2){
                 Comma(strb);
                 strb.Append(procCode.AbbrDesc+" mod3");
             }
             if(proc.CodeMod4.Length!=0 && proc.CodeMod4.Length!=2){
                 Comma(strb);
                 strb.Append(procCode.AbbrDesc+" mod4");
             }
             if(procCode.DrugNDC!="" && proc.DrugQty>0){
                 if(proc.DrugUnit==EnumProcDrugUnit.None){
                     Comma(strb);
                     strb.Append(procCode.AbbrDesc+" drug unit");
                 }
             }
         }
         else if(claim.MedType==EnumClaimMedType.Dental) {
             if(procCode.TreatArea==TreatmentArea.Arch && proc.Surf=="") {
                 Comma(strb);
                 strb.Append(procCode.AbbrDesc+" missing arch");
             }
             if(procCode.TreatArea==TreatmentArea.ToothRange && proc.ToothRange=="") {
                 Comma(strb);
                 strb.Append(procCode.AbbrDesc+" tooth range");
             }
             if((procCode.TreatArea==TreatmentArea.Tooth || procCode.TreatArea==TreatmentArea.Surf)
                 && !Tooth.IsValidDB(proc.ToothNum))
             {
                 Comma(strb);
                 strb.Append(procCode.AbbrDesc+" tooth number");
             }
             if(procCode.IsProsth) {
                 if(proc.Prosthesis=="") {//they didn't enter whether Initial or Replacement
                     Comma(strb);
                     strb.Append(procCode.AbbrDesc+" Prosthesis");
                 }
                 if(proc.Prosthesis=="R"	&& proc.DateOriginalProsth.Year<1880) {//if a replacement, they didn't enter a date
                     Comma(strb);
                     strb.Append(procCode.AbbrDesc+" Prosth Date");
                 }
             }
         }
         //Providers
         if(claim.ProvTreat!=proc.ProvNum && PrefC.GetBool(PrefName.EclaimsSeparateTreatProv)) {
             treatProv=ProviderC.ListLong[Providers.GetIndexLong(proc.ProvNum)];
             if(claim.MedType==EnumClaimMedType.Institutional) {
                 if(treatProv.IsNotPerson) {
                     Comma(strb);
                     strb.Append("Treat Prov must be a person for proc "+procCode.ProcCode);
                 }
             }
             if(treatProv.LName=="") {
                 Comma(strb);
                 strb.Append("Treat Prov LName for proc "+procCode.ProcCode);
             }
             if(treatProv.FName=="" && !treatProv.IsNotPerson) {
                 Comma(strb);
                 strb.Append("Treat Prov FName for proc "+procCode.ProcCode);
             }
             if(treatProv.SSN.Length<2) {
                 Comma(strb);
                 strb.Append("Treat Prov SSN/TIN for proc "+procCode.ProcCode);
             }
             if(treatProv.NationalProvID.Length<2) {
                 Comma(strb);
                 strb.Append("Treat Prov NPI for proc "+procCode.ProcCode);
             }
             if(CultureInfo.CurrentCulture.Name.EndsWith("US")) {//United States
                 if(!Regex.IsMatch(treatProv.SSN,"^[0-9]{9}$")) {
                     Comma(strb);
                     strb.Append("Treat Prov SSN/TIN for proc "+procCode.ProcCode+" must be a 9 digit number");
                 }
                 if(!Regex.IsMatch(treatProv.NationalProvID,"^(80840)?[0-9]{10}$")) {
                     Comma(strb);
                     strb.Append("Treat Prov NPI for proc "+procCode.ProcCode+" must be a 10 digit number with an optional prefix of 80840");
                 }
             }
             //will add any other checks as needed. Can't think of any others at the moment.
         }
     }//for int i claimProcs
     if(claim.MedType==EnumClaimMedType.Medical && !princDiagExists) {
         Comma(strb);
         strb.Append("Princ Diagnosis");
     }
     queueItem.Warnings=warning;
     queueItem.MissingData=strb.ToString();
 }
Exemple #11
0
 ///<summary>Returns a string describing all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.</summary>
 public static string GetMissingData(ClaimSendQueueItem queueItem)
 {
     return "";
 }
Exemple #12
0
        ///<summary>Returns a string describing all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.  There is also an out parameter containing any warnings.  Warnings will not block sending.</summary>
        public static void Validate(ClaimSendQueueItem queueItem)
        {
            //,out string warning) {
            StringBuilder strb=new StringBuilder();
            string warning="";
            Clearinghouse clearhouse=null;//ClearinghouseL.GetClearinghouse(queueItem.ClearinghouseNum);
            for(int i=0;i<Clearinghouses.Listt.Length;i++) {
                if(Clearinghouses.Listt[i].ClearinghouseNum==queueItem.ClearinghouseNum) {
                    clearhouse= Clearinghouses.Listt[i];
                }
            }
            if(clearhouse==null) {
                throw new ApplicationException("Error. Could not locate Clearinghouse.");
            }
            Claim claim=Claims.GetClaim(queueItem.ClaimNum);
            Clinic clinic=Clinics.GetClinic(claim.ClinicNum);
            //if(clearhouse.Eformat==ElectronicClaimFormat.X12){//not needed since this is always true
            X12Validate.ISA(clearhouse,strb);
            if(clearhouse.GS03.Length<2) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Clearinghouse GS03");
            }
            List<X12TransactionItem> claimItems=Claims.GetX12TransactionInfo(((ClaimSendQueueItem)queueItem).ClaimNum);//just to get prov. Needs work.
            Provider billProv=ProviderC.ListLong[Providers.GetIndexLong(claimItems[0].ProvBill1)];
            Provider treatProv=ProviderC.ListLong[Providers.GetIndexLong(claim.ProvTreat)];
            InsPlan insPlan=InsPlans.GetPlan(claim.PlanNum,null);
            InsSub sub=InsSubs.GetSub(claim.InsSubNum,null);
            //if(insPlan.IsMedical) {
            //	return "Medical e-claims not allowed";
            //}
            //billProv
            X12Validate.BillProv(billProv,strb);
            //treatProv
            if(treatProv.LName=="") {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Treating Prov LName");
            }
            if(treatProv.FName=="") {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Treating Prov FName");
            }
            if(treatProv.SSN.Length<2) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Treating Prov SSN");
            }
            if(treatProv.NationalProvID.Length<2) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Treating Prov NPI");
            }
            if(treatProv.StateLicense=="") {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Treating Prov Lic #");
            }
            if(insPlan.IsMedical) {
                if(treatProv.NationalProvID.Length<2) {
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append("Treating Prov NPI");
                }
            }
            if(PrefC.GetString(PrefName.PracticeTitle)=="") {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Practice Title");
            }
            if(clinic==null) {
                X12Validate.PracticeAddress(strb);
            }
            else {
                X12Validate.Clinic(clinic,strb);
            }
            if(!sub.ReleaseInfo) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("InsPlan Release of Info");
            }
            Carrier carrier=Carriers.GetCarrier(insPlan.CarrierNum);
            X12Validate.Carrier(carrier,strb);
            ElectID electID=ElectIDs.GetID(carrier.ElectID);
            if(electID!=null && electID.IsMedicaid && billProv.MedicaidID=="") {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("BillProv Medicaid ID");
            }
            if(claim.PlanNum2>0) {
                InsPlan insPlan2=InsPlans.GetPlan(claim.PlanNum2,new List<InsPlan>());
                InsSub sub2=InsSubs.GetSub(claim.InsSubNum2,null);
                Carrier carrier2=Carriers.GetCarrier(insPlan2.CarrierNum);
                if(carrier2.Address=="") {
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append("Secondary Carrier Address");
                }
                if(carrier2.City.Length<2) {
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append("Secondary Carrier City");
                }
                if(carrier2.State.Length!=2) {
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append("Secondary Carrier State(2 char)");
                }
                if(carrier2.Zip.Length<3) {
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append("Secondary Carrier Zip");
                }
                if(claim.PatNum != sub2.Subscriber//if patient is not subscriber
                    && claim.PatRelat2==Relat.Self) {//and relat is self
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append("Secondary Relationship");
                }
            }
            //Provider Idents:
            /*ProviderSupplementalID[] providerIdents=ElectIDs.GetRequiredIdents(carrier.ElectID);
                //No longer any required supplemental IDs
            for(int i=0;i<providerIdents.Length;i++){
                if(!ProviderIdents.IdentExists(providerIdents[i],billProv.ProvNum,carrier.ElectID)){
                    if(retVal!="")
                        strb.Append(",";
                    strb.Append("Billing Prov Supplemental ID:"+providerIdents[i].ToString();
                }
            }*/
            if(sub.SubscriberID.Length<2) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("SubscriberID");
            }
            Patient patient=Patients.GetPat(claim.PatNum);
            Patient subscriber=Patients.GetPat(sub.Subscriber);
            if(claim.PatNum != sub.Subscriber//if patient is not subscriber
                && claim.PatRelat==Relat.Self) {//and relat is self
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Claim Relationship");
            }
            if(patient.Address=="") {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Patient Address");
            }
            if(patient.City.Length<2) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Patient City");
            }
            if(patient.State.Length!=2) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Patient State");
            }
            if(patient.Zip.Length<3) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Patient Zip");
            }
            if(patient.Birthdate.Year<1880) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Patient Birthdate");
            }
            if(claim.AccidentRelated=="A" && claim.AccidentST.Length!=2) {//auto accident with no state
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Auto accident State");
            }
            /*if(clearhouse.ISA08=="113504607" && claim.Attachments.Count>0) {//If Tesia and has attachments
                string storedFile;
                for(int c=0;c<claim.Attachments.Count;c++) {
                    storedFile=ODFileUtils.CombinePaths(FormEmailMessageEdit.GetAttachPath(),claim.Attachments[c].ActualFileName);
                    if(!File.Exists(storedFile)){
                        if(retVal!="")
                            strb.Append(",";
                        strb.Append("attachments missing";
                        break;
                    }
                }
            }*/
            //Warning if attachments are listed as Mail even though we are sending electronically.
            bool pwkNeeded=false;
            if(claim.AttachedFlags!="Mail") {//in other words, if there are additional flags.
                pwkNeeded=true;
            }
            if(claim.Radiographs>0 || claim.AttachedImages>0 || claim.AttachedModels>0) {
                pwkNeeded=true;
            }
            if(claim.AttachedFlags.Contains("Mail") && pwkNeeded) {
                if(warning!="")
                    warning+=",";
                warning+="Attachments set to Mail";
            }
            //Warning if any PWK segments are needed, and there is no ID code.
            if(pwkNeeded && claim.AttachmentID=="") {
                if(warning!="")
                    warning+=",";
                warning+="Attachment ID missing";
            }
            //List<ClaimProc> claimProcList=ClaimProcs.Refresh(patient.PatNum);
            //List<ClaimProc> claimProcs=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
            //List<Procedure> procList=Procedures.Refresh(claim.PatNum);
            List<ClaimProc> claimProcList=ClaimProcs.RefreshForClaim(claim.ClaimNum);
            List<ClaimProc> claimProcs=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
            List<Procedure> procList=Procedures.GetProcsFromClaimProcs(claimProcs);
            Procedure proc;
            ProcedureCode procCode;
            bool princDiagExists=false;
            for(int i=0;i<claimProcs.Count;i++) {
                proc=Procedures.GetProcFromList(procList,claimProcs[i].ProcNum);
                procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
                if(procCode.TreatArea==TreatmentArea.Arch && proc.Surf=="") {
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append(procCode.AbbrDesc+" missing arch");
                }
                if(procCode.TreatArea==TreatmentArea.ToothRange && proc.ToothRange=="") {
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append(procCode.AbbrDesc+" tooth range");
                }
                if((procCode.TreatArea==TreatmentArea.Tooth || procCode.TreatArea==TreatmentArea.Surf)
                    && !Tooth.IsValidDB(proc.ToothNum)) {
                    if(strb.Length!=0) {
                        strb.Append(",");
                    }
                    strb.Append(procCode.AbbrDesc+" tooth number");
                }
                if(procCode.IsProsth) {
                    if(proc.Prosthesis=="") {//they didn't enter whether Initial or Replacement
                        if(strb.Length!=0) {
                            strb.Append(",");
                        }
                        strb.Append(procCode.AbbrDesc+" Prosthesis");
                    }
                    if(proc.Prosthesis=="R"
                        && proc.DateOriginalProsth.Year<1880) {//if a replacement, they didn't enter a date
                        if(strb.Length!=0) {
                            strb.Append(",");
                        }
                        strb.Append(procCode.AbbrDesc+" Prosth Date");
                    }
                }
                if(insPlan.IsMedical) {
                    if(proc.DiagnosticCode=="") {
                        if(strb.Length!=0) {
                            strb.Append(",");
                        }
                        strb.Append("Procedure Diagnosis");
                    }
                    if(proc.IsPrincDiag && proc.DiagnosticCode!="") {
                        princDiagExists=true;
                    }
                }
                if(claim.ProvTreat!=proc.ProvNum && PrefC.GetBool(PrefName.EclaimsSeparateTreatProv)) {
                    treatProv=ProviderC.ListLong[Providers.GetIndexLong(proc.ProvNum)];
                    if(treatProv.LName=="") {
                        if(strb.Length!=0) {
                            strb.Append(",");
                        }
                        strb.Append("Treating Prov LName");
                    }
                    if(treatProv.FName=="") {
                        if(strb.Length!=0) {
                            strb.Append(",");
                        }
                        strb.Append("Treating Prov FName");
                    }
                    if(treatProv.SSN.Length<2) {
                        if(strb.Length!=0) {
                            strb.Append(",");
                        }
                        strb.Append("Treating Prov SSN");
                    }
                    if(treatProv.NationalProvID.Length<2) {
                        if(strb.Length!=0) {
                            strb.Append(",");
                        }
                        strb.Append("Treating Prov NPI");
                    }
                    if(treatProv.StateLicense=="") {
                        if(strb.Length!=0) {
                            strb.Append(",");
                        }
                        strb.Append("Treating Prov Lic #");
                    }
                    //will add any other checks as needed. Can't think of any others at the moment.
                }
            }//for int i claimProcs
            if(insPlan.IsMedical && !princDiagExists) {
                if(strb.Length!=0) {
                    strb.Append(",");
                }
                strb.Append("Princ Diagnosis");
            }

            /*
                        if(==""){
                            if(strb.Length!=0) {
                                strb.Append(",");
                            }
                            strb.Append("";
                        }*/

            //return strb.ToString();
            queueItem.Warnings=warning;
            queueItem.MissingData=strb.ToString();
        }
Exemple #13
0
		///<summary>Fills the missing data field on the queueItem that was passed in.  This contains all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.</summary>
		public static void GetMissingData(ClaimSendQueueItem queueItem){//, out string warnings){
			queueItem.Warnings="";
			queueItem.MissingData="";
			Clearinghouse clearhouse=ClearinghouseL.GetClearinghouse(queueItem.ClearinghouseNum,true);//Suppress error message in case no default medical clearinghouse set.
			//this is usually just the default clearinghouse or the clearinghouse for the PayorID.
			if(clearhouse==null){
				if(queueItem.MedType==EnumClaimMedType.Dental) {
					queueItem.MissingData+="No default dental clearinghouse set.";
				}
				else {
					queueItem.MissingData+="No default medical/institutional clearinghouse set.";
				}				
				return;
			}
			#region Data Sanity Checking (for Replication)
			//Example: We had one replication customer who was able to delete an insurance plan for which was attached to a claim.
			//Imagine two replication servers, server A and server B.  An insplan is created which is not associated to any claims.
			//Both databases have a copy of the insplan.  The internet connection is lost.  On server A, a user deletes the insurance
			//plan (which is allowed because no claims are attached).  On server B, a user creates a claim with the insurance plan.
			//When the internet connection returns, the delete insplan statement is run on server B, which then creates a claim with
			//an invalid InsPlanNum on server B.  Without the checking below, the send claims window would crash for this one scenario.
			Claim claim=Claims.GetClaim(queueItem.ClaimNum);//This should always exist, because we just did a select to get the queue item.
			InsPlan insPlan=InsPlans.RefreshOne(claim.PlanNum);
			if(insPlan==null) {//Check for missing PlanNums
				queueItem.MissingData=Lans.g("Eclaims","Claim insurance plan record missing.  Please recreate claim.");
				return;
			}
			if(claim.InsSubNum2!=0) {
				InsPlan insPlan2=InsPlans.RefreshOne(claim.PlanNum2);
				if(insPlan2==null) {//Check for missing PlanNums
					queueItem.MissingData=Lans.g("Eclaims","Claim other insurance plan record missing.  Please recreate claim.");
					return;//This will let the office send other claims that passed validation without throwing an exception.
				}
			}
			#endregion Data Sanity Checking (for Replication)
			if(clearhouse.Eformat==ElectronicClaimFormat.x837D_4010){
				X837_4010.Validate(queueItem);//,out warnings);
				//return;
			}
			else if(clearhouse.Eformat==ElectronicClaimFormat.x837D_5010_dental
				|| clearhouse.Eformat==ElectronicClaimFormat.x837_5010_med_inst)
			{
				X837_5010.Validate(queueItem);//,out warnings);
				//return;
			}
			else if(clearhouse.Eformat==ElectronicClaimFormat.Renaissance){
				queueItem.MissingData=Renaissance.GetMissingData(queueItem);
				//return;
			}
			else if(clearhouse.Eformat==ElectronicClaimFormat.Canadian) {
				queueItem.MissingData=Canadian.GetMissingData(queueItem);
				//return;
			}
			else if(clearhouse.Eformat==ElectronicClaimFormat.Dutch) {
				Dutch.GetMissingData(queueItem);//,out warnings);
				//return;
			}
			//return "";
		}
Exemple #14
0
		///<summary>Returns a string describing all missing data on this claim.  Claim will not be allowed to be sent electronically unless this string comes back empty.  There is also an out parameter containing any warnings.  Warnings will not block sending.</summary>
		public static void Validate(ClaimSendQueueItem queueItem) {//,out string warning) {
			StringBuilder strb=new StringBuilder();
			string warning="";
			Clearinghouse clearhouse=null;//ClearinghouseL.GetClearinghouse(queueItem.ClearinghouseNum);
			for(int i=0;i<Clearinghouses.Listt.Length;i++) {
				if(Clearinghouses.Listt[i].ClearinghouseNum==queueItem.ClearinghouseNum) {
					clearhouse= Clearinghouses.Listt[i];
				}
			}
			if(clearhouse==null) {
				throw new ApplicationException("Error. Could not locate Clearinghouse.");
			}
			Claim claim=Claims.GetClaim(queueItem.ClaimNum);
			Clinic clinic=Clinics.GetClinic(claim.ClinicNum);
			//if(clearhouse.Eformat==ElectronicClaimFormat.X12){//not needed since this is always true
			X12Validate.ISA(clearhouse,strb);
			if(clearhouse.GS03.Length<2) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Clearinghouse GS03");
			}
			List<X12TransactionItem> claimItems=Claims.GetX12TransactionInfo(((ClaimSendQueueItem)queueItem).ClaimNum);//just to get prov. Needs work.
			List<Provider> listProvs=ProviderC.GetListLong();
			Provider billProv=listProvs[Providers.GetIndexLong(claimItems[0].ProvBill1,listProvs)];
			Provider treatProv=listProvs[Providers.GetIndexLong(claim.ProvTreat,listProvs)];
			InsPlan insPlan=InsPlans.GetPlan(claim.PlanNum,null);
			InsSub sub=InsSubs.GetSub(claim.InsSubNum,null);
			//if(insPlan.IsMedical) {
			//	return "Medical e-claims not allowed";
			//}
			//billProv
			X12Validate.BillProv(billProv,strb);
			//treatProv
			if(treatProv.LName=="") {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Treating Prov LName");
			}
			if(treatProv.FName=="") {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Treating Prov FName");
			}
			//Treating prov SSN/TIN is not sent on paper or eclaims. Do not verify or block.
			if(!Regex.IsMatch(treatProv.NationalProvID,"^(80840)?[0-9]{10}$")) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Treating Prov NPI must be a 10 digit number with an optional prefix of 80840");
			}
			if(treatProv.TaxonomyCodeOverride.Length>0 && treatProv.TaxonomyCodeOverride.Length!=10) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Treating Prov Taxonomy Code must be 10 characters");
			}
			if(treatProv.StateLicense=="") {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Treating Prov Lic #");
			}
			if(PrefC.GetString(PrefName.PracticeTitle)=="") {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Practice Title");
			}
			if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
				X12Validate.BillingAddress(strb);
			}
			else if(clinic==null) {
				X12Validate.PracticeAddress(strb);
			}
			else {
				X12Validate.Clinic(clinic,strb);
			}
			if(!sub.ReleaseInfo) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("InsPlan Release of Info");
			}
			Carrier carrier=Carriers.GetCarrier(insPlan.CarrierNum);
			X12Validate.Carrier(carrier,strb);
			ElectID electID=ElectIDs.GetID(carrier.ElectID);
			if(electID!=null && electID.IsMedicaid && billProv.MedicaidID=="") {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("BillProv Medicaid ID");
			}
			Patient patient=Patients.GetPat(claim.PatNum);
			if(claim.PlanNum2>0) {
				InsPlan insPlan2=InsPlans.GetPlan(claim.PlanNum2,new List<InsPlan>());
				InsSub sub2=InsSubs.GetSub(claim.InsSubNum2,null);
				if(sub2.SubscriberID.Length<2) {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append("Other Insurance SubscriberID");
				}
				Patient subscriber2=Patients.GetPat(sub2.Subscriber); //Always exists because validated in UI.
				if(subscriber2.Birthdate.Year<1880) {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append("Other Insurance Subscriber Birthdate");
				}
				if(subscriber2.PatNum!=patient.PatNum) {//Patient address is validated below, so we only need to check if subscriber is not the patient.
					X12Validate.Subscriber2(subscriber2,strb);
				}
				Carrier carrier2=Carriers.GetCarrier(insPlan2.CarrierNum);
				if(carrier2.Address.Trim()=="") {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append("Other Insurance Carrier Address");
				}
				if(carrier2.City.Trim().Length<2) {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append("Other Insurance Carrier City");
				}
				if(carrier2.State.Trim().Length!=2) {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append("Other Insurance Carrier State(2 char)");
				}
				if(!Regex.IsMatch(carrier2.Zip.Trim(),"^[0-9]{5}\\-?([0-9]{4})?$")) {//#####, or #####-, or #####-####, or #########. Dashes are removed when X12 is generated.
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append("Other Insurance Carrier Zip");
				}
				if(claim.PatNum != sub2.Subscriber//if patient is not subscriber
					&& claim.PatRelat2==Relat.Self) {//and relat is self
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append("Other Insurance Relationship");
				}
			}
			else { //other insurance not specified
				if(claim.ClaimType=="S") {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append("Secondary claim missing other insurance");
				}
			}
			//Provider Idents:
			/*ProviderSupplementalID[] providerIdents=ElectIDs.GetRequiredIdents(carrier.ElectID);
				//No longer any required supplemental IDs
			for(int i=0;i<providerIdents.Length;i++){
				if(!ProviderIdents.IdentExists(providerIdents[i],billProv.ProvNum,carrier.ElectID)){
					if(retVal!="")
						strb.Append(",";
					strb.Append("Billing Prov Supplemental ID:"+providerIdents[i].ToString();
				}
			}*/
			if(sub.SubscriberID.Length<2) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("SubscriberID");
			}
			Patient subscriber=Patients.GetPat(sub.Subscriber);
			//We do not need to validate subscriber DOB, because the date '01/01/1900' will be sent above if the DOB is before the year 1900.
			if(subscriber.PatNum!=patient.PatNum) {//Patient address is validated below, so we only need to check if subscriber is not the patient.
				X12Validate.Subscriber(subscriber,strb);
			}
			if(claim.PatNum != sub.Subscriber//if patient is not subscriber
				&& claim.PatRelat==Relat.Self) {//and relat is self
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Claim Relationship");
			}
			if(patient.Address.Trim()=="") {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Patient Address");
			}
			if(patient.City.Trim().Length<2) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Patient City");
			}
			if(patient.State.Trim().Length!=2) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Patient State");
			}
			if(!Regex.IsMatch(patient.Zip.Trim(),"^[0-9]{5}\\-?([0-9]{4})?$")) {//#####, or #####-, or #####-####, or #########. Dashes are removed when X12 is generated.
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Patient Zip");
			}
			if(patient.Birthdate.Year<1880) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Patient Birthdate");
			}
			if(claim.AccidentRelated=="A" && claim.AccidentST.Length!=2) {//auto accident with no state
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Auto accident State");
			}
			/*if(clearhouse.ISA08=="113504607" && claim.Attachments.Count>0) {//If Tesia and has attachments
				string storedFile;
				for(int c=0;c<claim.Attachments.Count;c++) {
					storedFile=ODFileUtils.CombinePaths(FormEmailMessageEdit.GetAttachPath(),claim.Attachments[c].ActualFileName);
					if(!File.Exists(storedFile)){
						if(retVal!="")
							strb.Append(",";
						strb.Append("attachments missing";
						break;
					}
				}
			}*/
			//Warning if attachments are listed as Mail even though we are sending electronically.
			bool pwkNeeded=false;
			if(claim.AttachedFlags!="Mail") {//in other words, if there are additional flags.
				pwkNeeded=true;
			}
			if(claim.Radiographs>0 || claim.AttachedImages>0 || claim.AttachedModels>0) {
				pwkNeeded=true;
			}
			if(claim.AttachedFlags.Contains("Mail") && pwkNeeded) {
				if(warning!="")
					warning+=",";
				warning+="Attachments set to Mail";
			}
			//Warning if any PWK segments are needed, and there is no ID code.
			if(pwkNeeded && claim.AttachmentID=="") {
				if(warning!="")
					warning+=",";
				warning+="Attachment ID missing";
			}
			//List<ClaimProc> claimProcList=ClaimProcs.Refresh(patient.PatNum);
			//List<ClaimProc> claimProcs=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
			//List<Procedure> procList=Procedures.Refresh(claim.PatNum);
			List<ClaimProc> claimProcList=ClaimProcs.RefreshForClaim(claim.ClaimNum);
			List<ClaimProc> claimProcs=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
			if(claimProcs.Count==0) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("No procedures attached please recreate claim");
			}
			if(claimProcs.Count>50) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("More than 50 procedures create multiple claims instead");
			}
			List<Procedure> procList=Procedures.GetProcsFromClaimProcs(claimProcs);
			Procedure proc;
			ProcedureCode procCode;
			bool princDiagExists=false;
			for(int i=0;i<claimProcs.Count;i++) {
				proc=Procedures.GetProcFromList(procList,claimProcs[i].ProcNum);
				procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
				if(procCode.TreatArea==TreatmentArea.Arch && proc.Surf=="") {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append(procCode.AbbrDesc+" missing arch");
				}
				if(procCode.TreatArea==TreatmentArea.ToothRange && proc.ToothRange=="") {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append(procCode.AbbrDesc+" tooth range");
				}
				if((procCode.TreatArea==TreatmentArea.Tooth || procCode.TreatArea==TreatmentArea.Surf)
					&& !Tooth.IsValidDB(proc.ToothNum)) {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append(procCode.AbbrDesc+" tooth number");
				}
				if(procCode.TreatArea==TreatmentArea.Surf && proc.Surf=="") {
					if(strb.Length!=0) {
						strb.Append(",");
					}
					strb.Append(procCode.AbbrDesc+" surface missing");
				}
				if(procCode.IsProsth) {
					if(proc.Prosthesis=="") {//they didn't enter whether Initial or Replacement
						if(strb.Length!=0) {
							strb.Append(",");
						}
						strb.Append("procedure "+procCode.ProcCode+" must indicate prosthesis Initial or Replacement");
					}
					if(proc.Prosthesis=="R"
						&& proc.DateOriginalProsth.Year<1880) {//if a replacement, they didn't enter a date
						if(strb.Length!=0) {
							strb.Append(",");
						}
						strb.Append("procedure "+procCode.ProcCode+" must indicate prosthesis Original Date");
					}
				}
				//if(proc.PlaceService!=claim.PlaceService) {
				//  if(strb.Length!=0) {
				//    strb.Append(",");
				//  }
				//  strb.Append("Proc place of service does not match claim "+procCode.ProcCode);
				//}
				if(insPlan.IsMedical) {
					if(proc.DiagnosticCode=="") {
						if(strb.Length!=0) {
							strb.Append(",");
						}
						strb.Append("Procedure Diagnosis");
					}
					if(proc.IsPrincDiag && proc.DiagnosticCode!="") {
						princDiagExists=true;
					}
				}
				if(claim.ProvTreat!=proc.ProvNum && PrefC.GetBool(PrefName.EclaimsSeparateTreatProv)) {
					treatProv=listProvs[Providers.GetIndexLong(proc.ProvNum,listProvs)];
					if(treatProv.LName=="") {
						if(strb.Length!=0) {
							strb.Append(",");
						}
						strb.Append("Treating Prov LName");
					}
					if(treatProv.FName=="") {
						if(strb.Length!=0) {
							strb.Append(",");
						}
						strb.Append("Treating Prov FName");
					}
					//Treating prov SSN/TIN is not sent on paper or eclaims. Do not verify or block.
					if(treatProv.NationalProvID.Length<2) {
						if(strb.Length!=0) {
							strb.Append(",");
						}
						strb.Append("Treating Prov NPI");
					}
					if(treatProv.TaxonomyCodeOverride.Length>0 && treatProv.TaxonomyCodeOverride.Length!=10) {
						if(strb.Length!=0) {
							strb.Append(",");
						}
						strb.Append("Treating Prov Taxonomy Code for proc "+procCode.ProcCode+" must be 10 characters");
					}
					if(treatProv.StateLicense=="") {
						if(strb.Length!=0) {
							strb.Append(",");
						}
						strb.Append("Treating Prov Lic #");
					}
					//will add any other checks as needed. Can't think of any others at the moment.
				}
			}//for int i claimProcs
			if(insPlan.IsMedical && !princDiagExists) {
				if(strb.Length!=0) {
					strb.Append(",");
				}
				strb.Append("Princ Diagnosis");
			}

			/*
						if(==""){
							if(strb.Length!=0) {
								strb.Append(",");
							}
							strb.Append("";
						}*/

			//return strb.ToString();
			queueItem.Warnings=warning;
			queueItem.MissingData=strb.ToString();
		}