Пример #1
0
		private static string Run(int scriptNum,bool version2,bool sendToItrans,Carrier carrier,out List <Etrans> etransRequests) { 
			string retVal="";
			Provider prov=Providers.GetProv(PrefC.GetLong(PrefName.PracticeDefaultProv));
			etransRequests=CanadianOutput.GetOutstandingTransactions(version2,sendToItrans,carrier,prov);
			retVal+="Outstanding Transactions#"+scriptNum.ToString()+" successful.\r\n";
			return retVal;
		}
		private void butOK_Click(object sender,EventArgs e) {
			if(!checkGetForAllCarriers.Checked) {
				if(listCarriers.SelectedIndex<0 && listNetworks.SelectedIndex<0) {
					MsgBox.Show(this,"You must first choose one carrier or one network.");
					return;
				}
			}
			if(listTreatingProvider.SelectedIndex<0) {
				MsgBox.Show(this,"You must first choose a treating provider.");
				return;
			}
			DateTime reconciliationDate;
			try {
				reconciliationDate=DateTime.Parse(textDateReconciliation.Text).Date;
			}
			catch {
				MsgBox.Show(this,"Reconciliation date invalid.");
				return;
			}
			Cursor=Cursors.WaitCursor;
			try {
				if(checkGetForAllCarriers.Checked) {
					Carrier carrier=new Carrier();
					carrier.CDAnetVersion="04";
					carrier.ElectID="999999";//The whole ITRANS network.
					carrier.CanadianEncryptionMethod=1;//No encryption.
					CanadianOutput.GetSummaryReconciliation(carrier,null,ProviderC.ListShort[listTreatingProvider.SelectedIndex],reconciliationDate);
				}
				else {
					if(listCarriers.SelectedIndex>=0) {
						CanadianOutput.GetSummaryReconciliation(carriers[listCarriers.SelectedIndex],null,ProviderC.ListShort[listTreatingProvider.SelectedIndex],reconciliationDate);
					}
					else {
						CanadianOutput.GetSummaryReconciliation(null,CanadianNetworks.Listt[listNetworks.SelectedIndex],ProviderC.ListShort[listTreatingProvider.SelectedIndex],reconciliationDate);
					}
				}
				Cursor=Cursors.Default;
				MsgBox.Show(this,"Done.");
			}
			catch(Exception ex) {
				Cursor=Cursors.Default;
				MessageBox.Show(Lan.g(this,"Request failed: ")+ex.Message);
			}			
			DialogResult=DialogResult.OK;
		}
Пример #3
0
		///<summary>StringBuilder does not get altered if no invalid data.</summary>
		public static void Carrier(Carrier carrier,StringBuilder strb) {
			if(carrier.Address.Trim()=="") {
				Comma(strb);
				strb.Append("Carrier Address");
			}
			if(carrier.City.Trim().Length<2) {
				Comma(strb);
				strb.Append("Carrier City");
			}
			if(carrier.State.Trim().Length!=2) {
				Comma(strb);
				strb.Append("Carrier State(2 char)");
			}
			if(!Regex.IsMatch(carrier.Zip.Trim(),"^[0-9]{5}\\-?([0-9]{4})?$")) {//#####, or #####-, or #####-####, or #########. Dashes are removed when X12 is generated.
				Comma(strb);
				strb.Append("Carrier Zip");
			}
		}
Пример #4
0
		///<summary>StringBuilder does not get altered if no invalid data.</summary>
		public static void Carrier(Carrier carrier,StringBuilder strb) {
			if(carrier.Address.Trim()=="") {
				Comma(strb);
				strb.Append("Carrier Address");
			}
			if(carrier.City.Trim().Length<2) {
				Comma(strb);
				strb.Append("Carrier City");
			}
			if(carrier.State.Trim().Length!=2) {
				Comma(strb);
				strb.Append("Carrier State(2 char)");
			}
			if(carrier.Zip.Trim().Length<3) {
				Comma(strb);
				strb.Append("Carrier Zip");
			}
		}
Пример #5
0
 private void butAdd_Click(object sender, System.EventArgs e)
 {
     FormCarrierEdit FormCE=new FormCarrierEdit();
     FormCE.IsNew=true;
     Carrier carrier=new Carrier();
     if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
         carrier.IsCDA=true;
     }
     FormCE.CarrierCur=new Carrier();
     FormCE.ShowDialog();
     if(FormCE.DialogResult!=DialogResult.OK){
         return;
     }
     changed=true;
     FillGrid();
     for(int i=0;i<table.Rows.Count;i++){
         if(FormCE.CarrierCur.CarrierNum.ToString()==table.Rows[i]["CarrierNum"].ToString()){
             gridMain.SetSelected(i,true);
         }
     }
 }
Пример #6
0
		private static void WriteFunctionalGroup(StreamWriter sw,List<ClaimSendQueueItem> queueItems,int batchNum,Clearinghouse clearhouse,EnumClaimMedType medType) {
			#region Functional Group Header
			int transactionNum=1;//Gets incremented for each carrier. Can be reused in other functional groups and interchanges, so not persisted
			//Functional Group Header
			string groupControlNumber=batchNum.ToString();//Must be unique within file.  We will use batchNum
			string industryIdentifierCode="";
			if(medType==EnumClaimMedType.Medical) {
				industryIdentifierCode="005010X222A1";
			}
			else if(medType==EnumClaimMedType.Institutional) {
				industryIdentifierCode="005010X223A2";
			}
			else if(medType==EnumClaimMedType.Dental) {
				industryIdentifierCode="005010X224A2";
			}
			sw.Write("GS"+s
				+"HC"+s//GS01 2/2 Functional Identifier Code: Health Care Claim.
				+X12Generator.GetGS02(clearhouse)+s//GS02 2/15 Application Sender's Code: Sometimes Jordan Sparks.  Sometimes the sending clinic.
				+Sout(clearhouse.GS03,15,2)+s//GS03 2/15 Application Receiver's Code:
				+DateTime.Today.ToString("yyyyMMdd")+s//GS04 8/8 Date: today's date.
				+DateTime.Now.ToString("HHmm")+s//GS05 4/8 TIME: current time.
				+groupControlNumber+s//GS06 1/9 Group Control Number: No padding necessary.
				+"X"+s//GS07 1/2 Responsible Agency Code: X=Accredited Standards Committee X12.
				+industryIdentifierCode//GS08 1/12 Version/Release/Industry Identifier Code:
				+endSegment);
			#endregion Functional Group Header
			#region Define Variables
			int HLcount=1;
			int parentProv=0;//the HL sequence # of the current provider.
			int parentSubsc=0;//the HL sequence # of the current subscriber.
			string hasSubord="";//0 if no subordinate, 1 if at least one subordinate
			Claim claim;
			InsPlan insPlan;
			InsPlan otherPlan=null;
			InsSub sub;
			InsSub otherSub=new InsSub();
			Patient patient;
			Patient subscriber;
			Patient otherSubsc=new Patient();
			Carrier carrier;
			Carrier otherCarrier=new Carrier();
			List<ClaimProc> claimProcList;//all claimProcs for a patient.
			List<ClaimProc> claimProcs;
			List<Procedure> procList;
			List<ToothInitial> initialList;
			List<PatPlan> patPlans;
			Procedure proc;
			ProcedureCode procCode;
			Provider provTreat;//claim level treating provider.
			Provider billProv=null;
			Clinic clinic=null;
			seg=0;
			#endregion Define Variables
			#region Transaction Set Header
			//if(i==0//if this is the first claim
			//	|| claimItems[i].PayorId0 != claimItems[i-1].PayorId0)//or the payorID has changed
			//{
			//	newTrans=true;
			//	seg=0;
			//}
			//else newTrans=false;
			//if(newTrans) {
			//Transaction Set Header (one for each carrier)
			//transactionNum gets incremented in SE section
			//ST02 Transact. control #. Must be unique within ISA
			//NO: So we used combination of transaction and group, eg 00011
			sw.Write("ST"+s
				+"837"+s//ST01 3/3 Transaction Set Identifier Code: 
				+transactionNum.ToString().PadLeft(4,'0')+s//ST02 4/9 Transaction Set Control Number: 
				+industryIdentifierCode);//ST03 1/35 Implementation Convention Reference:
			EndSegment(sw);
			sw.Write("BHT"+s
				+"0019"+s//BHT01 4/4 Hierarchical Structure Code: 0019=Information Source, Subscriber, Dependant.
				+"00"+s//BHT02 2/2 Transaction Set Purpose Code: 00=Original transmissions are transmissions which have never been sent to the reciever.
				+transactionNum.ToString().PadLeft(4,'0')+s//BHT03 1/50 Reference Identification: Can be same as ST02.
				+DateTime.Now.ToString("yyyyMMdd")+s//BHT04 8/8 Date: 
				+DateTime.Now.ToString("HHmmss")+s//BHT05 4/8 Time: 
				+"CH");//BHT06 2/2 Transaction Type Code: CH=Chargable.
			EndSegment(sw);
			//1000A Submitter is OPEN DENTAL and sometimes it's the practice
			//(depends on clearinghouse and Partnership agreements)
			//See 2010AA PER (after REF) for the new billing provider contact phone number
			//1000A NM1: 41 (medical,institutional,dental) Submitter Name.
			Write1000A_NM1(sw,clearhouse);
			//1000A PER: IC (medical,institutional,dental) Submitter EDI Contact Information. Contact number.
			Write1000A_PER(sw,clearhouse);
			//1000B NM1: 40 (medical,institutional,dental) Receiver Name. Always the Clearinghouse.
			sw.Write("NM1"+s
				+"40"+s//NM101 2/3 Entity Identifier Code: 40=Receiver.
				+"2"+s);//NM102 1/1 Entity Type Qualifier: 2=Non-Person Entity.
			if(IsClaimConnect(clearhouse)) {
				sw.Write("CLAIMCONNECT"+s);//NM103 1/60 Name Last or Organization Name: Receiver Name.
			}
			else if(IsDentiCal(clearhouse)) {
				sw.Write("DENTICAL"+s);//NM103 1/60 Name Last or Organization Name: Receiver Name.
			}
			else {
				sw.Write(Sout(clearhouse.Description,60)+s);//NM103 1/60 Name Last or Organization Name: Receiver Name.
			}
			sw.Write(s//NM104 1/35 Name First: Not Used.
				+s//NM105 1/25 Name Middle: Not Used.
				+s//NM106 1/10 Name Prefix: Not Used.
				+s//NM107 1/10 Name Suffix: Not Used.
				+"46"+s);//NM108 1/2 Identification Code Qualifier: 46=Electronic Transmitter Identification Number (ETIN).
			if(IsDentiCal(clearhouse)) {
				sw.Write("1941461312");//NM109 2/80 Identification Code: Receiver ID Code. aka ETIN#.
			}
			else {
				sw.Write(Sout(clearhouse.ISA08,80,2));//NM109 2/80 Identification Code: Receiver ID Code. aka ETIN#.
			}
			EndSegment(sw);//NM110 through NM112 are not used.
			HLcount=1;
			parentProv=0;//the HL sequence # of the current provider.
			parentSubsc=0;//the HL sequence # of the current subscriber.
			hasSubord="";//0 if no subordinate, 1 if at least one subordinate
			//}
			#endregion
			for(int i=0;i<queueItems.Count;i++) {
				#region Initialize Variables
				claim=Claims.GetClaim(queueItems[i].ClaimNum);
				insPlan=InsPlans.GetPlan(claim.PlanNum,new List<InsPlan>());
				sub=InsSubs.GetSub(claim.InsSubNum,null);
				//insPlan could be null if db corruption. No error checking for that
				otherPlan=null;//Must be reset each time through because if otherPlan!=null below then we assume the current claim has a secondary plan.
				if(claim.PlanNum2>0) {
					otherPlan=InsPlans.GetPlan(claim.PlanNum2,new List<InsPlan>());
					otherSub=InsSubs.GetSub(claim.InsSubNum2,null);
					otherSubsc=Patients.GetPat(otherSub.Subscriber);
					otherCarrier=Carriers.GetCarrier(otherPlan.CarrierNum);
				}
				patient=Patients.GetPat(claim.PatNum);
				subscriber=Patients.GetPat(sub.Subscriber);
				carrier=Carriers.GetCarrier(insPlan.CarrierNum);
				claimProcList=ClaimProcs.Refresh(patient.PatNum);
				claimProcs=ClaimProcs.GetForSendClaim(claimProcList,claim.ClaimNum);
				procList=Procedures.Refresh(claim.PatNum);
				initialList=ToothInitials.Refresh(claim.PatNum);
				patPlans=PatPlans.Refresh(patient.PatNum);
				#endregion Initialize Variables
				#region Billing Provider
				//Billing address is based on clinic, not provider.  All claims in a batch are guaranteed to be from a single clinic.  That validation is done in FormClaimSend.
				//Although, now that we have a separate loop for each claim, we might be able to allow a batch with mixed clinics.
				if(!PrefC.GetBool(PrefName.EasyNoClinics)) {//if using clinics
					clinic=Clinics.GetClinic(claim.ClinicNum);//might be null
				}
				//2000A HL: (medical,instituational,dental) Billing Provider Hierarchical Level.
				sw.Write("HL"+s+HLcount.ToString()+s//HL01 1/12 Heirarchical ID Number: 
					+s//HL02 1/12 Hierarchical Parent ID Number: Not used.
					+"20"+s//HL03 1/2 Heirarchical Level Code: 20=Information Source.
					+"1");//HL04 1/1 Heirarchical Child Code. 1=Additional Subordinate HL Data Segment in This Hierarchical Structure.
				EndSegment(sw);
				//billProv=ProviderC.ListLong[Providers.GetIndexLong(claimItems[i].ProvBill1)];
				billProv=Providers.GetProv(claim.ProvBill);
				//2000A PRV: BI (medical,institutional,dental) Billing Provider Specialty Information. Situational. Required when billing provider is treating provider.
				bool usePrvBilling=false;
				if(claim.ProvBill==claim.ProvTreat) {
					usePrvBilling=true;
				}
				if(IsWashingtonMedicaid(clearhouse,carrier)) {
					usePrvBilling=true;
				}
				if(usePrvBilling) {
					sw.Write("PRV"+s
						+"BI"+s//PRV01 1/3 Provider Code: BI=Billing.
						+"PXC"+s//PRV02 2/3 Reference Identification Qualifier: PXC=Health Care Provider Taxonomy Code.
						+X12Generator.GetTaxonomy(billProv));//PRV03 1/50 Reference Identification: Provider Taxonomy Code.
					EndSegment(sw);//PRV04 through PRV06 are not used.
				}
				//2000A CUR: (medical,instituational,dental) Foreign Currency Information. Situational. We do not need to specify because united states dollars are default.
				//2010AA NM1: 85 (medical,institutional,dental) Billing Provider Name.
				if(medType==EnumClaimMedType.Institutional) {
					billProv.IsNotPerson=true;//Required by X12 specification. Cannot send a person as the billing provider.
				}
				WriteNM1Provider("85",sw,billProv);
				//2010AA N3: (medical,institutional,dental) Billing Provider Address.
				string billingAddress1="";
				string billingAddress2="";
				string billingCity="";
				string billingState="";
				string billingZip="";
				if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
					billingAddress1=PrefC.GetString(PrefName.PracticeBillingAddress);
					billingAddress2=PrefC.GetString(PrefName.PracticeBillingAddress2);
					billingCity=PrefC.GetString(PrefName.PracticeBillingCity);
					billingState=PrefC.GetString(PrefName.PracticeBillingST);
					billingZip=PrefC.GetString(PrefName.PracticeBillingZip);
				}
				else if(clinic==null) {
					billingAddress1=PrefC.GetString(PrefName.PracticeAddress);
					billingAddress2=PrefC.GetString(PrefName.PracticeAddress2);
					billingCity=PrefC.GetString(PrefName.PracticeCity);
					billingState=PrefC.GetString(PrefName.PracticeST);
					billingZip=PrefC.GetString(PrefName.PracticeZip);
				}
				else {
					billingAddress1=clinic.Address;
					billingAddress2=clinic.Address2;
					billingCity=clinic.City;
					billingState=clinic.State;
					billingZip=clinic.Zip;
				}
				sw.Write("N3"+s+Sout(billingAddress1,55));//N301 1/55 Address Information:
				if(billingAddress2!="") {
					sw.Write(s+Sout(billingAddress2,55));//N302 1/55 Address Information:
				}
				EndSegment(sw);
				//2010AA N4: (medical,institutional,dental) Billing Provider City, State, Zip Code.
				sw.Write("N4"+s+Sout(billingCity,30)+s//N401 2/30 City Name: 
					+Sout(billingState,2,2)+s//N402 2/2 State or Province Code: 
					+Sout(billingZip.Replace("-",""),15));//N403 3/15 Postal Code: 
				EndSegment(sw);//NM404 through NM407 are either situational with United States as default, or not used, so we don't specify any of them.
				//2010AA REF: EI (medical,institutional,dental) Billing Provider Tax Identification.
				sw.Write("REF"+s);
				if(medType==EnumClaimMedType.Medical) {
					sw.Write((billProv.UsingTIN?"EI":"SY")+s);//REF01 2/3 Reference Identification Qualifier: EI=Employer's Identification Number (EIN). SY=Social Security Number (SSN).
				}
				else if(medType==EnumClaimMedType.Institutional) {
					sw.Write("EI"+s);//REF01 2/3 Reference Identification Qualifier: EI=Employer's Identification Number (EIN).
				}
				else if(medType==EnumClaimMedType.Dental) {
					sw.Write((billProv.UsingTIN?"EI":"SY")+s);//REF01 2/3 Reference Identification Qualifier: EI=Employer's Identification Number (EIN). SY=Social Security Number (SSN).
				}
				sw.Write(Sout(billProv.SSN,50));//REF02 1/50 Reference Identification. Tax ID #.
				EndSegment(sw);//REF03 and REF04 are not used.
				if(medType==EnumClaimMedType.Medical || medType==EnumClaimMedType.Dental) {
					//2010AA REF: (medical,dental) Billing Provider UIPN/License Information: Situational. We do not use. Max repeat 2.
				}
				if(medType==EnumClaimMedType.Dental) {
					//2010AA REF: (dental) State License Number: Required by RECS and Emdeon clearinghouses. We do NOT validate that it's entered because sending it with non-persons causes problems.
					//if(IsEmdeonDental(clearhouse) || clearhouse.CommBridge==EclaimsCommBridge.RECS) {
					if(!IsDentiCal(clearhouse)) { //Denti-Cal never wants this.
						if(billProv.StateLicense!="") {
							sw.Write("REF"+s
								+"0B"+s//REF01 2/3 Reference Identification Qualifier: 0B=State License Number.
								+Sout(billProv.StateLicense,50));//REF02 1/50 Reference Identification: 
							EndSegment(sw);//REF03 and REF04 are not used.
						}
					}
					//2010AA REF G5 (dental) Site Identification Number: NOT IN X12 5010 STANDARD DOCUMENTATION. Only required by Emdeon.
					if(IsEmdeonDental(clearhouse)) {
						Write2010AASiteIDforEmdeon(sw,billProv,carrier.ElectID);
					}
				}
				//2010AA PER: IC (medical,institutional,dental) Billing Provider Contact Information: Probably required by a number of carriers and by Emdeon.
				sw.Write("PER"+s
					+"IC"+s//PER01 2/2 Contact Function Code: IC=Information Contact.
					+Sout(PrefC.GetString(PrefName.PracticeTitle),60)+s//PER02 1/60 Name: Practice Title.
					+"TE"+s);//PER03 2/2 Communication Number Qualifier: TE=Telephone.
				if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
					sw.Write(Sout(PrefC.GetString(PrefName.PracticePhone),256));//PER04  1/256 Communication Number: Telephone number.
				}
				else if(clinic==null){
					sw.Write(Sout(PrefC.GetString(PrefName.PracticePhone),256));//PER04  1/256 Communication Number: Telephone number.
				}
				else{
					sw.Write(Sout(clinic.Phone,256));//PER04  1/256 Communication Number: Telephone number.
				}
				EndSegment(sw);//PER05 through PER08 are situational and PER09 is not used. We do not use.
				if(PrefC.GetString(PrefName.PracticePayToAddress)!="") {
					//2010AB NM1: 87 (medical,institutional,dental) Pay-To Address Name.
					sw.Write("NM1"+
						s+"87"+s);//NM101 2/3 Entity Identifier Code: 87=Pay-to Provider.
					if(medType==EnumClaimMedType.Institutional) {
						sw.Write("2");//NM102 1/1 Entity Type Qualifier: 2=Non-Person Entity.
					}
					else { //(medical,dental)
						sw.Write((billProv.IsNotPerson?"2":"1"));//NM102 1/1 Entity Type Qualifier: 1=Person, 2=Non-Person Entity.
					}
					EndSegment(sw);//NM103 through NM112 are not used.
					//2010AB N3: (medical,institutional,dental) Pay-To Address.
					sw.Write("N3"+s+Sout(PrefC.GetString(PrefName.PracticePayToAddress),55));//N301 1/55 Address Information:
					if(PrefC.GetString(PrefName.PracticePayToAddress2)!="") {
						sw.Write(s+Sout(PrefC.GetString(PrefName.PracticePayToAddress2),55));//N302 1/55 Address Information:
					}
					EndSegment(sw);
					//2010AB N4: (medical,institutional,dental) Pay-To Address City, State, Zip Code.
					sw.Write("N4"+s+Sout(PrefC.GetString(PrefName.PracticePayToCity),30)+s//N401 2/30 City Name: 
						+Sout(PrefC.GetString(PrefName.PracticePayToST),2,2)+s//N402 2/2 State or Province Code: 
						+Sout(PrefC.GetString(PrefName.PracticePayToZip).Replace("-",""),15));//N403 3/15 Postal Code: 
					EndSegment(sw);//NM404 through NM407 are either situational with United States as default, or not used, so we don't specify any of them.
				}
				//2010AC NM1: 98 (medical,institutional,dental) Pay-To Plan Name. We do not use.
				//2010AC N3: (medical,institutional,dental) Pay-To Plan Address. We do not use.
				//2010AC N4: (medical,institutional,dental) Pay-To Plan City, State, Zip Code. We do not use.
				//2010AC REF: (medical,institutional,dental) Pay-To Plan Secondary Identification. We do not use.
				//2010AC REF: (medical,institutional,dental) Pay-To Plan Tax Identification Number. We do not use.
				parentProv=HLcount;
				HLcount++;
				#endregion Billing Provider
				#region Attachments
				/*if(IsTesia(clearhouse) && claim.Attachments.Count>0){//If Tesia and has attachments
					claim.ClaimNote="TESIA#"+claim.ClaimNum.ToString()+" "+claim.ClaimNote;
					string saveFolder=clearhouse.ExportPath;//we've already tested to make sure this exists.
					string saveFile;
					string storedFile;
					for(int c=0;c<claim.Attachments.Count;c++){
						saveFile=ODFileUtils.CombinePaths(saveFolder,
							claim.ClaimNum.ToString()+"_"+(c+1).ToString()+Path.GetExtension(claim.Attachments[c].DisplayedFileName)+".IMG");
						storedFile=ODFileUtils.CombinePaths(FormEmailMessageEdit.GetAttachPath(),claim.Attachments[c].ActualFileName);
						File.Clone(storedFile,saveFile,true);
					}					
				}*/
				#endregion
				#region Subscriber
				if(patient.PatNum==subscriber.PatNum){//if patient is the subscriber
					hasSubord="0";//-claim level will follow
					//subordinate patients will not follow in this loop.  The subscriber loop will be duplicated for them.
				}
				else {//patient is not the subscriber
					hasSubord="1";//-patient will always follow
				}
				//2000B HL: (medical,institutional,dental) Subscriber Hierarchical Level.
				sw.Write("HL"+s+HLcount.ToString()+s//HL01 1/12 Hierarchical ID Number:
					+parentProv.ToString()+s//HL02 1/12 Hierarchical Parent ID Number: parent HL is always the billing provider HL.
					+"22"+s//HL03 1/2 Hierarchical Level Code: 22=Subscriber.
					+hasSubord);//HL04 1/1 Hierarchical Child Code: 0=No subordinate HL segment in this hierarchical structure. 1=Additional subordinate HL data segment in this hierarchical structure.
				EndSegment(sw);
				//2000B SBR: (medical,institutional,dental) Subscriber Information.
				sw.Write("SBR"+s);
				bool claimIsPrimary=true;//we currently support only primary and secondary.  Plan2, if present, must be the opposite.
				if(claim.ClaimType=="PreAuth") {
					if(otherPlan!=null && PatPlans.GetOrdinal(claim.InsSubNum2,patPlans) < PatPlans.GetOrdinal(claim.InsSubNum,patPlans)) { //When there are two plans and the secondary plan is in the primary ins position.
						claimIsPrimary=false;
					}
				}
				else if(otherPlan!=null && (otherPlan.IsMedical || insPlan.IsMedical)) { //When there are two plans and at least one plan is medical.
					if(PatPlans.GetOrdinal(claim.InsSubNum2,patPlans) < PatPlans.GetOrdinal(claim.InsSubNum,patPlans)) { //The insurance plan order is determined by patplan.ordinal
						claimIsPrimary=false;
					}
				}
				else if(claim.ClaimType=="P") {
				}
				else if(claim.ClaimType=="S") { //Verification ensures that there are two plans associated with the claim in this case.
					claimIsPrimary=false;
				}
				else if(claim.ClaimType=="Other") { //Also used for a medical claim with only one insurance.
					//We always send medical plans as primary.  They are totally separate from the ordinals for dental.
				}
				else if(claim.ClaimType=="Cap") {
					//All captication claims are treated as primary claims.
					//todo: is secondary capitation possible?
				}
				sw.Write((claimIsPrimary?"P":"S")+s);//SBR01 1/1 Payer Responsibility Sequence Number Code: 
				string relationshipCode="";//empty if patient is not subscriber.
				if(patient.PatNum==subscriber.PatNum) {//if patient is the subscriber
					relationshipCode="18";
				}
				sw.Write(relationshipCode+s//SBR02 2/2 Individual Relationship Code: 18=Self (The only option besides blank).
					+Sout(insPlan.GroupNum,50)+s);//SBR03 1/50 Reference Identification: Does not need to be validated because group number is optional.
				//SBR04 1/60 Name: Situational. Required when SBR03 is not used. Does not need to be validated because group name is optional.
				if(insPlan.GroupNum!="") {
					sw.Write(s);
				} 
				else {
					sw.Write(Sout(insPlan.GroupName,60)+s);
				}
				sw.Write(s//SBR05 1/3 Insurance Type Code. Situational.  Skip because we don't support secondary Medicare.
					+s//SBR06 1/1 Coordination of Benefits Code: Not used.
					+s//SBR07 1/1 Yes/No Condition or Respose Code: Not used.
					+s//SBR08 2/2 Employment Status Code: Not used.
					+GetFilingCode(insPlan));//SBR09: 12=PPO,17=DMO,BL=BCBS,CI=CommercialIns,FI=FEP,HM=HMO. Will no longer be required when HIPPA National Plan ID is mandated.
				EndSegment(sw);
				if(medType==EnumClaimMedType.Medical) {
					//2000B PAT: (medical) Patient Information. Situational. Required when the patient is the subscriber or considered to be the subscriber and at least one of the element requirements are met. Element requirements include: when the patient is deceased and the date of death is available; or when the claim involves Medicare Durable Medical Equipment Regional Carriers Certificate of Medical Necessity (DMERC CMN) 02.03, 10.02, or DMA MAC 10.03; or when law requires to know if the patient is pregnant or not. We do not use, because we do not track death date, durable medical equipment information, nor do we know weather or not the patient is pregnant. Some of these fields may be necessary in the future, but not likely since our medical claims are usually pretty simple.
				}
				//2010BA NM1: IL (medical,institutional,dental) Subscriber Name.
				sw.Write("NM1"+s
					+"IL"+s//NM101 2/3 Entity Identifier Code: IL=Insured or Subscriber.
					+"1"+s//NM102 1/1 Entity Type Qualifier: 1=Person, 2=Non-Person Entity.
					+Sout(subscriber.LName,60)+s//NM103 1/60 Name Last or Organization Name: Never blank, because validated in the patient edit window when a patient is added/edited.
					+Sout(subscriber.FName,35)+s//NM104 1/35 Name First:
					+Sout(subscriber.MiddleI,25)+s//NM105 1/25 Name Middle:
					+s//NM106 1/10 Name Prefix: Not Used.
					+s//NM107 1/10 Name Suffix: Situational. Not present in Open Dental yet so we leave blank.
					+"MI"+s//NM108 1/2 Identification Code Qualifier: MI=Member Identification Number.
					+Sout(sub.SubscriberID.Replace("-",""),80,2));//NM109 2/80 Identification Code: Situational. Required when NM102=1.
				EndSegment(sw);//NM110 through NM112 are not used.
				//In 4010s, at the request of Emdeon, we always include N3,N4,and DMG even if patient is not subscriber.  This did not make the transaction non-compliant, and they found it useful.
				//In 5010s, we will follow the X12 specification for most clearinghouses and only include subsc address when subscriber=patient.
				//But for any clearinghouse who requests it, we will always include, [js 3/14/13 even when subscriber!=patient].  List them here:
				//ClaimConnect, EmdeonMed, EmdeonDent, LindsayTechnicalConsultants, OfficeAlly: Always include.
				//PostNTrack, BCBSIdaho: Only include when subscriber=patient.
				bool subscIncludeAddressAndGender=false;
				if(IsClaimConnect(clearhouse) || IsEmdeonDental(clearhouse) || IsEmdeonMedical(clearhouse) || IsLindsayTechnicalConsultants(clearhouse) || IsOfficeAlly(clearhouse)) {
					subscIncludeAddressAndGender=true;
				}
				else {//X12 standard behavior for everyone else, including: BCBSIdaho, ColoradoMedicaid, Denti-Cal, PostNTrack, WashingtonMedicaid.
					if(subscriber.PatNum==patient.PatNum) {//[js 3/14/13 only include when subscriber==patient]
						subscIncludeAddressAndGender=true;
					}
					//[js 3/14/13 when subscriber!=patient, don't include address]
				}
				if(subscIncludeAddressAndGender) {
					//2010BA N3: (medical,institutional,dental) Subscriber Address. Situational. Required when the patient is the subscriber.
					sw.Write("N3"+s+Sout(subscriber.Address,55));//N301 1/55 Address Information:
					if(subscriber.Address2!="") {
						sw.Write(s+Sout(subscriber.Address2,55));//N302 1/55 Address Information:
					}
					EndSegment(sw);
					//2010BA N4: (medical,institutional,dental) Subscriber City, State, Zip Code. Situational. Required when the patient is the subscriber.
					sw.Write("N4"+s
						+Sout(subscriber.City,30)+s//N401 2/30 City Name:
						+Sout(subscriber.State,2,2)+s//N402 2/2 State or Provice Code:
						+Sout(subscriber.Zip.Replace("-",""),15));//N403 3/15 Postal Code:
					EndSegment(sw);//N404 through N407 either not used or required for addresses outside of the United States.
					//2010BA DMG: (medical,institutional,dental) Subscriber Demographic Information. Situational. Required when the patient is the subscriber.
					//Carriers tend to complain if the BD is missing for the subscriber even though it's not strictly required.  So we will require it from users.
					sw.Write("DMG"+s
						+"D8"+s//DMG01 2/3 Date Time Period Format Qualifier: D8=Date Expressed in Format CCYYMMDD.
						+subscriber.Birthdate.ToString("yyyyMMdd")+s//DMG02 1/35 Date Time Period: Birthdate. The subscriber birtdate is validated.
						+GetGender(subscriber.Gender));//DMG03 1/1 Gender Code: F=Female, M=Male, U=Unknown.
					EndSegment(sw);
				}
				//2010BA REF: SY (medical,institutional,dental) Secondary Secondary Identification: Situational. Required when an additional identification number to that provided in NM109 of this loop is necessary. We do not use this.
				//2010BA REF: Y4 (medical,institutional,dental) Property and Casualty Claim Number: Required when the services included in this claim are to be considered as part of a property and casualty claim. We do not use this.
				//2010BA PER: IC (medical) Property and Casualty Subscriber Contact information: Situational. We do not use this.
				//2010BB NM1: PR (medical,institutional,dental) Payer Name.
				sw.Write("NM1"+s
					+"PR"+s//NM101 2/3 Entity Identifier Code: PR=Payer.
					+"2"+s);//NM102 1/1 Entity Type Qualifier: 2=Non-Person Entity.
				//NM103 1/60 Name Last or Organization Name:
				if(IsEMS(clearhouse)) {
					//This is a special situation requested by EMS.  This tacks the employer onto the end of the carrier.
					sw.Write(Sout(carrier.CarrierName,30)+"|"+Sout(Employers.GetName(insPlan.EmployerNum),30)+s);
				}
				else if(IsDentiCal(clearhouse)) {
					sw.Write("DENTICAL"+s);
				}
				else {
					sw.Write(Sout(carrier.CarrierName,60)+s);
				}
				sw.Write(s//NM104 1/35 Name First: Not used.
					+s//NM105 1/25 Name Middle: Not used.
					+s//NM106 1/10 Name Prefix: Not used.
					+s//NM107 1/10 Name Suffix: Not used.
					+"PI"+s);//NM108 1/2 Identification Code Qualifier: PI=Payor Identification.
				sw.Write(Sout(GetCarrierElectID(carrier,clearhouse),80,2));//NM109 2/80 Identification Code: PayorID.
				EndSegment(sw);//NM110 through NM112 Not Used.
				//2010BB N3: (medical,institutional,dental) Payer Address.
				sw.Write("N3"+s+Sout(carrier.Address,55));//N301 1/55 Address Information:
				if(carrier.Address2!="") {
					sw.Write(s+Sout(carrier.Address2,55));//N302 1/55 Address Information: Required when there is a second address line.
				}
				EndSegment(sw);
				//2010BB N4: (medical,institutional,dental) Payer City, State, Zip Code.
				sw.Write("N4"+s
					+Sout(carrier.City,30)+s//N401 2/30 City Name:
					+Sout(carrier.State,2)+s//N402 2/2 State or Province Code:
					+Sout(carrier.Zip.Replace("-",""),15));//N403 3/15 Postal Code:
				EndSegment(sw);//N404 through N407 are either not used or are for addresses outside of the United States.
				//2010BB REF 2U,EI,FY,NF (dental) Payer Secondary Identificaiton. Situational.
				//2010BB REF G2,LU Billing Provider Secondary Identification. Situational. Not required because we always send NPI.
				if(!IsDentiCal(clearhouse)){//DentiCal complained that they don't usually want this (except for non-subparted NPIs, which we don't handle).  So far, nobody else has complained.
					//Always required by Emdeon Dental.
					WriteProv_REFG2orLU(sw,billProv,carrier.ElectID);
				}
				parentSubsc=HLcount;
				HLcount++;
				#endregion
				#region Patient
				if(patient.PatNum!=subscriber.PatNum){//if patient is not the subscriber
					//2000C HL: (medical,institutional,dental) Patient Hierarchical Level.
					sw.Write("HL"+s+HLcount.ToString()+s//HL01 1/12 Hierarchical ID Number:
						+parentSubsc.ToString()+s//HL02 1/12 Hierarchical Parent ID Number: Parent is always the subscriber HL.
						+"23"+s//HL03 1/2 Hierarchical Level Code: 23=Dependent.
						+"0");//HL04 1/1 Hierarchical Child Code: 0=No subordinate HL segment in this hierarchical structure.
					EndSegment(sw);
					//2000C PAT: (medical,institutional,dental) Patient Information.
					if(IsEmdeonDental(clearhouse)) {
						sw.Write("PAT"+s
							+GetRelat(claim.PatRelat)+s//PAT01 2/2 Individual Relationship Code:
							+s//PAT02 1/1 Patient Location Code: Not used.
							+s//PAT03 2/2 Employment Status Code: Not used.
							+GetStudentEmdeon(patient.StudentStatus));//PAT04 1/1 Student Status Code: Not used. Emdeon wants us to sent this code corresponding to version 4010, even through it is not standard X12.
						EndSegment(sw);//PAT05 through PAT08 not used in institutional or dental, but is sometimes used in medical. We do not use.
					}
					else {
						sw.Write("PAT"+s
							+GetRelat(claim.PatRelat));//PAT01 2/2 Individual Relationship Code:
						EndSegment(sw);//PAT02 through PAT04 Not used. PAT05 through PAT08 not used in institutional or dental, but is sometimes used in medical. We do not use.
					}
					//2010CA NM1: QC (medical,institutional,dental) Patient Name.
					sw.Write("NM1"+s
						+"QC"+s//NM101 2/3 Entity Identifier Code: QC=Patient.
						+"1"+s//NM102 1/1 Entity Type Qualifier: 1=Person.
						+Sout(patient.LName,60)+s//NM103 1/60 Name Last or Organization Name:
						+Sout(patient.FName,35));//NM104 1/35 Name First: Never blank, because validated in the patient edit window when a patient is added/edited.
						if(patient.MiddleI!="") {
							sw.Write(s+Sout(patient.MiddleI,25));//NM105 1/25 Name Middle
						}
					EndSegment(sw);
					//NM106 not used. NM107, No suffix field in Open Dental. NM108 through NM112 not used.
					//2010CA N3: (medical,institutional,dental) Patient Address.
					sw.Write("N3"+s+
						Sout(patient.Address,55));//N301 1/55 Address Information
					if(patient.Address2!="") {
						sw.Write(s+Sout(patient.Address2,55));//N302 1/55 Address Information:
					}
					EndSegment(sw);
					//2010CA N4: (medical,institutional,dental) Patient City, State, Zip Code.
					sw.Write("N4"+s
						+Sout(patient.City,30)+s//N401 2/30 City Name:
						+Sout(patient.State,2,2)+s//N402 2/2 State or Provice Code: 
						+Sout(patient.Zip.Replace("-",""),15));//N403 3/15 Postal Code: 
					EndSegment(sw);//N404 through N407 are either not used or only required for addresses outside the United States.
					//2010CA DMG: (medical,institutional,dental) Patient Demographic Information.
					sw.Write("DMG"+s
						+"D8"+s//DMG01 2/3 Date Time Period Format Qualifier: D8=Date Expressed in Format CCYYMMDD.
						+patient.Birthdate.ToString("yyyyMMdd")+s//DMG02 1/35 Date Time Period:
						+GetGender(patient.Gender));//DMG03 1/1 Gender Code: F=Female,M=Male,U=Unknown.
					EndSegment(sw);//DMG04 through DMG11 are not used.
					//2010CA REF: (medical,instituional,dental) Property and Casualty Claim Number. Situational. We do not use this.
					//2010CA REF: (medical,institutional) Property and Casualty Patient Identifier. Situational.  We do not use.
					//2010CA PER: (medical) Property and Casualty Patient Contact Information. Situational. We do not use.
					HLcount++;
				}
				#endregion
				#region Claim CLM
				//2300 CLM: (medical,institutional,dental) Claim Information.
				string clm01=claim.ClaimIdentifier;//Typically PatNum/ClaimNum. Check for uniqueness is performed in UI.
				if(IsDentiCal(clearhouse)) {
					clm01=Sout(clm01,17);//Denti-Cal has a maximum of 17 chars here. This field is what Denti-Cal refers to as the PDCN.
				}
				else if(IsEmdeonMedical(clearhouse)) {
					clm01=clm01.Replace('/','-');//Emdeon Medical only allows letters, numbers, dashes, periods, spaces and asterisks. The claim identifier will contain / inside the claim edit window still.
				}
				string claimFrequencyTypeCode="1";
				if(claim.CorrectionType==ClaimCorrectionType.Original) {
					claimFrequencyTypeCode="1";
				}
				else if(claim.CorrectionType==ClaimCorrectionType.Replacement) {
					claimFrequencyTypeCode="7";
				}
				else if(claim.CorrectionType==ClaimCorrectionType.Void) {
					claimFrequencyTypeCode="8";
				}
				//the next 8 lines fix a rare bug where the total doesn't match the sum of the procs.  This would result in invalid X12
				decimal claimFeeBilled=0;
				for(int j=0;j<claimProcs.Count;j++) {
					claimFeeBilled+=(decimal)claimProcs[j].FeeBilled;
				}
				if(claimFeeBilled!=(decimal)claim.ClaimFee) {
					claim.ClaimFee=(double)claimFeeBilled;
				  Claims.Update(claim);
				}
				sw.Write("CLM"+s
					+Sout(clm01,20)+s//CLM01 1/38 Claim Submitter's Identifier: A unique id. Carriers are not required to handle more than 20 char. 
					+claimFeeBilled.ToString("f2")+s//CLM02 1/18 Monetary Amount:
					+s//CLM03 1/2 Claim Filing Indicator Code: Not used.
					+s);//CLM04 1/2 Non-Institutional Claim Type Code: Not used.
				//CLM05 (medical,institutional,dental) Health Care Services Location Information.
				if(medType==EnumClaimMedType.Medical) {
					sw.Write(GetPlaceService(claim.PlaceService)+isa16//CLM05-1 1/2  Facility Code Value: Place of Service.
						+"B"+isa16//CLM05-2 1/2 Facility Code Qualifier, B=Place of Service Codes.
						+claimFrequencyTypeCode+s);//CLM05-3 1/1 Claim Frequency Type Code: 1=original, 7=replacement, 8=void(in limited jurisdictions).
				}
				else if(medType==EnumClaimMedType.Institutional) {
					//claim.UniformBillType validated to be exactly 3 char
					//Example: 771: 7=clinic, 7=FQHC, 1=Only claim.  713: 7=clinic, 1=rural health clinic, 3=continuing claim.
					sw.Write(claim.UniformBillType.Substring(0,2)+isa16//CLM05-1 1/2  Facility Code Value: First and second position of UniformBillType.
						+"A"+isa16//CLM05-2 1/2 Facility Code Qualifier, A=Uniform Billing Claim Form Bill Type.
						+claim.UniformBillType.Substring(2,1)+s);//CLM05-3 1/1 Claim Frequency Type Code: Third position of UniformBillType.
				}
				else{//dental.
					sw.Write(GetPlaceService(claim.PlaceService)+isa16//CLM05-1 1/2  Facility Code Value: Place of Service.
						+"B"+isa16//CLM05-2 1/2 Facility Code Qualifier, B=Place of Service Codes.
						+claimFrequencyTypeCode+s);//CLM05-3 1/1 Claim Frequency Type Code: 1=original, 7=replacement, 8=void(in limited jurisdictions).
				}
				if(medType==EnumClaimMedType.Medical) {
					sw.Write("Y"+s);//CLM06 1/1 Yes/No Condition or Response Code: prov sig on file (always yes)
				}
				else if(medType==EnumClaimMedType.Institutional) {
					sw.Write(s);//CLM06 1/1 Yes/No Condition or Response Code: Not used.
				}
				else if(medType==EnumClaimMedType.Dental) {
					sw.Write("Y"+s);//CLM06 1/1 Yes/No Condition or Response Code: prov sig on file (always yes)
				}
				sw.Write("A"+s//CLM07 1/1 Provider Accept Assignment Code: Prov accepts medicaid assignment. OD has no field for this, so no choice.
					+(sub.AssignBen?"Y":"N")+s//CLM08 1/1 Yes/No Condition or Response Code: We do not support W.
					+(sub.ReleaseInfo?"Y":"I"));//CLM09 1/1 Release of Information Code: Y or I(which is equivalent to No)
				if(medType==EnumClaimMedType.Medical || medType==EnumClaimMedType.Dental) {
					if(claim.AccidentDate.Year>1880 || claim.SpecialProgramCode!=EnumClaimSpecialProgram.none || claim.ClaimType=="PreAuth") {//if val for 11,12, or 19
						sw.Write(s+s//end of CLM09. CLM10 not used
							+GetRelatedCauses(claim));//CLM11 2/3:2/3:2/3:2/2:2/3 Related Causes Information: Situational. Accident related, including state. Might be blank.
					}
					if(claim.SpecialProgramCode!=EnumClaimSpecialProgram.none || claim.ClaimType=="PreAuth") {//if val for 12, or 19
						sw.Write(s//nothing for CLM11.
							+GetSpecialProgramCode(claim.SpecialProgramCode));//CLM12 2/3 Special Program Code: Situational. Example EPSTD.
					}
					if(claim.ClaimType=="PreAuth") {//if val for 19
						sw.Write(s//nothing for CLM12.
							+s+s+s+s+s+s//CLM13-18 not used
							+"PB");//CLM19 2/2 Claim Submission Reason Code: PB=Predetermination of Benefits. TODO: Not allowed in medical claims. What is the replacement??
						//CLM20 1/2 Delay Reason Code: Situational. Required when claim is submitted late. Not supported.
					}
				}
				//CLM10-19 not used, 20 not supported for institutional.
				EndSegment(sw);
				#endregion Claim CLM
				#region Claim DTP
				if(medType==EnumClaimMedType.Medical) {
					//2300 DTP: 431 (medical) Date Onset of Current Illness or Symptom. Situational. We do not use.
					//2300 DTP: 454 (medical) Initial Treatment Date. Situational. We do not use. (spinal manipulation).
					//2300 DTP: 304 (medical) Date Last Seen. Situational. We do not use. (foot care)
					//2300 DTP: 453 (medical) Date Accute Manifestation. Situational. We do not use. (spinal manipulation)
					//2300 DTP: 439 (medical) Date Accident. Situational.
					if(claim.AccidentDate.Year>1880) {
						sw.Write("DTP"+s
							+"439"+s//DTP01 3/3 Date/Time Qualifier: 439=accident
							+"D8"+s//DTP02 2/3 Date Time Period Format Qualifer: D8=Date Expressed in Format CCYYMMDD.
							+claim.AccidentDate.ToString("yyyyMMdd"));//DTP03 1/35 Date Time Period:
						EndSegment(sw);
					}
					//2300 DTP: 484 (medical) Last Menstrual Period Date. Situational. We do not use.
					//2300 DTP: 455 (medical) Last X-ray Date. Situational. We do not use.
					//2300 DTP: 471 (medical) Hearing and Vision Prescription Date. Situational. We do not use.
					//2300 DTP: 314,360,361 (medical) Disability Dates. Situational. We do not use.
					//2300 DTP: 297 (medical) Date Last Worked. Situational. We do not use.
					//2300 DTP: 296 (medical) Date Authorized Return to Work. Situational. We do not use.
					//2300 DTP: 435 (medical) Date Admission. Situational. We do not use. Inpatient. Request #2843.
					//2300 DTP: 096 (medical) Date Discharge. Situational. We do not use. Inpatient. Request #2843.
					//2300 DTP: 090 (medical) Date Assumed and Relinquished Care Dates. Situational. We do not use.
					//2300 DTP: 444 (medical) Date Property and Casualty Date of First Contact. Situational. We do not use.
					//2300 DTP: 050 (medical) Repricer Received Date. Situational. We do not use.
				}
				else if(medType==EnumClaimMedType.Institutional) {
					//2300 DTP 096 (institutional) Discharge Hour. Situational. We do not use. Inpatient. 
					//2300 DTP 434 (instititional) Statement Dates.
//todo:how to handle preauths?
					if(claim.DateService.Year>1880) {//DateService validated
						sw.Write("DTP"+s
							+"434"+s//DTP01 3/3 Date/Time Qualifier: 434=Statement.
							+"RD8"+s//DTP02 2/3 Date Time Period Format Qualifier: RD8=Range of Dates Expressed in Format CCYYMMDD-CCYYMMDD.
							+claim.DateService.ToString("yyyyMMdd")+"-"+claim.DateService.ToString("yyyyMMdd"));//DTP03 1/35 Date Time Period:
						EndSegment(sw);
					}
					//2300 DTP 435 (institutional) Admission Date/Hour. Situational. We do not use. Inpatient.
					//For the UB04 we are using claim.DateService for this field.
					//2300 DTP 050 (institutional) Repricer Received Date. Situational. Not supported.
				}
				else if(medType==EnumClaimMedType.Dental) {
					//2300 DTP 439 (dental) Date accident. Situational. Required when there was an accident.
					if(claim.AccidentDate.Year>1880) {
						sw.Write("DTP"+s
							+"439"+s//DTP01 3/3 Date/Time Qualifier: 439=accident
							+"D8"+s//DTP02 2/3 Date Time Period Format Qualifer: D8=Date Expressed in Format CCYYMMDD.
							+claim.AccidentDate.ToString("yyyyMMdd"));//DTP03 1/35 Date Time Period:
						EndSegment(sw);
					}
					//2300 DTP 452 (dental) Date Appliance Placement. Situational. Values can be overriden in loop 2400 for individual service items, but we don't support that.
					if(claim.OrthoDate.Year>1880) {
						sw.Write("DTP"+s
							+"452"+s//DTP01 3/3 Date/Time Qualifier: 452=Appliance Placement.
							+"D8"+s//DTP02 2/3 Date Time Period Format Qualifier: D8=Date Expressed in Format CCYYMMDD.
							+claim.OrthoDate.ToString("yyyyMMdd"));//DTP03 1/35 Date Time Period:
						EndSegment(sw);
					}
					//2300 DTP 472 (dental) Service Date. Not used if predeterm.
					if(claim.ClaimType!="PreAuth") {
						if(claim.DateService.Year>1880) {
							sw.Write("DTP"+s
								+"472"+s//DTP01 3/3 Date/Time Qualifier: 472=Service.
								+"D8"+s//DTP02 2/3 Date Time Period Format Qualifier: D8=Date Expressed in Format CCYYMMDD.
								+claim.DateService.ToString("yyyyMMdd"));//DTP03 1/35 Date Time Period:
							EndSegment(sw);
						}
					}
					//2300 DTP 050 (dental) Repricer Received Date.  Not supported.
				}
				#endregion Claim DTP
				#region Claim DN CL1
				if(medType==EnumClaimMedType.Dental) {
					//2300 DN1: Orthodontic Total Months of Treatment.
					if(claim.IsOrtho) {
						sw.Write("DN1"+s
							+s//DN101 1/15 Quantity: Total months of orthodontic treatment. Not used because no field yet in OD.
							+claim.OrthoRemainM.ToString());//DN102 1/15 Quantity: Number of treatment months remaining.
						EndSegment(sw);//DN103 is not used and DN104 is situational but we do not use it.
					}
					//2300 DN2: Tooth Status. Missing teeth.
					List<string> missingTeeth=ToothInitials.GetMissingOrHiddenTeeth(initialList);
					bool doSkip;
					int countMissing=0;
					for(int j=0;j<missingTeeth.Count;j++) {
						//if the missing tooth is missing because of an extraction being billed here, then exclude it
						//still needed, even though missing teeth are not based on procedures any longer
						doSkip=false;
						for(int p=0;p<claimProcs.Count;p++) {
							proc=Procedures.GetProcFromList(procList,claimProcs[p].ProcNum);
							procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
							if(procCode.PaintType==ToothPaintingType.Extraction && proc.ToothNum==missingTeeth[j]) {
								doSkip=true;
								break;
							}
						}
						if(doSkip) {
							continue;
						}
						countMissing++;
						if(countMissing>35) {//segment max use 35
							continue;
						}
						sw.Write("DN2"+s
							+missingTeeth[j]+s//DN201 1/50 Reference Identification: Tooth number.
							+"M"+s//DN202: M=Missing, I=Impacted, E=To be extracted.
							+s//DN203 1/15 Quantity: Not used.
							+s//DN204 2/3 Date Time Period Format Qualifier: Not used.
							+s//DN205 1/35 Date Time Period: Not used.
							+"JP");//DN206 1/3 Code List Qualifier Code: Required. JP=JP Universal National Tooth Designation System.
						EndSegment(sw);
					}
				}
				if(medType==EnumClaimMedType.Institutional) {
					//2300 CL1: Institutional Claim Code. Required
					sw.Write("CL1"+s
						+claim.AdmissionTypeCode+s//CL101 1/1 Admission Type Code: Validated.
						+claim.AdmissionSourceCode+s//CL102 1/1 Admission Source Code: Required for inpatient services. Validated.
						+claim.PatientStatusCode);//CL103 1/2 Patient Status Code: Validated.
					EndSegment(sw);//CL104 1/1 Nursing Home Residential Status Code: Not used.
				}
				#endregion Claim DN CL1
				#region Claim PWK
				//2300 PWK: (medical,institutional,dental) Claim Supplemental Information. Paperwork. Used to identify attachments.
				/*if(IsTesia(clearhouse) && claim.Attachments.Count>0) {//If Tesia and has attachments
					sw.Write("PWK"+s
						+"OZ"+s//PWK01: ReportTypeCode. OZ=Support data for claim.
						+"EL"+s//PWK02: Report Transmission Code. EL=Electronic
						+s+s//PWK03 and 04: not used
						+"AC"+s//PWK05: Identification Code Qualifier. AC=Attachment Control Number
						+"TES"+claim.ClaimNum.ToString());//PWK06: Identification Code.
				 	EndSegment(sw);
				}*/
				//If Attachment ID # is present but no attachment flag, then sending is blocked.
				//No other validation is done.  However, warnings are displayed if:
				//Warning if attachments are listed as Mail even though we are sending electronically.
				//Warning if any PWK segments are needed, and there is no ID code.
				//PWK can repeat max 10 times.  However, we only write one PWK segment, because the user can only enter one Attachment Control Number.
				string pwk01="  ";//This double blank will never actually get sent because of the trim and if statement around the PWK creation.
				if(claim.AttachedFlags.Contains("EoB")) {
					pwk01="EB";//Explaination of Benefits
				}
				if(claim.AttachedFlags.Contains("Perio")) {
					if(medType==EnumClaimMedType.Dental) {
						pwk01="P6";//Periodontal Charts
					}
					else {//Medical and institutional
						pwk01="OZ";//Support Data for Claim. There is no "P6" nor a code for perio charts.
					}
				}
				if(claim.AttachedFlags.Contains("Misc") || claim.AttachedFlags.Contains("Note") || claim.AttachedImages>0) {
					pwk01="OZ";//Support Data for Claim
				}
				if(claim.Radiographs>0) {
					pwk01="RB";//Radiology Films
				}
				if(claim.AttachedModels>0) {
					pwk01="DA";//Dental Models
				}
				string pwk02="  ";
				if(IsDentiCal(clearhouse)) {
					pwk02="FT";//"File Transfer". Might be electronic or mail, but Denti-Cal requires a value of FT here.
				}
				else {
					if(claim.AttachedFlags.Contains("Mail")) {
						pwk02="BM";//By Mail
					}
					else {
						pwk02="EL";//Elect
					}
				}
				string pwk06=claim.AttachmentID;
				if(pwk02=="BM" && pwk06=="") {//If By Mail is checked, they will typically leave attachment ID blank, but X12 requires a value, so we make one up.
					pwk06="00";
				}
				pwk06=Sout(pwk06,80,2);
				if(pwk01.Trim()!="" && pwk06!="") {
					sw.Write("PWK"+s
						+pwk01+s//PWK01 2/2 Report Type Code:
						+pwk02+s//PWK02 1/2 Report Transmission Code: EL=Electronically Only, BM=By Mail.
						+s+s//PWK03 and PWK04: Not Used.
						+"AC"+s//PWK05 1/2 Identification Code Qualifier: AC=Attachment Control Number.
						+pwk06);//PWK06 2/80 Identification Code:
					EndSegment(sw);//PWK07 through PWK09 are not used.
				}
				#endregion Claim PWK
				#region Claim CN1 AMT
				//2300 CN1: (medical,institutional,dental)Contract Information. Situational. We do not use this.
				//2300 AMT: (institutional) Patient Estimated Amount Due.
				//2300 AMT: (medical,dental) Patient Amount Paid. Situational. We do not use this.
				if(medType==EnumClaimMedType.Medical || medType==EnumClaimMedType.Dental) {
					//sw.Write("AMT"+s
				  //  +"F5"+s//AMT01 1/3 Amount Qualifier Code: F5=Patient Paid Amount.
				  //  +"0");//AMT02 1/18 Monetary Amount: We don't track this information very well so we always put zero.
					//EndSegment(sw);//AMT03 is not used.
				}
				#endregion Claim CN1 AMT
				#region Claim REF
				if(medType==EnumClaimMedType.Dental) {
					//2300 REF: G3 (dental) Predetermination Identification. Situational.  Required when sending claim for previously predetermined services. Do not send prior authorization number here.
					if(claim.PreAuthString!="") {//validated to be empty for medical and inst
						sw.Write("REF"+s
							+"G3"+s//REF01 2/3 G3=Predetermination of Benefits Identification Number.
							+Sout(claim.PreAuthString,50));//REF02 1/50 Predeterm of Benfits Identifier.
						EndSegment(sw);//REF03 and REF04 are not used.
					}
				}
				//2300 REF: 4N (medical,institutional,dental) Service Authorization Exception Code. Situational. Required if services were performed without authorization.
//todo: ServiceAuthException
				//2300 REF: F5 (medical) Mandatory Medicare (Section 4081) Crossover Indicator. Situational. Required when submitter is Medicare and the claim is a Medigap or COB crossover claim. We do not use.
				//2300 REF: EW (medical) Mammography Certification Number. Situational. We do not use.
				//2300 REF: F8 (medical,institutional,dental) Payer Claim Control Number: Situational. Required if this is a replacement or void claim. Might not be required for corrected, but we require anyway since it is required in 4010.
					//aka Original Document Control Number/Internal Control Number (DCN/ICN).
					//aka Transaction Control Number (TCN).  
					//aka Claim Reference Number. 
					//Seems to be required by Medicaid when voiding a claim or resubmitting a claim by setting the CLM05-3.
				if(claim.CorrectionType!=ClaimCorrectionType.Original 
					|| claim.UniformBillType.Length>2 && (claim.UniformBillType.Substring(2,1)=="6" || claim.UniformBillType.Substring(2,1)=="7" || claim.UniformBillType.Substring(2,1)=="8")) { //correction, replacement or void.
					sw.Write("REF"+s
						+"F8"+s//REF01 2/3 Reference Identification Qualifier: F8=Original Reference Number.
						+Sout(claim.OrigRefNum,50));//REF02 1/50 Reference Identification: Payer Claim Control Number.
					EndSegment(sw);//REF03 and REF04 are not used.
				}
				//2300 REF: 9F (medical,institutional,dental) Referral Number. Situational. Required when a referral number is assigned by the payer or Utilization Management Organization (UMO) AND a referral is involved.
				if(claim.RefNumString!="") {
					sw.Write("REF"+s
						+"9F"+s//REF01 2/3 Reference Identification Qualifier: 9F=Referral Number.
						+Sout(claim.RefNumString,30));//REF02 1/50 Reference Identification:
					EndSegment(sw);//REF03 and REF04 are not used.
				}
				//2300 REF: X4 (medical) Clinical Laboratory Improvement Amendment (CLIA) Number. Situational. We do not use.
				//2300 REF: G1 (medical,institutional,dental) Prior Authorization. Situational. Do not report predetermination of benefits id number here. G1 and G3 were muddled in 4010.  
				if(claim.PriorAuthorizationNumber!="") {
					sw.Write("REF"+s
						+"G1"+s//REF01 2/3 Reference Identification Qualifier: G1=Prior Authorization Number.
						+Sout(claim.PriorAuthorizationNumber,50));//REF02 1/50 Reference Identification: Prior Authorization Number.
					EndSegment(sw);//REF03 and REF04 are not used.
				}					
				//2300 REF: 9A (medical,institutional,dental) Repriced Claim Number. Situational. We do not use. 
				//2300 REF: 9C (medical,institutional,dental) Adjusted Repriced Claim Number. Situational. We do not use.
				//2300 REF: D9 (medical,institutional,dental) Claim Identifier For Transmission Intermediaries. Situational.
				if(IsClaimConnect(clearhouse)) { //Since this information has only been requested by ClaimConnect and is optional in the specification, we should only add specific clearinghouses here when requested.
					sw.Write("REF"+s
						+"D9"+s//REF01 2/3 Reference Identification Qualifier: D9=Claim Number.
						+Sout(claim.ClaimIdentifier,20));//REF02 1/50 Reference Identification: Value Added Network Trace Number. From specification, maximum of 20 characters even though there is space for 50.
					EndSegment(sw);//REF03 and REF04 are not used.
				}
				//2300 REF: LX (medical,institutional) Investigational Device Exemption Number. Situational. Required for FDA IDE.
				//2300 REF: LU (institutional) Auto Accident State. Situational. Seems to me to be a duplicate of the info in CLM11.
				//2300 REF: EA (medical,institutional) Medical Record Number. Situational. We do not use.
				//2300 REF: P4 (medical,institutional) Demonstration Project Identifier. Situational. We do not use. Seems very unimportant.
				//2300 REF: G4 (institutional) Peer Review Organization (PRO) Approval Number. Situational. We do not use.
				//2300 REF: 1J (medical) Care Plan Oversight. Situational. We do not use.
				#endregion Claim REF
				#region Claim K3 NTE CRx
				//2300 K3: File info (medical,institutional,dental). Situational. We do not use this.
				//NTE loops------------------------------------------------------------------------------------------------------
				//2300 NTE: (medical,institutional,dental) Claim Note. Situational. A number of NTE01 codes other than 'ADD', which we don't support.
				string note="";
				if(claim.AttachmentID!="" && !claim.ClaimNote.StartsWith(claim.AttachmentID)) {
					note=claim.AttachmentID+" ";
				}
				note+=claim.ClaimNote;
				if(note!="") {
					sw.Write("NTE"+s
						+"ADD"+s//NTE01 3/3 Note Reference Code: ADD=Additional information.
						+Sout(note,80));//NTE02 1/80 Description:
					EndSegment(sw);
				}
				//2300 NTE: (institutional) Billing Note. Situational. We do not use.
				//CRx loops------------------------------------------------------------------------------------------------------
				//2300 CR1: LB (medical) Ambulance Transport Information. Situational. We do not use.
				//2300 CR2: (medical) Spinal Manipulation Service Information. Situational. We do not use.
				//2300 CRC: (medical) Ambulance Certification. Situational. We do not use.
				//2300 CRC: (medical) Patient Condition Information Vision. Situational. We do not use.
				//2300 CRC: (medcial) Homebound Indicator. Situational. We do not use.
				//2300 CRC: (medical,institutional) EPSDT Referral. Situational. Required on EPSDT claims when the screening service is being billed in this claim. We do not use.
				#endregion Claim K3 NTE CRx
				#region Claim HI HCP
				//HI loops-------------------------------------------------------------------------------------------------------
				List<string> diagnosisList=new List<string>();//princDiag will always be the first element.
				if(medType==EnumClaimMedType.Medical || medType==EnumClaimMedType.Institutional){
					for(int j=0;j<claimProcs.Count;j++) {
						proc=Procedures.GetProcFromList(procList,claimProcs[j].ProcNum);
						if(proc.DiagnosticCode=="") {
							continue;
						}
						if(proc.IsPrincDiag) {
							if(diagnosisList.Contains(proc.DiagnosticCode)) {
								diagnosisList.Remove(proc.DiagnosticCode);
							}
							diagnosisList.Insert(0,proc.DiagnosticCode);//princDiag always goes first. There will always be one.
						}
						else {//not princDiag
							if(!diagnosisList.Contains(proc.DiagnosticCode)) {
								diagnosisList.Add(proc.DiagnosticCode);
							}
						}
					}
				}
				//2300 HI: BK (medical,dental) Health Care Diagnosis Code. Situational. For OMS or anesthesiology.
//todo: validate at least one diagnosis
				if(medType==EnumClaimMedType.Institutional) {
					sw.Write("HI"+s
						+"BK"+isa16//HI01-1 1/3 Code List Qualifier Code: BK=ICD-9 Principal Diagnosis.
						+Sout(diagnosisList[0].Replace(".",""),30));//HI01-2 1/30 Industry Code: Diagnosis code. No periods.
					EndSegment(sw);
				} 
				else if(medType==EnumClaimMedType.Medical) {
					sw.Write("HI"+s
						+"BK"+isa16//HI01-1 1/3 Code List Qualifier Code: BK=ICD-9 Principal Diagnosis.
						+Sout(diagnosisList[0].Replace(".",""),30));//HI01-2 1/30 Industry Code: Diagnosis code. No periods.
					for(int j=1;j<diagnosisList.Count;j++) {
						if(j>11) {//maximum of 12 diagnoses
							break;
						}
						sw.Write(s//this is the separator from the _previous_ field.
							+"BF"+isa16//HI0#-1 1/3 Code List Qualifier Code: BF=ICD-9 Diagnosis
							+Sout(diagnosisList[j].Replace(".",""),30));//HI0#-2 1/30 Industry Code: Diagnosis code. No periods.
					}
					EndSegment(sw);
				}
				//2300 HI: BP (medical) Anesthesia Related Procedure. Situational. We do not use.
				//2300 HI: BJ (institutional) Admitting Diagnosis. Situational. Required for inpatient admission. We do not use.
				//2300 HI: PR (institutional) Patient's Reason for Visit. Situational. Required for outpatient visits.
				if(medType==EnumClaimMedType.Institutional) {
					sw.Write("HI"+s
						+"PR"+isa16//HI01-1 1/3 Code List Qualifier Code: PR=ICD-9 Patient's Reason for Visit.
						+Sout(diagnosisList[0].Replace(".",""),30));//HI01-2 1/30 Industry Code: No periods. This is not really principal diagnosis but is close to the same, so someday we will add this field to claim.
					EndSegment(sw);
				}
				//2300 HI: BN (institutional) External Cause of Injury. Situational. We do not use.
				//2300 HI: (institutional) Diagnosis Related Group (DRG) Information. Situational. We do not use. For inpatient hospital under DRG contract.
				//2300 HI: BF (institutional) Other Diagnosis Information. Situational. We do not use. When other conditions coexist or develop.
				//2300 HI: BR (institutional) Principal Procedure Information. Situational. We do not use. Required on inpatient claims when a procedure was performed.
				//2300 HI: BQ (institutional) Other Procedure Information. Situational. We do not use. Inpatient claims for additional procedures.
				//2300 HI: BI (institutional) Occurence Span Information. Situational. We do not use. For an occurence span code.
				//2300 HI: BH (institutional) Occurence Information. Situational. We do not use. For an occurence code.
				//2300 HI: BE (institutional) Value Information. Situational. We do not use. For a value code.
				//2300 HI: BG (medical,institutional) Condition Information. Situational. We do not use. For a condition code.
				//2300 HI: TC (institutional) Treatment Code Information. Situational. We do not use. When home health agencies need to report plan of treatment information under contracts.
				//2300 HCP: (medical,institutional,dental) Claim Pricing/Repricing Information. Situational. We do not use.
				#endregion Claim HI HCP
				bool sendFacilityNameAndAddress=false;
				if(medType==EnumClaimMedType.Medical) {
					//Code added to send the segment below, but no logic here for sending yet, so it is never sent.
				}
				else if(medType==EnumClaimMedType.Institutional) {
					//Code added to send the segment below, but no logic here for sending yet, so it is never sent.
				}
				else if(medType==EnumClaimMedType.Dental) {
					if(claim.PlaceService!=PlaceOfService.Office) {
						if(IsClaimConnect(clearhouse)) {
							//Osvaldo Ferrer, VIP account manager for DentalXChange, says we need the segment whenever the place of service is not office.
							sendFacilityNameAndAddress=true;
						}
						else {//for other clearinghouses, the X12 specs say that we don't send it if it's the same as the billing prov.
							//and since we always set it the same as the billing prov, we shouldn't send it.
						}
					}
				}
				Provider facilityProv=billProv;//If this provider changes in the future, then the validation section will also need to be updated.
				string facilityAddress1=billingAddress1;
				string facilityAddress2=billingAddress2;
				string facilityCity=billingCity;
				string facilityState=billingState;
				string facilityZip=billingZip;
				//For medical, instititional, and dental, sending facility NPI must be for an organization (non-person).
				if(!facilityProv.IsNotPerson) {//Validated also
					sendFacilityNameAndAddress=false;
				}
				provTreat=Providers.GetProv(claim.ProvTreat);
				#region 2310 Claim Providers (medical)
				//Since order might be important, we have to handle medical, institutional, and dental separately.
				if(medType==EnumClaimMedType.Medical) {
					//2310A NM1: DN/P3 (medical) Referring Provider Name. Situational.
					WriteNM1_DN(sw,claim.ReferringProv);
					//2310A REF: (medical) Referring Provider Secondary Identification. Situational. We do not use.
					//Always included for Emdeon Medical, because Emdeon Medical will automatically remove this segment if the payer does not want it
					//Some payers reject if not specified, even when the claim.ProvTreat=claim.ProvBill. For example, Texas Medicaid.
					//if(claim.ProvTreat!=claim.ProvBill || IsEmdeonMedical(clearhouse)) {
					//2310B NM1: 82 (medical) Rendering Provider Name. Required when treating provider is different from billing provider.
					WriteNM1Provider("82",sw,provTreat);
					//2310B PRV: PE (medical) Rendering Provider Specialty Information. Situational.
					WritePRV_PE(sw,provTreat);
					//2310B REF: (medical) Rendering Provider Secondary Identification. Situational. We do not use.					
					//2310C NM1: 77 (medical) Service Facility Location Name. Conditions different than 4010.  
					//Not supposed to send if same location as 2010AA Billing Provider, but some clearinghouses want this segment anyway.
					if(sendFacilityNameAndAddress) {
						sw.Write("NM1"+s
							+"77"+s//NM101 2/3 Entity Identifier Code: 77=Service Location.
							+"2"+s//NM102 1/1 Entity Type Qualifier: 2=Non-Person Entity.
							+Sout(facilityProv.LName,60)+s//NM103 1/60 Name Last or Organization Name: Laboratory or Facility Name.
							+s//NM104 1/35 Name First: Not used.
							+s//NM105 1/25 Name Middle: Not used.
							+s//NM106 1/10 Name Prefix: Not used.
							+s//NM107 1/10 Name Suffix: Not used.
							+"XX"+s//NM108 1/2 Identification Code Qualifier: XX=NPI.
							+Sout(facilityProv.NationalProvID,80));//NM109 2/80 Identification Code: Laboratory or Facility Identifier. Validated.
						EndSegment(sw);//NM110 through NM112 not used.
						//2310C N3: (medical) Service Facility Location Address.
						sw.Write("N3"+s+Sout(facilityAddress1,55));//N301 1/55 Address Information: Laboratory or Facility Address Line.
						if(facilityAddress2!="") {
							sw.Write(s+Sout(facilityAddress2,55));//N302 1/55 Address Information: Laboratory or Facility Address Line 2. Only required when there is a secondary address line.
						}
						EndSegment(sw);
						//2310C N4: (medical) Service Facility Location City, State, Zip Code.
						sw.Write("N4"+s
							+Sout(facilityCity,30)+s//N401 2/30 City Name: Laboratory or Facility City Name.
							+Sout(facilityState,2,2)+s//N402 2/2 State or Provice Code: Laboratory or Facility State or Province Code.
							+Sout(facilityZip.Replace("-",""),15));//N403 3/15 Postal Code: Laboratory or Facility Postal Zone or ZIP Code.
						EndSegment(sw);//N404 through N407 are either not used or only required when outside of the United States.
						//2310C REF: (medical) Service Facility Location Secondary Identification. Situational. We do not use this.
						//2310C PER: (medical) Service Facility Contact Information. Situational. Required for property and casualty claims. We do not use.
					}
					//2310D NM1: (medical) Supervising Provider Name. Situational. We do not use.
					//2310D REF: (medical) Supervising Provider Secondary Identification. Situational. We do not use.
					//2310E NM1: (medical) Ambulance Pick-up Location. Situational. We do not use.
					//2310E N3: (medical) Ambulance Pick-up Location Address. We do not use.
					//2310E N4: (medical) Ambulance Pick-up Location City, State, Zip Code. We do not use.
					//2310F NM1: (medical) Ambulance Drop-off Location. Situational. We do not use.
					//2310F N3: (medical) Ambulance Drop-off Location Address. We do not use.
					//2310F N4: (medical) Ambulance Drop-off Location City, State, Zip Code. We do not use.
				}
				#endregion 2310 Claim Providers (medical)
				#region 2310 Claim Providers (inst)
				if(medType==EnumClaimMedType.Institutional) {
					//2310A NM1: 71 (institutional) Attending Provider Name. Situational. Always a person according to the specification (cannot be non-person).
					WriteNM1Provider("71",sw,provTreat.FName,provTreat.MI,provTreat.LName,provTreat.NationalProvID,false);
					//2310A PRV: AT (institutional) Attending Provider Specialty Information. Situational.
					sw.Write("PRV"+s
						+"AT"+s//PRV01 1/3 Provider Code: AT=Attending.
						+"PXC"+s//PRV02 2/3 Reference Identification Qualifier: PXC=Health Care Provider Taxonomy Code.
						+X12Generator.GetTaxonomy(provTreat));//PRV03 1/50 Reference Identification: Provider Taxonomy Code.
					EndSegment(sw);//PRV04 through PRV06 are not used.
					//2310A REF: (institutional) Attending Provider Secondary Identification. Situational.
					//2310B NM1: 72 (institutional) Operating Physician Name. Situational. For surgical procedure codes.
					//2310C REF: ZZ (institutional) Secondary Physician Secondary Identification. Situational.
					//2310C NM1: ZZ (institutional) Other Operating Physician Name. Situational.
					//2310C REF: ZZ (institutional) Other Operating Physician Secondary Identification. Situational.
					//2310D NM1: 82 (institutional) Rendering Provider Name. Situational. If different from attending provider AND when regulations require both facility and professional components.
					//2310D REF: ZZ (institutional) Rendering Provider Secondary Identificaiton. Situational.
					//2310E NM1: 77 (institutional) Service Facility Location Name. Conditions different than 4010.  
					//Not supposed to send if same location as 2010AA Billing Provider, but some clearinghouses want this segment anyway.
					if(sendFacilityNameAndAddress) {
						sw.Write("NM1"+s
							+"77"+s//NM101 2/3 Entity Identifier Code: 77=Service Location.
							+"2"+s//NM102 1/1 Entity Type Qualifier: 2=Non-Person Entity.
							+Sout(facilityProv.LName,60)+s//NM103 1/60 Name Last or Organization Name: Laboratory or Facility Name.
							+s//NM104 1/35 Name First: Not used.
							+s//NM105 1/25 Name Middle: Not used.
							+s//NM106 1/10 Name Prefix: Not used.
							+s//NM107 1/10 Name Suffix: Not used.
							+"XX"+s//NM108 1/2 Identification Code Qualifier: XX=NPI.
							+Sout(facilityProv.NationalProvID,80));//NM109 2/80 Identification Code: Laboratory or Facility Primary Identifier. Validated.
						EndSegment(sw);//NM110 through NM112 not used.
						//2310E N3: (institutional) Service Facility Location Address.
						sw.Write("N3"+s+Sout(facilityAddress1,55));//N301 1/55 Address Information: Laboratory or Facility Address Line.
						if(facilityAddress2!="") {
							sw.Write(s+Sout(facilityAddress2,55));//N302 1/55 Address Information: Laboratory or Facility Address Line 2. Only required when there is a secondary address line.
						}
						EndSegment(sw);
						//2310E N4: (institutional) Service Facility Location City, State, Zip Code.
						sw.Write("N4"+s
							+Sout(facilityCity,30)+s//N401 2/30 City Name: Laboratory or Facility City Name.
							+Sout(facilityState,2,2)+s//N402 2/2 State or Provice Code: Laboratory or Facility State or Province Code.
							+Sout(facilityZip.Replace("-",""),15));//N403 3/15 Postal Code: Laboratory or Facility Postal Zone or ZIP Code.
						EndSegment(sw);//N404 through N407 are either not used or only required when outside of the United States.
						//2310E REF: ZZ (institutional) Service Facility Location Secondary Identificiation. Situational. We do not use.
					}
					//2310F NM1: DN (institutional) Referring Provider Name. Situational. Required when referring provider is different from attending provider.
					if(claim.ReferringProv!=claim.ProvTreat) {
						WriteNM1_DN(sw,claim.ReferringProv);
					}
					//2310F REF: (institutional) Referring Provider Secondary Identification. Situational. 
				}
				#endregion 2310 Claim Providers (inst)
				#region 2310 Claim Providers (dental)
				if(medType==EnumClaimMedType.Dental) {
					//2310A NM1: DN (dental) Referring Provider Name. Situational.
					WriteNM1_DN(sw,claim.ReferringProv);
					//2310A PRV: (dental) Referring Provider Specialty Information. Situational.
					//2310A REF: G2 (dental) Referring Provider Secondary Identification. Situational.
					bool sendClaimTreatProv=false;
					if(claim.ProvTreat!=claim.ProvBill) { //Emdeon will reject the claim if this segment is the same as the billing provider for all claims in the batch.
						sendClaimTreatProv=true;//Standard X12 behavior to only include the treating provider if it is different than the billing provider.
					}
					//The following clearinghouses always want the claim treating provider, even if it is the same as the billing provider.
					if(IsOfficeAlly(clearhouse)) {
						sendClaimTreatProv=true;
					}
					if(sendClaimTreatProv) {
						//2310B NM1: 82 (dental) Rendering Provider Name. Situational. Only required if different from the billing provider.
						WriteNM1Provider("82",sw,provTreat);
						//2310B PRV: PE (dental) Rendering Provider Specialty Information.
						WritePRV_PE(sw,provTreat);
						//2310B REF: (dental) Rendering Provider Secondary Identification. Situational. Not required because we always send NPI. Max repeat of 4.
						if(IsClaimConnect(clearhouse) || IsEmdeonDental(clearhouse)) {
							//The state licence number can be anywhere between 4 and 14 characters depending on state, and most states have more than one state license format. 
							//Therefore, we only validate that the state license is present or not.
							if(provTreat.StateLicense!="") { 
								sw.Write("REF"+s
									+"0B"+s//REF01 2/3 Reference Identification Qualifier: 0B=State License Number.
									+Sout(provTreat.StateLicense,50));//REF02 1/50 Reference Identification:
								EndSegment(sw);//REF03 and REF04 are not used.
							}
						}
						if(IsEmdeonDental(clearhouse)) { //Always required by Emdeon Dental.
							WriteProv_REFG2orLU(sw,provTreat,carrier.ElectID);
						}
					}
					//2310C NM1: 77 (dental) Service Facility Location Name. Conditions different than 4010.  
					//Not supposed to send if same location as 2010AA Billing Provider, but ClaimConnect wants this segment anyway.
					if(sendFacilityNameAndAddress) {
						sw.Write("NM1"+s
							+"77"+s//NM101 2/3 Entity Identifier Code: 77=Service Location.
							+"2"+s//NM102 1/1 Entity Type Qualifier: 2=Non-Person Entity.
							+Sout(facilityProv.LName,60)+s//NM103 1/60 Name Last or Organization Name: Laboratory or Facility Name.
							+s//NM104 1/35 Name First: Not used.
							+s//NM105 1/25 Name Middle: Not used.
							+s//NM106 1/10 Name Prefix: Not used.
							+s//NM107 1/10 Name Suffix: Not used.
							+"XX"+s//NM108 1/2 Identification Code Qualifier: XX=NPI.
							+Sout(facilityProv.NationalProvID,80));//NM109 2/80 Identification Code: Laboratory or Facility Identifier. Validated.
						EndSegment(sw);//NM110 through NM112 not used.
						//2310C N3: (dental) Service Facility Location Address.
						sw.Write("N3"+s+Sout(facilityAddress1,55));//N301 1/55 Address Information: Laboratory or Facility Address Line.
						if(facilityAddress2!="") {
							sw.Write(s+Sout(facilityAddress2,55));//N302 1/55 Address Information: Laboratory or Facility Address Line 2. Only required when there is a secondary address line.
						}
						EndSegment(sw);
						//2310C N4: (dental) Service Facility Location City, State, Zip Code.
						sw.Write("N4"+s
							+Sout(facilityCity,30)+s//N401 2/30 City Name: Laboratory or Facility City Name.
							+Sout(facilityState,2,2)+s//N402 2/2 State or Provice Code: Laboratory or Facility State or Province Code.
							+Sout(facilityZip.Replace("-",""),15));//N403 3/15 Postal Code: Laboratory or Facility Postal Zone or ZIP Code.
						EndSegment(sw);//N404 through N407 are either not used or only required when outside of the United States.
						//2310C REF: (dental) Service Facility Location Secondary Identification. Situational. We do not use this.
					}
					//2310D NM1: (dental) Assistant Surgeon Name. Situational. We do not support.
					//2310D PRV: (dental) Assistant Surgeon Specialty Information. We do not support.
					//2310D REF: (dental) Assistant Surgeon Secondary Identification. We do not support.
					//2310E NM1: (dental) Supervising Provider Name. Situational. We do not support.
					//2310E REF: (dental) Supervising Provider Secondary Identification. Situational. We do not support.
				}
				#endregion 2310 Claim Providers (dental)
				#region 2320 Other subscriber information
				List<double> listProcWriteoffAmts=new List<double>();
				List<double> listProcDeductibleAmts=new List<double>();
				List<double> listProcPaidOtherInsAmts=new List<double>();
				bool hasAdjForOtherPlans=false;
				//2320 Other subscriber------------------------------------------------------------------------------------------
				if(otherPlan!=null) {
					//2320 SBR: Other Subscriber Information. Situational.
					sw.Write("SBR"+s);
					sw.Write((claimIsPrimary?"S":"P")+s);//SBR01 1/1 Payer Responsibility Sequence Number Code: When the claim is primary then the other insurance is secondary, and vice versa.
					sw.Write(GetRelat(claim.PatRelat2)+s//SBR02 2/2 Individual Relationship Code:
						+Sout(otherPlan.GroupNum,50)+s);//SBR03 1/50 Reference Identification:
					//SBR04 1/60 Name: Situational. Required when SBR03 is not specified.
					if(otherPlan.GroupNum!="") {
						sw.Write(s);
					}
					else {
						sw.Write(Sout(otherPlan.GroupName,60)+s);
					}
					sw.Write(s//SBR05 1/3 Insurance Type Code: Situational. Required when the payer in loop 2330B is Medicare and Medicare is not the primary payer. Medical and Dental only. TODO: implement.
						+s//SBR06 1/1 Coordination of Benefits Code: Not used.
						+s//SBR07 1/1 Yes/No Condition or Response Code: Not Used.
						+s//SBR08 2/2 Employment Status Code: Not Used.
						+GetFilingCode(otherPlan));//SBR09 1/2 Claim Filing Indicator Code: 12=PPO,17=DMO,BL=BCBS,CI=CommercialIns,FI=FEP,HM=HMO. Will no longer be required when HIPPA National Plan ID is mandated.
					EndSegment(sw);
					double claimWriteoffAmt=0;
					double claimDeductibleAmt=0;
					double claimPaidOtherInsAmt=0;
					double claimPatientPortionAmt=0;
					for(int j=0;j<claimProcs.Count;j++) {//Claim procs for this claim
						double procWriteoffAmt=0;
						double procDeductibleAmt=0;
						double procPaidOtherInsAmt=0;
						for(int k=0;k<claimProcList.Count;k++) {//All claim procs for patient
							if(ClaimProcs.IsValidClaimAdj(claimProcList[k],claimProcs[j].ProcNum,claimProcs[j].InsSubNum)) {//Adjustment due to other insurance plans.
								hasAdjForOtherPlans=true;
								claimWriteoffAmt+=claimProcList[k].WriteOff;
								claimDeductibleAmt+=claimProcList[k].DedApplied;
								claimPaidOtherInsAmt+=claimProcList[k].InsPayAmt;
								procWriteoffAmt+=claimProcList[k].WriteOff;
								procDeductibleAmt+=claimProcList[k].DedApplied;
								procPaidOtherInsAmt+=claimProcList[k].InsPayAmt;
							}
						}
						listProcWriteoffAmts.Add(procWriteoffAmt);
						listProcDeductibleAmts.Add(procDeductibleAmt);
						listProcPaidOtherInsAmts.Add(procPaidOtherInsAmt);
						double procPatientPortionAmt=Math.Max(0,claimProcs[j].FeeBilled-listProcWriteoffAmts[j]-listProcDeductibleAmts[j]-listProcPaidOtherInsAmts[j]);
						claimPatientPortionAmt+=procPatientPortionAmt;
					}
					//If sending the primary claim, then hasAdjForOtherPlans will be false, because all claimprocs for any other plans (secondary) will be estimates.
					//If sending the secondary claim, then hasAdjForOtherPlans will be true, because the primary claimprocs will be received.
					//This strategy works for dental and medical plans in any combination: D, M, DD, DM, MD, MM
					if(hasAdjForOtherPlans) {
						//2320 CAS: (medical,institutional,dental) Claim Level Adjustments. Situational. We use this to show patient responsibility, because the adjustments here plus AMT D below must equal claim amount in CLM02 for Emdeon.
						//Claim Adjustment Reason Codes can be found on the Washington Publishing Company website at: http://www.wpc-edi.com/reference/codelists/healthcare/claim-adjustment-reason-codes/
						if(claimWriteoffAmt>0) {
							sw.Write("CAS"+s
								+"CO"+s//CAS01 1/2 Claim Adjustment Group Code: CO=Contractual Obligations.
								+"45"+s//CAS02 1/5 Claim Adjustment Reason Code: 45=Charge exceeds fee schedule/maximum allowable or contracted/legislated fee arrangement.
								+AmountToStrNoLeading(claimWriteoffAmt));//CAS03 1/18 Monetary Amount:
							EndSegment(sw);
						}
						if(claimDeductibleAmt>0 || claimPatientPortionAmt>0) {
							sw.Write("CAS"+s
								+"PR");//CAS01 1/2 Claim Adjustment Group Code: PR=Patient Responsibility.
							if(claimDeductibleAmt>0) {
								sw.Write(s//end of previous field
									+"1"+s//CAS02 1/5 Claim Adjustment Reason Code: 1=Deductible.
									+AmountToStrNoLeading(claimDeductibleAmt)+s//CAS03 1/18 Monetary Amount:
									+"1");//CAS04 1/15 Quantity:
							}
							if(claimPatientPortionAmt>0) {
								sw.Write(s//end of previous field
									+"3"+s//CAS02 or CAS05 1/5 Claim Adjustment Reason Code: 3=Co-payment Amount.
									+AmountToStrNoLeading(claimPatientPortionAmt));//CAS03 or CAS06 1/18 Monetary Amount:
							}
							EndSegment(sw);
						}
						//2320 AMT: D (medical,institutional,dental) COB Payer Paid Amount. Situational. Required when the claim has been adjudicated by payer in loop 2330B.
						sw.Write("AMT"+s
							+"D"+s//AMT01 1/3 Amount Qualifier Code: D=Payor Amount Paid.
							+AmountToStrNoLeading(claimPaidOtherInsAmt));//AMT02 1/18 Monetary Amount:
						EndSegment(sw);//AMT03 Not used.
						//2320 AMT: EAF (medical,institutional,dental) Remaining Patient Liability. Situational. Required when claim has been adjudicated by payer in loop 2330B.
						sw.Write("AMT"+s
							+"EAF"+s//AMT01 1/3 Amount Qualifier Code: EAF=Amount Owed.
							+AmountToStrNoLeading(claimPatientPortionAmt));//AMT02 1/18 Monetary Amount:
						EndSegment(sw);//AMT03 Not used.
						//2320 AMT: A8 (medical,institutional,dental) COB Total Non-Covered Amount. Situational. Can be set when primary claim was not adjudicated. We do not use.
					}
					if(IsClaimConnect(clearhouse)) {
						//2320 DMG: Other subscriber demographics. This segment is not allowed in X12. ClaimConnect requires this information anyway. They will fix their validator later.
						sw.Write("DMG"+s
							+"D8"+s//DMG01 2/3 Date Time Period Format Qualifier: D8=Date Expressed in Format CCYYMMDD.
							+otherSubsc.Birthdate.ToString("yyyyMMdd")+s//DMG02 1/35 Date Time Period: Birthdate. The othet subscriber birtdate is validated.
							+GetGender(otherSubsc.Gender));//DMG03 1/1 Gender Code: F=Female, M=Male, U=Unknown.
							EndSegment(sw);
					}
					//2320 OI: (medical,institutional,dental) Other Insurance Coverage Information.
					sw.Write("OI"+s
						+s//OI01 1/2 Claim Filing Indicator Code: Not used.
						+s//OI02 2/2 Claim Submission Reason Code: Not used.
						+(otherSub.AssignBen?"Y":"N")+s//OI03 1/1 Yes/No Condition or Response Code:
						+s//OI04 1/1 Patient Signature Source Code: Not used in institutional or dental. Situational in medical, but we do not support.
						+s//OI05 1/1 Provider Agreement Code: Not used.
						+(otherSub.ReleaseInfo?"Y":"I"));//OI06 1/1 Release of Information Code:
					EndSegment(sw);
					//2320 MIA: (institutional) Inpatient Adjudication Information. Situational. We do not support.
					//2320 MOA: (medical,institutional,dental) Outpatient Adjudication Information. Situational. For reporting remark codes from ERAs. We don't support.
					#endregion 2320 Other subscriber information
					#region 2330A Other subscriber Name
					//2330A NM1: IL (medical,institutional,dental) Other Subscriber Name.
					sw.Write("NM1"+s
						+"IL"+s//NM101 2/3 Entity Identifier Code: IL=Insured or Subscriber.
						+"1"+s//NM102 1/1 Entity Type Qualifier: 1=Person.
						+Sout(otherSubsc.LName,60)+s//NM103 1/60 Name Last or Organization Name: Never blank, because validated in the patient edit window when a patient is added/edited.
						+Sout(otherSubsc.FName,35)+s//NM104 1/35 Name First:
						+Sout(otherSubsc.MiddleI,25)+s//NM105 1/25 Middle Name:
						+s//NM106 1/10 Name Prefix: Not used.
						+s//NM107 1/10 Name Suffix: Situational. No corresponding field in OD.
						+"MI"+s//NM108 1/2 Identification Code Qualifier: MI=Member Identification Number.
						+Sout(otherSub.SubscriberID,80));//NM109 2/80 Identification Code:
					EndSegment(sw);//NM110 through NM112 are not used.
					//2330A N3: Other Subscriber Address.
					sw.Write("N3"+s+Sout(otherSubsc.Address,55));//N301 1/55 Address Information:
					if(otherSubsc.Address2!="") {
						sw.Write(s+Sout(otherSubsc.Address2,55));
					}
					EndSegment(sw);//N302 1/55 Address Information:
					//2330A N4: (medical,institutional,dental) Other Subscriber City, State, Zip Code.
					sw.Write("N4"+s
						+Sout(otherSubsc.City,30)+s//N401 2/30 City Name:
						+Sout(otherSubsc.State,2,2)+s//N402 2/2 State or Province Code:
						+Sout(otherSubsc.Zip.Replace("-",""),15));//N403 3/15 Postal Code:
					EndSegment(sw);//N404 through N407 are either not required or are required when the address is outside of the United States.
					//2330A REF: (medical,institutional,dental) Other Subscriber Secondary Identification. Situational. Not supported.
					#endregion 2330A Other subscriber Name
					#region Other payer
					//2330B NM1: (medical,institutional,dental) Other Payer Name.
					sw.Write("NM1"+s
						+"PR"+s//NM101 2/3 Entity Code Identifier: PR=Payer.
						+"2"+s);//NM102 1/1 Entity Type Qualifier: 2=Non-Person.
					//NM103 1/60 Name Last or Organization Name:
					if(IsEMS(clearhouse)) {
						long employerNum=0;
						if(otherPlan!=null) {
							employerNum=otherPlan.EmployerNum;
						}
						//This is a special situation requested by EMS.  This tacks the employer onto the end of the carrier.
						sw.Write(Sout(otherCarrier.CarrierName,30)+"|"+Sout(Employers.GetName(employerNum),30)+s);
					}
					else if(IsDentiCal(clearhouse)) {
						sw.Write("DENTICAL"+s);
					}
					else {
						sw.Write(Sout(otherCarrier.CarrierName,60)+s);
					}
					sw.Write(s//NM104 1/35 Name First: Not used.
						+s//NM105 1/25 Name Middle: Not used.
						+s//NM106 1/10 Name Prefix: Not used.
						+s//NM107 1/10 Name Suffix: Not used.
						+"PI"+s);//NM108 1/2 Identification Code Qualifier: PI=Payor Identification. XV must be used after national plan ID mandated.
					sw.Write(Sout(GetCarrierElectID(otherCarrier,clearhouse),80,2));//NM109 2/80 Identification Code:
					EndSegment(sw);//NM110 through NM112 not used.
					//2230B N3: (medical,institutional,dental) Other Payer Address. Situational. We don't support.
					//2330B N4: (medical,institutional,dental) Other Payer City, State, Zip Code. Situational. We don't support.
					//2330B DTP: 573 (medical,institutional,dental) Claim Check or Remittance Date. Situational. Claim Paid date.
					if(hasAdjForOtherPlans) {
						DateTime datePaidOtherIns=DateTime.Today;
						DateTime dtThisCP;
						for(int j=0;j<claimProcs.Count;j++) {
							dtThisCP=ClaimProcs.GetDatePaid(claimProcList,claimProcs[j].ProcNum,claimProcs[j].PlanNum);
							if(dtThisCP>datePaidOtherIns) {
								datePaidOtherIns=dtThisCP;
							}
						}
						//it's a required segment, so always include it.
						sw.Write("DTP"+s
							+"573"+s//DTP01 3/3 Date/Time Qualifier: 573=Date Claim Paid.
							+"D8"+s//DTP02 2/3 Date Time Period Format Qualifier: D8=Date Expressed in Format CCYYMMDD.
							+datePaidOtherIns.ToString("yyyyMMdd"));//DTP03 1/35 Date Time Period:
						EndSegment(sw);
					}
					//2330B REF: (medical,institutional,dental) Other Payer Secondary Identifier. Situational. We do not use.
					//2330B REF: G1 (medical,institutional,dental) Other Payer Prior Authorization Number. Situational. We do not use.
					//2330B REF: 9F (medical,institutional,dental) Other Payer Referral Number. Situational. We do not use.
					//2330B REF: T4 (medical,institutional,dental) Other Payer Claim Adjustment Indicator. Situational. We do not use.
					//2330B REF: G3 (dental) Other Payer Predetermination Identification. Situational. We do not use.
					//2230B REF: F8 (medical,institutional,dental) Other Payer Claim Control Number. Situational. We do not use.					
					if(medType==EnumClaimMedType.Medical) {
						//2330C NM1: (medical) Other Payer Referring Provider. Situational. Only used in crosswalking COBs. We do not use.
						//2330C REF: (medical) Other Payer Referring Provider Secondary Identification. We do not use.
						//2330D NM1: 82 (medical) Other Payer Rendering Provider. Situational. Only used in crosswalking COBs. We do not use.
						//2330D REF: (medical) Other Payer Rendering Provider Secondary Identificaiton. We do not use.
						//2330E NM1: 77 (medical) Other Payer Service Facility Location. Situational. We do not use.
						//2330E REF: (medical) Other Payer Service Facility Location Secondary Identification. We do not use.
						//2330F NM1: DQ (medical) Other Payer Supervising Provider. Situational. We do not use.
						//2330F REF: (medical) Other Payer Supervising Provider Secondary Identificaiton. We do not use.
						//2330G NM1: 85 (medical) Other Payer Billing Provider. Situational. We do not use.
						//2330G REF: (medical) Other Payer Billing Provider Secondary Identification. We do not use.
					}
					else if(medType==EnumClaimMedType.Institutional) {
						//2330C NM1: 71 (institutional) Other Payer Attending Provider. Situational. Only used in crosswalking COBs. We do not use.
						//2330C REF: (institutional) Other Payer Attending Provider Secondary Identification. We do not use.
						//2330D NM1: 72 (institutional) Other Payer Operating Physician. Situational.
						//2330D REF: (institutional) Other Payer Operating Physician Secondary Identificaiton. We do not use.
						//2330E NM1: ZZ (institutional) Other Payer Other Operating Physician. Situational. We do not use.
						//2330E REF: (institutional) Other Payer Other Operating Physician Secondary Identificaiton. We do not use.
						//2330F NM1: 77 (institutional) Other Payer Service Facility Location. Situational. We do not use.
						//2330F REF: (institutional) Other Payer Service Facility Location Secondary Identification. We do not use.
						//2330G NM1: 82 (institutional) Other Payer Rendering Provider Name. Situatiuonal. We do not use.
						//2330G REF: (institutional) Other Payer Rendering Provider Secondary Identificaiton. We do not use.
						//2330H NM1: DN (institutional) Other Payer Referring Provider. Situational. We do not use.
						//2330H REF: (institutional) Other Payer Referring Provider Secondary Identificaiton. We do not use.
						//2330I NM1: 85 (institutional) Other Payer Billing Provider. Situational. We do not use.
						//2330I REF: (institutional) Other Payer Billing Provider Secondary Identification. We do not use.
					}
					else if(medType==EnumClaimMedType.Dental) {
						//2330C NM1: (dental) Other Payer Referring Provider. Situational. Only used in crosswalking COBs. We do not use.
						//2330C REF: (dental) Other Payer Referring Provider Secondary Identification. We do not use.
						//2330D NM1: 82 (dental) Other Payer Rendering Provider. Situational. Only used in crosswalking COBs. We do not use.
						//2330D REF: (dental) Other Payer Rendering Provider Secondary Identificaiton. We do not use.
						//2330E NM1: DQ (dental) Other Payer Supervising Provider. Situational. We do not use.
						//2330E REF: (dental) Other Payer Supervising Provider Secondary Identificaiton. We do not use.
						//2330F NM1: 85 (dental) Other Payer Billing Provider. Situational. We do not use.
						//2330F REF: (dental) Other Payer Billing Provider Secondary Identification. We do not use.
						//2330G NM1: 77 (dental) Other Payer Service Facility Location. Situational. We do not use.
						//2330G REF: (dental) Other Payer Service Facility Location Secondary Identification. We do not use.
						//2330H NM1: DD (dental) Other Payer Assistant Sugeon. Situational. We do not use.
						//2330H REF: (dental) Other Payer Assistant Surgeon Secondary Identifier. We do not use.
					}
					#endregion Other payer
				}
				for(int j=0;j<claimProcs.Count;j++) {
					#region Service Line
					proc=Procedures.GetProcFromList(procList,claimProcs[j].ProcNum);
					procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
					//2400 LX: Service Line Number.
					sw.Write("LX"+s+(j+1).ToString());//LX01 1/6 Assigned Number:
					EndSegment(sw);
					if(medType==EnumClaimMedType.Medical) {
						//2400 SV1: Professional Service.
						sw.Write("SV1"+s
							//SV101 Composite Medical Procedure Identifier
							+"HC"+isa16//SV101-1 2/2 Product/Service ID Qualifier: HC=Health Care.
							+Sout(claimProcs[j].CodeSent));//SV101-2 1/48 Product/Service ID: Procedure code. The rest of SV101 is not supported.
						if(proc.CodeMod1!="" || proc.CodeMod2!="" || proc.CodeMod3!="" || proc.CodeMod4!="" || proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.CodeMod1));//SV101-3 2/2 Procedure Modifier: Situational.
						}
						if(proc.CodeMod2!="" || proc.CodeMod3!="" || proc.CodeMod4!="" || proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.CodeMod2));//SV101-4 2/2 Procedure Modifier: Situational.
						}
						if(proc.CodeMod3!="" || proc.CodeMod4!="" || proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.CodeMod3));//SV101-5 2/2 Procedure Modifier: Situational.
						}
						if(proc.CodeMod4!="" || proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.CodeMod4));//SV101-6 2/2 Procedure Modifier: Situational.
						}
						if(proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.ClaimNote,80));//SV101-7 1/80 Description: Situational.
						}
						sw.Write(s//SV101-8 is not used.
							+claimProcs[j].FeeBilled.ToString()+s);//SV102 1/18 Monetary Amount: Charge Amt.
						if(proc.UnitQtyType==ProcUnitQtyType.MinutesAnesth) {
							sw.Write("MJ"+s);//SV103 2/2 Unit or Basis for Measurement Code: MJ=minutes, UN=Unit.
						}
						else {
							sw.Write("UN"+s);//SV103 2/2 Unit or Basis for Measurement Code: MJ=minutes, UN=Unit.
						}
						sw.Write(proc.UnitQty+s);//SV104 1/15 Quantity: Service Unit Count or Anesthesia Minutes.
						if(proc.PlaceService!=claim.PlaceService) {
							sw.Write(GetPlaceService(proc.PlaceService));
						}
						sw.Write(s//SV105 1/2 Facility Code Value: Place of Service Code if different from claim.
							+s);//SV106 1/2 Service Type Code: Not used.
						//SV107: Composite Diagnosis Code Pointer. Required when 2300HI(Health Care Diagnosis Code) is used (always).
						//SV107-1: Primary diagnosis. Only allowed pointers 1-8 even though 2300HI supports 12 diagnoses.
						//We don't validate that there are not more than 8 diagnoses on one claim.
						//If the diagnosis we need is not in the first 8, then we will use the primary.
						if(proc.DiagnosticCode=="") {//If the diagnosis is blank, we will use the primary.
							sw.Write("1");//use primary.
						}
						else {
							int diagI=1;
							for(int d=0;d<diagnosisList.Count;d++) {
								if(d>7) {//we can't point to any except first 8.
									continue;
								}
								if((string)diagnosisList[d]==proc.DiagnosticCode) {
									diagI=d+1;
								}
							}
							sw.Write(diagI.ToString());
						}
						//SV107-2 through SV107-4: Other diagnoses, which we don't support yet.
						EndSegment(sw);//SV108 through SV121 are not used or situational. We do not use.
					}
					else if(medType==EnumClaimMedType.Institutional) {
						//2400 SV2: Institutional Service Line.
						sw.Write("SV2"+s
							+Sout(proc.RevCode,48)+s//SV201 1/48 Product/Service ID: Revenue Code, validated.
							//SV202 Composite Medical Procedure Identifier
							+"HC"+isa16//SV202-1 2/2 Product/Service ID Qualifier: HC=Health Care. Includes CPT codes.
							+Sout(claimProcs[j].CodeSent));//SV202-2 1/48 Product/Service ID: Procedure code. 
						//mods validated to be exactly 2 char long or else blank.
						if(proc.CodeMod1!="" || proc.CodeMod2!="" || proc.CodeMod3!="" || proc.CodeMod4!="" || proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.CodeMod1));//SV202-3 2/2 Procedure Modifier: Situational.
						}
						if(proc.CodeMod2!="" || proc.CodeMod3!="" || proc.CodeMod4!="" || proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.CodeMod2));//SV202-4 2/2 Procedure Modifier: Situational.
						}
						if(proc.CodeMod3!="" || proc.CodeMod4!="" || proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.CodeMod3));//SV202-5 2/2 Procedure Modifier: Situational.
						}
						if(proc.CodeMod4!="" || proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.CodeMod4));//SV202-6 2/2 Procedure Modifier: Situational.
						}
						if(proc.ClaimNote!="") {
							sw.Write(isa16+Sout(proc.ClaimNote,80));//SV202-7 1/80 Description: Situational.
						}
						sw.Write(s//SV202-8 is not used.
							+claimProcs[j].FeeBilled.ToString()+s);//SV203 1/18 Monetary Amount: Charge Amt.
						if(proc.UnitQtyType==ProcUnitQtyType.Days) {
							sw.Write("DA"+s);//SV204 2/2 Unit or Basis for Measurement Code: DA=Days, UN=Unit.
						}
						else {
							sw.Write("UN"+s);//SV204 2/2 Unit or Basis for Measurement Code: DA=Days, UN=Unit.
						}
						sw.Write(proc.UnitQty.ToString());//SV205 1/15 Quantity:
						EndSegment(sw);//SV206,208,209 and 210 are not used, SV207 is situational but we do not use.
					}
					else if(medType==EnumClaimMedType.Dental) {
						//2400 SV3: Dental Service.
						sw.Write("SV3"+s
								+"AD"+isa16//SV301-1 2/2 Product/Service ID Qualifier: AD=American Dental Association Codes
								+Sout(claimProcs[j].CodeSent,5));//SV301-2 1/48 Product/Service ID: Procedure code
						if(proc.ClaimNote!="") {
							sw.Write(isa16//SV301-3 2/2 Procedure Modifier: Situational. We do not use.
								+isa16//SV301-4 2/2 Procedure Modifier: Situational. We do not use.
								+isa16//SV301-5 2/2 Procedure Modifier: Situational. We do not use.
								+isa16//SV301-6 2/2 Procedure Modifier: Situational. We do not use.
								+isa16+Sout(proc.ClaimNote,80));//SV301-7 1/80 Description: Situational.
						}
						sw.Write(s//SV301-8 is not used.
							+claimProcs[j].FeeBilled.ToString());//SV302 1/18 Monetary Amount: Charge Amount.
						string placeService="";
						if(proc.PlaceService!=claim.PlaceService) {
							placeService=GetPlaceService(proc.PlaceService);
						}
						string area=GetArea(proc,procCode);
						int unitQty=Math.Max(proc.UnitQty,1);//Minimum of 1
						bool includeUnits=false;
						if(unitQty>=2) {//Standard behavior based on the X12 guide.
							includeUnits=true;
						}
						//The following carriers always want to see the unit quantity, even if it is only 1.
						if(IsColoradoMedicaid(clearhouse) || IsWashingtonMedicaid(clearhouse,carrier)) {
							includeUnits=true;
						}
						if(placeService!="" || area!="" || proc.Prosthesis!="" || includeUnits) {
							sw.Write(s+placeService);//SV303 1/2 Facility Code Value: Location Code if different from claim.
						}
						if(area!="" || proc.Prosthesis!="" || includeUnits) {
							sw.Write(s+area);//SV304 Oral Cavity Designation: SV304-1 1/3 Oral Cavity Designation Code: Area. SV304-2 through SV304-5 are situational and we do not use.
						}
						if(proc.Prosthesis!="" || includeUnits) {
							sw.Write(s+proc.Prosthesis);//SV305 1/1 Prothesis, Crown or Inlay Code: I=Initial Placement. R=Replacement.
						}
						if(includeUnits) {
							sw.Write(s+unitQty.ToString());//SV306 1/15 Quantity: Situational. Procedure count.
						}
						EndSegment(sw);//SV307 throug SV311 are either not used or are situational and we do not use.
						//2400 TOO: Tooth Information. Number/Surface. Multiple iterations of the TOO segment are allowed only when the quantity reported in Loop ID-2400 SV306 is equal to one.
						if(procCode.TreatArea==TreatmentArea.Tooth) {
							sw.Write("TOO"+s
								+"JP"+s//TOO01 1/3 Code List Qualifier Code: JP=Universal National Tooth Designation System.
								+proc.ToothNum);//TOO02 1/30 Industry Code: Tooth number.
							EndSegment(sw);//TOO03 Tooth Surface: Situational. Not applicable.
						}
						else if(procCode.TreatArea==TreatmentArea.Surf) {
							sw.Write("TOO"+s
								+"JP"+s//TOO01 1/3 Code List Qualifier Code: JP=Universal National Tooth Designation System.
								+proc.ToothNum+s);//TOO02 1/30 Industry Code: Tooth number.
							string validSurfaces=Tooth.SurfTidyForClaims(proc.Surf,proc.ToothNum);
							for(int k=0;k<validSurfaces.Length;k++) {
								if(k>0) {
									sw.Write(isa16);
								}
								sw.Write(validSurfaces.Substring(k,1));//TOO03 Tooth Surface: TOO03-1 through TOO03-5 are for individual surfaces.
							}
							EndSegment(sw);
						}
						else if(procCode.TreatArea==TreatmentArea.ToothRange) {
							string[] individTeeth=proc.ToothRange.Split(',');
							for(int t=0;t<individTeeth.Length;t++) {
								sw.Write("TOO"+s
									+"JP"+s//TOO01 1/3 Code List Qualifier Code: JP=Universal National Tooth Designation System.
									+individTeeth[t]);//TOO02 1/30 Industry Code: Tooth number.
								EndSegment(sw);//TOO03 Tooth Surface: Situational. Not applicable.
							}
						}
					}//dental
					#endregion Service Line
					//2400 PWK: (institutional) Line Supplemental Information. Situational. We do not use.
					//2400 CRC: (medical) Condition Indicator/Durable Medical Equipment. Situational. We do not use.
					#region Service DTP
					//2400 DTP: 472 (medical,institutional,dental) Service Date. Situaitonal. Required for medical. Required if different from claim for dental and inst.
					if(claim.ClaimType!="PreAuth") {
						bool useProcDateService=false;
						//Always required for medical because there is no date of service at the claim level.
						if(medType==EnumClaimMedType.Medical) {
							useProcDateService=true;
						}
						else { //Institutional and dental.
							//Standard X12 behavior, preferred by the following clearinghouses: EmdeonDental.
							//Required for institutional and dental when procedure date of service is different from the claim date of service.
							if(proc.ProcDate!=claim.DateService) {
								useProcDateService=true;
							}
						}
						//The following clearinghouses always want this segment no matter what: Apex, Inmediata.
						if(IsApex(clearhouse) || IsInmediata(clearhouse)) {
							useProcDateService=true;
						}
						if(useProcDateService) {
							sw.Write("DTP"+s
								+"472"+s//DTP01 3/3 Date/Time Qualifier: 472=Service.
								+"D8"+s//DTP02 2/3 Date Time Period Format Qualifier: D8=Date Expressed in Format CCYYMMDD.
								+proc.ProcDate.ToString("yyyyMMdd"));//DTP03 1/35 Date Time Period:
							EndSegment(sw);
						}
					}
					//2400 DTP: 139/441 (dental) Date Prior Placement. Situational. Required when replacement.
					if(proc.Prosthesis=="R") {//already validated date
						sw.Write("DTP"+s
							+"441"+s//DTP01 3/3 Date/Time Qualifier: 441=Prior Placement.
							+"D8"+s//DTP02 2/3 Date Time Period Format Qualifier: D8=Date Expressed in Format CCYYMMDD.
							+proc.DateOriginalProsth.ToString("yyyyMMdd"));//DTP03 1/35 Date Time Period:
						EndSegment(sw);
					}
					//2400 DTP: 452 (dental) Date Appliance Placement. Situational. Ortho appliance placement. We do not use.
					//2400 DTP: 446 (dental) Date Replacement. Date ortho appliance replaced. We do not use.
					//2400 DTP: 196 (medical,dental) Date Treatment Start. Situational. Rx date. We do not use.
					//2400 DTP: 198 (dental) Date Treatment Completion. Situational. We do not use.
					//2400 DTP: 471 (medical) Prescription Date: Situational. We do not use.
					//2400 DTP: 607 (medical) Date Certification Revision/Recertification. Situational. Not supported.
					//2400 DTP: 463 (medical) Date Begin Therapy. Situational. Not supported.
					//2400 DTP: 461 (medical) Date Last Certification. Situational. Not supported.
					//2400 DTP: 304 (medical) Date Last Seen. Situational. Not supported.
					//2400 DTP: 738/739 (medical) Test Date. Situational. For Dialysis. Not supported.
					//2400 DTP: 011 (medical) Date Shipped. Situational. Not supported.
					//2400 DTP: 455 (medical) Date Last X-Ray. Situational. Not supported.
					//2400 DTP: 454 (medical) Date Initial Treatment. Situational. Not supported.					
					#endregion Service DTP
					#region Service QTY MEA CN1
					//2400 QTY: PT (medical) Ambulance Patient Count. Situational. Not supported.
					//2400 QTY: FL (medical) Obstetric Anesthesia Additional Units. Situational. Anesthesia quantity. We do not use.
					//2400 MEA: (medical) Test Result. Situational. We do not use.
					//2400 CN1: (medical,dental) Contract Information. Situational. We do not use.
					#endregion Service QTY MEA CN1
					#region Service REF
					//2400 REF: G3 (dental) Service Predetermination Identification. Situational. Pretermination ID. We do not use.
					//2400 REF: G1 (medical,dental) Prior Authorization. Situational. We do not use.
					//2400 REF: 9F (medical,dental) Referral Number. Situational. We do not use.
					//2400 REF: 9A (dental) Repriced Claim Number. Situational. We do not use.
					//2400 REF: 9B (medical,institutional) Repriced Line Item Reference Number. Situational. We do not use.
					//2400 REF: 9C (dental) Adjusted Repriced claim Number. Situational. We do not use.
					//2400 REF: 9D (medical,instituitonal) Adjusted Repriced Line Item Reference Number. Situational. We do not use.
					//2400 REF: 6R (medical,institutional,dental) Line Item Control Number. ProcNum. Will later be used for ERAs.
					sw.Write("REF"+s
						+"6R"+s//REF01 2/3 Reference Identification Qualifier: 6R=Procedure Control Number.
						+proc.ProcNum.ToString());//REF02 1/50 Reference Identification: 
					EndSegment(sw);//REF03 and REF04 are not used.
					//2400 REF: EW (medical) Mammography Certification Number. Situational. We do not use.
					//2400 REF: X4 (medical) Clinical Laboratory Improvement Amendment (CLIA) Number. Situational. We do not use.
					//2400 REF: F4 (medical) Referring Clinical Laboratory Improvement Amendment (CLIA) Facility Identification. Situational. We do not use.
					//2400 REF: BT (medical) Immunization Batch Number. Situational. We do not use.
					#endregion Service REF
					#region Service AMT K3 NTE PS1 HCP LIN CTP
					//2400 AMT: T (medical,dental) Sales Tax Amount. Situational. Not supported.
					//2400 AMT: F4 (medical) Postage Claimed Amount. Situational. We do not use.
					//2400 AMT GT (institutional) Service Tax Amount. Situational. Not supported.
					//2400 AMT N8 (institutional) Facility Tax Amount. Situational. Not supported.
					//2400 K3: (medical,dental) File Information. Situational. Not supported.
					//2400 NTE: ADD/DCP (medical) Line Note. Situational. We do not use.
					//2400 NTE: TPO (medical,institutional) Third Party Organization Notes. Situational. Not sent by providers. Not supported.
					//2400 PS1: (medical) Purchased Service Information. Situational. We do not use.
					//2400 HCP: (medical,institutional,dental) Line Pricing/Repricing Information. Situational. Not used by providers. Not supported.
					#endregion Service AMT K3 NTE PS1 HCP
					#region 2410 Service Drug Identification
					//2410 LIN,CTP,REF: (medical) ?
					if(medType==EnumClaimMedType.Medical || medType==EnumClaimMedType.Institutional) {
						//2410 LIN: (medical,institutional) Drug Identification
						if(procCode.DrugNDC!="" && proc.DrugQty>0){
							sw.Write("LIN"+s+s//LIN01 1/20 Assigned Identification: Not used.
								+"N4"+s//LIN02 2/2 Product/Service ID Qualifier: N4=NDC code in 5-4-2 format, no dashes.
								+procCode.DrugNDC);//LIN03 1/48 Product/Service ID: NDC.
							EndSegment(sw);//LIN04 through LIN31 not used.
							//2410 CTP: (medical,institutional) Drug Quantity.
							sw.Write("CTP"+s+s+s+s//CTP01 through CTP03 not used.
								+proc.DrugQty.ToString()+s//CTP04 1/15 Quantity:
								+GetDrugUnitCode(proc.DrugUnit));//CTP05-1 2/2 Unit or Basis for Measurement Code: Code Qualifier, validated to not be None.
							EndSegment(sw);//CTP05-2 through CTP05-15 not used. CTP06 through CTP11 not used.
							//2410 REF (inst) Rx or compound drug association number.  Not supported.
						}
					}
					#endregion 2410 Service Drug Identification
					Provider provTreatProc=provTreat;//procedure level treating provider.
					//2410 REF: VY/XZ (medical,institutional) Prescription or Compound Drug Association Number. Situational. We do not use.
					#region 2420 Service Providers (medical)
					if(medType==EnumClaimMedType.Medical) {
						if(claim.ProvTreat!=proc.ProvNum
							&& PrefC.GetBool(PrefName.EclaimsSeparateTreatProv)) {
							//2420A NM1: 82 (medical) Rendering Provider Name. Only if different from the claim.
							provTreatProc=Providers.GetProv(proc.ProvNum);
							WriteNM1Provider("82",sw,provTreatProc);
							//2420A PRV: (medical) Rendering Provider Specialty Information.
							sw.Write("PRV"+s
								+"PE"+s//PRV01 1/3 Provider Code: PE=Performing.
								+"PXC"+s//PRV02 2/3 Reference Identification Qualifier: PXC=Health Care Provider Taxonomy Code.
								+X12Generator.GetTaxonomy(provTreatProc));//PRV03 1/50 Reference Identification: Taxonomy Code.
							EndSegment(sw);//PRV04 through PRV06 not used.
							//2420A REF: (medical) Rendering Provider Secondary Identification.
							sw.Write("REF"+s
								+"0B"+s//REF01 2/3 Reference Identification Qualifier: 0B=State License Number.
								+Sout(provTreatProc.StateLicense,50));//REF02 1/50 Reference Identification: 
							EndSegment(sw);//REF03 1/80 Description: Not used. REF04 Reference Identifier: Situational. Not used when REF01 is 0B or 1G.
						}
						//2420B NM1: Purchased Service Provider Name. Situational. We do not use.
						//2420B REF: Purchased Service Provider Secondary Identificaiton. Situational. We do not use.
						//2420C NM1: 77 (medical) Service Facility Location Name. Situational. We enforce all procs on a claim being performed at the same location so we don't need this.
						//2420C N3: (medical) Service Facility Location Address. We do not use.
						//2420C N4: (medical) Service Facility Location City, State, Zip Code. We do not use.
						//2420C REF: (medical) Service Facility Location Secondary Identification. Situational. We do not use.
						//2420D NM1: DQ (medical) Supervising Provider Name. Situational. We do not support.
						//2420D REF: (medical) Supervising Provider Secondary Identification. Situational. We do not support.
						//Emdeon Medical requires loop 2420E when the claim is sent to DMERC (Medicaid) carriers. This loop can only be used for a provider that is a person, not an organization, so we don't send this loop if not a person.
						if(!provTreatProc.IsNotPerson) { //Treating provider is a person.
							//2420E NM1: DK (medical) Ordering Provider Name. Situational. Required to be a person.
							WriteNM1Provider("DK",sw,provTreatProc);
							//2420E N3: (medical) Ordering Provider Address. Situational.
							sw.Write("N3"+s+Sout(billingAddress1,55));//N301 1/55 Address Information:
							if(billingAddress2!="") {
								sw.Write(s+Sout(billingAddress2,55));//N302 1/55 Address Information: Only required when there is a secondary address line.
							}
							EndSegment(sw);
							//2420E N4: (medical) Ordering Provider City, State, Zip Code. Situational.
							sw.Write("N4"+s
								+Sout(billingCity,30)+s//N401 2/30 City Name:
								+Sout(billingState,2,2)+s//N402 2/2 State or Provice Code:
								+Sout(billingZip.Replace("-",""),15));//N403 3/15 Postal Code:
							EndSegment(sw);//N404 through N407 are either not used or only required when outside of the United States.						
							//2420E REF: (medical) Ordering Provider Secondary Identification. Situational. Required before NPIs were in effect. We do not use this segment because we require NPI.
							//2420E PER: (medical) Ordering Provider Contact Information. Situational.
							sw.Write("PER"+s
								+"IC"+s//PER01 2/2 Contact Function Code: IC=Information Contact.
								+Sout(PrefC.GetString(PrefName.PracticeTitle),60)+s//PER02 1/60 Name: Practice Title.
								+"TE"+s);//PER03 2/2 Communication Number Qualifier: TE=Telephone.
							if(clinic==null) {
								sw.Write(Sout(PrefC.GetString(PrefName.PracticePhone),256));//PER04 1/256 Communication Number: Telephone number.
							}
							else {
								sw.Write(Sout(clinic.Phone,256));//PER04 1/256 Communication Number: Telephone number.
							}
							EndSegment(sw);//PER05 through PER08 are situational and PER09 is not used. We do not use.
						}
						//2420F NM1: (medical) Referring Provider Name. Situational. We do not use.
						//2420F REF: (medical) Referring Provider Secondary Identification. Situational. We do not use.
						//2420G NM1: PW (medical) Ambulance Pick-up Location. Situational. We do not use.
						//2420G N3: (medical) Ambulance Pick-up Location Address. We do not use.
						//2420G N4: (medical) Ambulance Pick-up Location City, State, Zip Code. We do not use.
						//2420H NM1: (medical) Ambulance Drop-off Location. Situational. We do not use.
						//2420H N3: (medical) Ambulance Drop-off Location Address. We do not use.
						//2420H N4: (medical) Ambulance Drop-off Location City, State, Zip Code. We do not use.
					}
					#endregion 2420 Service Providers (medical)
					#region 2420 Service Providers (inst)
					if(medType==EnumClaimMedType.Institutional) {
						//2420A NM1: 72 (institutional) Operating Physician Name. Situational. Only for surgical procedures. We don't support.
						//2420A REF: (instititional) Operating Physician Secondary Identification. Situational. Only for surgical procedures. We don't support.						
						//2420B NM1: ZZ (institutional) Other Operating Physician Name. Situational. We don't support.
						//2420B REF: (institutional) Other Operating Physician Secondary Identification. Situational. We don't support.
						if(claim.ProvTreat!=proc.ProvNum
							&& PrefC.GetBool(PrefName.EclaimsSeparateTreatProv)) 
						{
							provTreatProc=Providers.GetProv(proc.ProvNum);
							//2420C NM1: 82 (institutional) Rendering Provider Name. Situational. Only if different than claim attending (treating) prov. Person only, non-person not allowed.
							WriteNM1Provider("82",sw,provTreatProc.FName,provTreatProc.MI,provTreatProc.LName,provTreatProc.NationalProvID,false);
							//2420C REF: Rendering Provider Secondary Identification. Situational.
							sw.Write("REF"+s
								+"0B"+s//REF01 2/3 Reference Identification Qualifier: 0B=State License Number.
								+Sout(provTreatProc.StateLicense,50));//REF02 1/50 Reference Identification: Valided to be present.
							EndSegment(sw);//REF03 through REF04 are not used or situational.
						}
						//2420D NM1: DN (institutional) Referring Provider Name. Situational. We do not use.
						//2420D REF: (institutional) Referring Provider Secondary Identification. Situational. We do not use.
					}
					#endregion 2420 Service Providers (inst)
					#region 2420 Service Providers (dental)
					if(medType==EnumClaimMedType.Dental) {
						if(claim.ProvTreat!=proc.ProvNum
							&& PrefC.GetBool(PrefName.EclaimsSeparateTreatProv)) 
						{
							//2420A NM1: 82 (dental) Rendering Provider Name. Only if different from the claim.
							provTreatProc=Providers.GetProv(proc.ProvNum);
							WriteNM1Provider("82",sw,provTreatProc);
							//2420A PRV: (dental) Rendering Provider Specialty Information.
							sw.Write("PRV"+s
								+"PE"+s//PRV01 1/3 Provider Code: PE=Performing.
								+"PXC"+s//PRV02 2/3 Reference Identification Qualifier: PXC=Health Care Provider Taxonomy Code.
								+X12Generator.GetTaxonomy(provTreatProc));//PRV03 1/50 Reference Identification: Taxonomy Code.
							EndSegment(sw);//PRV04 through PRV06 not used.
							//2420A REF: (dental) Rendering Provider Secondary Identification. Never required because we always send NPI (validated).
							if(!IsDentiCal(clearhouse)) { //Denti-Cal never wants this.
								if(provTreatProc.StateLicense!="") {
									sw.Write("REF"+s
										+"0B"+s//REF01 2/3 Reference Identification Qualifier: 0B=State License Number.
										+Sout(provTreatProc.StateLicense,50));//REF02 1/50 Reference Identification: 
									EndSegment(sw);//REF03 1/80 Description: Not used. REF04 Reference Identifier: Situational. Not used when REF01 is 0B or 1G.
								}
							}
						}
						//2420B NM1: DD (dental) Assistant Surgeon Name. Situational. We do not support.
						//2420B PRV: AS (dental) Assistant Surgeon Specialty Information. Situational. We do not support.
						//2420B REF: (dental) Assistant Surgeon Secondary Identification. Situational. We do not support.
						//2420C NM1: DQ (dental) Supervising Provider Name. Situational. We do not support.
						//2420C REF: (dental) Supervising Provider Secondary Identification. Situational. We do not support.
						//2420D NM1: 77 (dental) Service Facility Location Name. Situational. We enforce all procs on a claim being performed at the same location so we don't need this.
						//2420D N3: (dental) Service Facility Location Address. We do not use.
						//2420D N4: (dental) Service Facility Location City, State, Zip Code. We do not use.
						//2420D REF: (dental) Service Facility Location Secondary Identification. Situational. We do not use.
					}
					#endregion 2420 Service Providers (dental)
					//2430 SVD: (medical,institutional,dental) Line Adjudication Information. Situational. We do not support.   
					//2430 CAS: (medical,institutional,dental) Line Adjustment. Situational. Required when the payer identified in Loop 2330B made line level adjustments which caused the amount paid to differ from the amount originally charged.
					//These CAS segments at the procedure level should add up to their respective claim level 2320 CAS segments.
					//Claim Adjustment Reason Codes can be found on the Washington Publishing Company website at: http://www.wpc-edi.com/reference/codelists/healthcare/claim-adjustment-reason-codes/
					if(hasAdjForOtherPlans && IsApex(clearhouse)) {//This section of code might work for other clearinghouses, but has not yet been tested, and nobody else has requested this information yet.
						double procPatientPortionAmt=Math.Max(0,claimProcs[j].FeeBilled-listProcWriteoffAmts[j]-listProcDeductibleAmts[j]-listProcPaidOtherInsAmts[j]);
						if(listProcWriteoffAmts[j]>0) {
							sw.Write("CAS"+s
								+"CO"+s//CAS01 1/2 Claim Adjustment Group Code: CO=Contractual Obligations.
								+"45"+s//CAS02 1/5 Claim Adjustment Reason Code: 45=Charge exceeds fee schedule/maximum allowable or contracted/legislated fee arrangement.
								+AmountToStrNoLeading(listProcWriteoffAmts[j]));//CAS03 1/18 Monetary Amount:
							EndSegment(sw);
						}
						if(listProcDeductibleAmts[j]>0 || procPatientPortionAmt>0) {
							sw.Write("CAS"+s
								+"PR");//CAS01 1/2 Claim Adjustment Group Code: PR=Patient Responsibility.
							if(listProcDeductibleAmts[j]>0) {
								sw.Write(s//end of previous field
									+"1"+s//CAS02 1/5 Claim Adjustment Reason Code: 1=Deductible.
									+AmountToStrNoLeading(listProcDeductibleAmts[j])+s//CAS03 1/18 Monetary Amount:
									+"1");//CAS04 1/15 Quantity:
							}
							if(procPatientPortionAmt>0) {
								sw.Write(s//end of previous field
									+"3"+s//CAS02 or CAS05 1/5 Claim Adjustment Reason Code: 3=Co-payment Amount.
									+AmountToStrNoLeading(procPatientPortionAmt));//CAS03 or CAS06 1/18 Monetary Amount:
							}
							EndSegment(sw);
						}
					}
					//2430 DTP: (medical,institutional,dental) Line Check or Remittance Date. We do not support.
					//2430 AMT: (medical,institutional,dental) Remaining Patient Liability. We do not support.
					//2440 LQ: (medical) Form Identification Code. Situational. We do not use.
					//2440 FRM: (medical) Supporting Documentation. We do not use.
				}
			}
			#region Trailers
			//Transaction Trailer
			sw.Write("SE"+s
				+(seg+1).ToString()+s//SE01 1/10 Number of Included Segments: Total segments, including ST & SE. We add 1 for this SE segment, since the seg variable is not incremented until after this segment is written.
				+transactionNum.ToString().PadLeft(4,'0'));//SE02 4/9 Transaction Set Control Number:
			EndSegment(sw);
			//Functional Group Trailer
			sw.Write("GE"+s+transactionNum.ToString()+s//GE01 1/6 Number of Transaction Sets Included.  Always 1 for us.
				+groupControlNumber//GE02 1/9 Group Control Number: Must be identical to GS06.
				+endSegment);
			#endregion Trailers
		}
Пример #7
0
		private static string GetCarrierElectID(Carrier carrier,Clearinghouse clearhouse) {
			string electid=carrier.ElectID;
			if(electid=="" && IsApex(clearhouse)) {//only for Apex
				return "PAPRM";//paper claims
			}
			if(electid=="" && IsTesia(clearhouse)) {//only for Tesia
				return "00000";//paper claims
			}
			if(electid.Length<3) {
				return "06126";//paper claims
			}
			return electid;
		}
Пример #8
0
 ///<summary>Fills the carrier fields on the form based on the specified carrierNum.</summary>
 private void FillCarrier2(long carrierNum)
 {
     selectedCarrier2=Carriers.GetCarrier(carrierNum);
     textCarrier2.Text=selectedCarrier2.CarrierName;
     textPhone2.Text=selectedCarrier2.Phone;
 }
Пример #9
0
 private void butOK_Click(object sender,EventArgs e)
 {
     if(  textBirthdate1.errorProvider1.GetError(textBirthdate1)!=""
         || textBirthdate2.errorProvider1.GetError(textBirthdate2)!=""
         || textBirthdate3.errorProvider1.GetError(textBirthdate3)!=""
         || textBirthdate4.errorProvider1.GetError(textBirthdate4)!=""
         || textBirthdate5.errorProvider1.GetError(textBirthdate5)!=""
         ){
         MsgBox.Show(this,"Please fix data entry errors first.");
         return;
     }
     //no validation on birthdate reasonableness.
     if(textLName1.Text=="" || textFName1.Text==""){
         MsgBox.Show(this,"Guarantor name must be entered.");
         return;
     }
     // Validate Insurance subscribers--------------------------------------------------------------------------------------------------------
     if((comboSubscriber1.SelectedIndex==2 || comboSubscriber2.SelectedIndex==2) && (textFName2.Text=="" || textLName2.Text=="")){
         MsgBox.Show(this,"Subscriber must have name entered.");
         return;
     }
     if((comboSubscriber1.SelectedIndex==3 || comboSubscriber2.SelectedIndex==3) && (textFName3.Text=="" || textLName3.Text=="")){
         MsgBox.Show(this,"Subscriber must have name entered.");
         return;
     }
     if((comboSubscriber1.SelectedIndex==4 || comboSubscriber2.SelectedIndex==4) && (textFName4.Text=="" || textLName4.Text=="")){
         MsgBox.Show(this,"Subscriber must have name entered.");
         return;
     }
     if((comboSubscriber1.SelectedIndex==5 || comboSubscriber2.SelectedIndex==5) && (textFName5.Text=="" || textLName5.Text=="")){
         MsgBox.Show(this,"Subscriber must have name entered.");
         return;
     }
     // Validate Insurance Plans--------------------------------------------------------------------------------------------------------------
     bool insComplete1=false;
     bool insComplete2=false;
     if(comboSubscriber1.SelectedIndex>0
         && textSubscriberID1.Text!=""
         && textCarrier1.Text!="")
     {
         insComplete1=true;
     }
     if(comboSubscriber2.SelectedIndex>0
         && textSubscriberID2.Text!=""
         && textCarrier2.Text!="")
     {
         insComplete2=true;
     }
     //test for insurance having only some of the critical fields filled in
     if(comboSubscriber1.SelectedIndex>0
         || textSubscriberID1.Text!=""
         || textCarrier1.Text!="")
     {
         if(!insComplete1){
             MsgBox.Show(this,"Subscriber, Subscriber ID, and Carrier are all required fields if adding insurance.");
             return;
         }
     }
     if(comboSubscriber2.SelectedIndex>0
         || textSubscriberID2.Text!=""
         || textCarrier2.Text!="")
     {
         if(!insComplete2){
             MsgBox.Show(this,"Subscriber, Subscriber ID, and Carrier are all required fields if adding insurance.");
             return;
         }
     }
     if(checkInsOne1.Checked
         || checkInsOne2.Checked
         || checkInsOne3.Checked
         || checkInsOne4.Checked
         || checkInsOne5.Checked)
     {
         if(!insComplete1){
             MsgBox.Show(this,"Subscriber, Subscriber ID, and Carrier are all required fields if adding insurance.");
             return;
         }
     }
     if(checkInsTwo1.Checked
         || checkInsTwo2.Checked
         || checkInsTwo3.Checked
         || checkInsTwo4.Checked
         || checkInsTwo5.Checked)
     {
         if(!insComplete2){
             MsgBox.Show(this,"Subscriber, Subscriber ID, and Carrier are all required fields if adding insurance.");
             return;
         }
     }
     //Validate Insurance subscriptions---------------------------------------------------------------------------------------------------
     if(insComplete1){
         if(!checkInsOne1.Checked
             && !checkInsOne2.Checked
             && !checkInsOne3.Checked
             && !checkInsOne4.Checked
             && !checkInsOne5.Checked)
         {
             MsgBox.Show(this,"Insurance information has been filled in, but has not been assigned to any patients.");
             return;
         }
         if(checkInsOne1.Checked && (textLName1.Text=="" || textFName1.Text=="")//Insurance1 assigned to invalid patient1
             || checkInsOne2.Checked && (textLName2.Text=="" || textFName2.Text=="")//Insurance1 assigned to invalid patient2
             || checkInsOne3.Checked && (textLName3.Text=="" || textFName3.Text=="")//Insurance1 assigned to invalid patient3
             || checkInsOne4.Checked && (textLName4.Text=="" || textFName4.Text=="")//Insurance1 assigned to invalid patient4
             || checkInsOne5.Checked && (textLName5.Text=="" || textFName5.Text=="")) //Insurance1 assigned to invalid patient5
         {
             MsgBox.Show(this,"Insurance information 1 has been filled in, but has been assigned to a patient with no name.");
             return;
         }
     }
     if(insComplete2){
         if(!checkInsTwo1.Checked
             && !checkInsTwo2.Checked
             && !checkInsTwo3.Checked
             && !checkInsTwo4.Checked
             && !checkInsTwo5.Checked)
         {
             MsgBox.Show(this,"Insurance information 2 has been filled in, but has not been assigned to any patients.");
             return;
         }
         if(checkInsTwo1.Checked && (textLName1.Text=="" || textFName1.Text=="")//Insurance2 assigned to invalid patient1
             || checkInsTwo2.Checked && (textLName2.Text=="" || textFName2.Text=="")//Insurance2 assigned to invalid patient2
             || checkInsTwo3.Checked && (textLName3.Text=="" || textFName3.Text=="")//Insurance2 assigned to invalid patient3
             || checkInsTwo4.Checked && (textLName4.Text=="" || textFName4.Text=="")//Insurance2 assigned to invalid patient4
             || checkInsTwo5.Checked && (textLName5.Text=="" || textFName5.Text=="")) //Insurance2 assigned to invalid patient5
         {
             MsgBox.Show(this,"Insurance information 2 has been filled in, but has been assigned to a patient with no name.");
             return;
         }
     }
     //End of validation------------------------------------------------------------------------------------------
     //Create Guarantor-------------------------------------------------------------------------------------------
     Patient guar=new Patient();
     guar.LName=textLName1.Text;
     guar.FName=textFName1.Text;
     if(listGender1.SelectedIndex==0){
         guar.Gender=PatientGender.Male;
     }
     else{
         guar.Gender=PatientGender.Female;
     }
     if(listPosition1.SelectedIndex==0){
         guar.Position=PatientPosition.Single;
     }
     else{
         guar.Position=PatientPosition.Married;
     }
     guar.Birthdate=PIn.Date(textBirthdate1.Text);
     guar.BillingType=PrefC.GetLong(PrefName.PracticeDefaultBillType);
     guar.PatStatus=PatientStatus.Patient;
     guar.PriProv=ProviderC.ListShort[comboPriProv1.SelectedIndex].ProvNum;
     if(comboSecProv1.SelectedIndex>0){
         guar.SecProv=ProviderC.ListShort[comboSecProv1.SelectedIndex-1].ProvNum;
     }
     guar.HmPhone=textHmPhone.Text;
     guar.Address=textAddress.Text;
     guar.Address2=textAddress2.Text;
     guar.City=textCity.Text;
     guar.State=textState.Text;
     guar.Zip=textZip.Text;
     guar.AddrNote=textAddrNotes.Text;
     guar.ClinicNum=Security.CurUser.ClinicNum;
     Patients.Insert(guar,false);
     Patient guarOld=guar.Copy();
     guar.Guarantor=guar.PatNum;
     Patients.Update(guar,guarOld);
     RefAttach refAttach;
     if(textReferral.Text!=""){
         //selectedReferral will already be set if user picked from list.
         //but, if selectedReferral doesn't match data in boxes, then clear it.
         if(selectedReferral!=null
             && (selectedReferral.LName!=textReferral.Text
             || selectedReferral.FName!=textReferralFName.Text))
         {
             selectedReferral=null;
         }
         if(selectedReferral==null){
             selectedReferral=new Referral();
             selectedReferral.LName=textReferral.Text;
             selectedReferral.FName=textReferralFName.Text;
             Referrals.Insert(selectedReferral);
         }
         //Now we will always have a valid referral to attach.  We will use it again for the other family members.
         refAttach=new RefAttach();
         refAttach.IsFrom=true;
         refAttach.RefDate=DateTime.Today;
         refAttach.ReferralNum=selectedReferral.ReferralNum;
         refAttach.PatNum=guar.PatNum;
         RefAttaches.Insert(refAttach);
     }
     //Patient #2-----------------------------------------------------------------------------------------------------
     Patient pat2=null;
     if(textFName2.Text!="" && textLName2.Text!=""){
         pat2=new Patient();
         pat2.LName=textLName2.Text;
         pat2.FName=textFName2.Text;
         if(listGender2.SelectedIndex==0){
             pat2.Gender=PatientGender.Male;
         }
         else{
             pat2.Gender=PatientGender.Female;
         }
         if(listPosition2.SelectedIndex==0){
             pat2.Position=PatientPosition.Single;
         }
         else{
             pat2.Position=PatientPosition.Married;
         }
         pat2.Birthdate=PIn.Date(textBirthdate2.Text);
         pat2.BillingType=PrefC.GetLong(PrefName.PracticeDefaultBillType);
         pat2.PatStatus=PatientStatus.Patient;
         pat2.PriProv=ProviderC.ListShort[comboPriProv2.SelectedIndex].ProvNum;
         if(comboSecProv2.SelectedIndex>0){
             pat2.SecProv=ProviderC.ListShort[comboSecProv2.SelectedIndex-1].ProvNum;
         }
         pat2.HmPhone=textHmPhone.Text;
         pat2.Address=textAddress.Text;
         pat2.Address2=textAddress2.Text;
         pat2.City=textCity.Text;
         pat2.State=textState.Text;
         pat2.Zip=textZip.Text;
         pat2.AddrNote=textAddrNotes.Text;
         pat2.ClinicNum=Security.CurUser.ClinicNum;
         pat2.Guarantor=guar.Guarantor;
         Patients.Insert(pat2,false);
         if(textReferral.Text!=""){
             //selectedReferral will already have been set in the guarantor loop
             refAttach=new RefAttach();
             refAttach.IsFrom=true;
             refAttach.RefDate=DateTime.Today;
             refAttach.ReferralNum=selectedReferral.ReferralNum;
             refAttach.PatNum=pat2.PatNum;
             RefAttaches.Insert(refAttach);
         }
     }
     //Patient #3-----------------------------------------------------------------------------------------------------
     Patient pat3=null;
     if(textFName3.Text!="" && textLName3.Text!=""){
         pat3=new Patient();
         pat3.LName=textLName3.Text;
         pat3.FName=textFName3.Text;
         if(listGender3.SelectedIndex==0){
             pat3.Gender=PatientGender.Male;
         }
         else{
             pat3.Gender=PatientGender.Female;
         }
         pat3.Position=PatientPosition.Child;
         pat3.Birthdate=PIn.Date(textBirthdate3.Text);
         pat3.BillingType=PrefC.GetLong(PrefName.PracticeDefaultBillType);
         pat3.PatStatus=PatientStatus.Patient;
         pat3.PriProv=ProviderC.ListShort[comboPriProv3.SelectedIndex].ProvNum;
         if(comboSecProv3.SelectedIndex>0){
             pat3.SecProv=ProviderC.ListShort[comboSecProv3.SelectedIndex-1].ProvNum;
         }
         pat3.HmPhone=textHmPhone.Text;
         pat3.Address=textAddress.Text;
         pat3.Address2=textAddress2.Text;
         pat3.City=textCity.Text;
         pat3.State=textState.Text;
         pat3.Zip=textZip.Text;
         pat3.AddrNote=textAddrNotes.Text;
         pat3.ClinicNum=Security.CurUser.ClinicNum;
         pat3.Guarantor=guar.Guarantor;
         Patients.Insert(pat3,false);
         if(textReferral.Text!=""){
             //selectedReferral will already have been set in the guarantor loop
             refAttach=new RefAttach();
             refAttach.IsFrom=true;
             refAttach.RefDate=DateTime.Today;
             refAttach.ReferralNum=selectedReferral.ReferralNum;
             refAttach.PatNum=pat3.PatNum;
             RefAttaches.Insert(refAttach);
         }
     }
     //Patient #4-----------------------------------------------------------------------------------------------------
     Patient pat4=null;
     if(textFName4.Text!="" && textLName4.Text!=""){
         pat4=new Patient();
         pat4.LName=textLName4.Text;
         pat4.FName=textFName4.Text;
         if(listGender4.SelectedIndex==0){
             pat4.Gender=PatientGender.Male;
         }
         else{
             pat4.Gender=PatientGender.Female;
         }
         pat4.Position=PatientPosition.Child;
         pat4.Birthdate=PIn.Date(textBirthdate4.Text);
         pat4.BillingType=PrefC.GetLong(PrefName.PracticeDefaultBillType);
         pat4.PatStatus=PatientStatus.Patient;
         pat4.PriProv=ProviderC.ListShort[comboPriProv4.SelectedIndex].ProvNum;
         if(comboSecProv4.SelectedIndex>0){
             pat4.SecProv=ProviderC.ListShort[comboSecProv4.SelectedIndex-1].ProvNum;
         }
         pat4.HmPhone=textHmPhone.Text;
         pat4.Address=textAddress.Text;
         pat4.Address2=textAddress2.Text;
         pat4.City=textCity.Text;
         pat4.State=textState.Text;
         pat4.Zip=textZip.Text;
         pat4.AddrNote=textAddrNotes.Text;
         pat4.ClinicNum=Security.CurUser.ClinicNum;
         pat4.Guarantor=guar.Guarantor;
         Patients.Insert(pat4,false);
         if(textReferral.Text!=""){
             //selectedReferral will already have been set in the guarantor loop
             refAttach=new RefAttach();
             refAttach.IsFrom=true;
             refAttach.RefDate=DateTime.Today;
             refAttach.ReferralNum=selectedReferral.ReferralNum;
             refAttach.PatNum=pat4.PatNum;
             RefAttaches.Insert(refAttach);
         }
     }
     //Patient #5-----------------------------------------------------------------------------------------------------
     Patient pat5=null;
     if(textFName5.Text!="" && textLName5.Text!=""){
         pat5=new Patient();
         pat5.LName=textLName5.Text;
         pat5.FName=textFName5.Text;
         if(listGender5.SelectedIndex==0){
             pat5.Gender=PatientGender.Male;
         }
         else{
             pat5.Gender=PatientGender.Female;
         }
         pat5.Position=PatientPosition.Child;
         pat5.Birthdate=PIn.Date(textBirthdate5.Text);
         pat5.BillingType=PrefC.GetLong(PrefName.PracticeDefaultBillType);
         pat5.PatStatus=PatientStatus.Patient;
         pat5.PriProv=ProviderC.ListShort[comboPriProv5.SelectedIndex].ProvNum;
         if(comboSecProv5.SelectedIndex>0){
             pat5.SecProv=ProviderC.ListShort[comboSecProv5.SelectedIndex-1].ProvNum;
         }
         pat5.HmPhone=textHmPhone.Text;
         pat5.Address=textAddress.Text;
         pat5.Address2=textAddress2.Text;
         pat5.City=textCity.Text;
         pat5.State=textState.Text;
         pat5.Zip=textZip.Text;
         pat5.AddrNote=textAddrNotes.Text;
         pat5.ClinicNum=Security.CurUser.ClinicNum;
         pat5.Guarantor=guar.Guarantor;
         Patients.Insert(pat5,false);
         if(textReferral.Text!=""){
             //selectedReferral will already have been set in the guarantor loop
             refAttach=new RefAttach();
             refAttach.IsFrom=true;
             refAttach.RefDate=DateTime.Today;
             refAttach.ReferralNum=selectedReferral.ReferralNum;
             refAttach.PatNum=pat5.PatNum;
             RefAttaches.Insert(refAttach);
         }
     }
     //Insurance------------------------------------------------------------------------------------------------------------
     InsSub sub1=null;
     InsSub sub2=null;
     if(selectedPlan1!=null){
         //validate the ins fields.  If they don't match perfectly, then set it to null
         if(Employers.GetName(selectedPlan1.EmployerNum)!=textEmployer1.Text
             || Carriers.GetName(selectedPlan1.CarrierNum)!=textCarrier1.Text
             || selectedPlan1.GroupName!=textGroupName1.Text
             || selectedPlan1.GroupNum!=textGroupNum1.Text)
         {
             selectedPlan1=null;
         }
     }
     if(selectedPlan2!=null){
         if(Employers.GetName(selectedPlan2.EmployerNum)!=textEmployer2.Text
             || Carriers.GetName(selectedPlan2.CarrierNum)!=textCarrier2.Text
             || selectedPlan2.GroupName!=textGroupName2.Text
             || selectedPlan2.GroupNum!=textGroupNum2.Text)
         {
             selectedPlan2=null;
         }
     }
     if(selectedCarrier1!=null){
         //validate the carrier fields.  If they don't match perfectly, then set it to null
         if(selectedCarrier1.CarrierName!=textCarrier1.Text
             || selectedCarrier1.Phone!=textPhone1.Text)
         {
             selectedCarrier1=null;
         }
     }
     if(selectedCarrier2!=null){
         if(selectedCarrier2.CarrierName!=textCarrier2.Text
             || selectedCarrier2.Phone!=textPhone2.Text)
         {
             selectedCarrier2=null;
         }
     }
     if(insComplete1){
         if(selectedCarrier1==null){
             //get a carrier, possibly creating a new one if needed.
             selectedCarrier1=Carriers.GetByNameAndPhone(textCarrier1.Text,textPhone1.Text);
         }
         long empNum1=Employers.GetEmployerNum(textEmployer1.Text);
         if(selectedPlan1==null){
             //don't try to get a copy of an existing plan. Instead, start from scratch.
             selectedPlan1=new InsPlan();
             selectedPlan1.EmployerNum=empNum1;
             selectedPlan1.CarrierNum=selectedCarrier1.CarrierNum;
             selectedPlan1.GroupName=textGroupName1.Text;
             selectedPlan1.GroupNum=textGroupNum1.Text;
             selectedPlan1.PlanType="";
             InsPlans.Insert(selectedPlan1);
             Benefit ben;
             for(int i=0;i<CovCatC.ListShort.Count;i++){
                 if(CovCatC.ListShort[i].DefaultPercent==-1){
                     continue;
                 }
                 ben=new Benefit();
                 ben.BenefitType=InsBenefitType.CoInsurance;
                 ben.CovCatNum=CovCatC.ListShort[i].CovCatNum;
                 ben.PlanNum=selectedPlan1.PlanNum;
                 ben.Percent=CovCatC.ListShort[i].DefaultPercent;
                 ben.TimePeriod=BenefitTimePeriod.CalendarYear;
                 ben.CodeNum=0;
                 Benefits.Insert(ben);
             }
         }
         sub1=new InsSub();
         sub1.PlanNum=selectedPlan1.PlanNum;
         sub1.AssignBen=true;
         sub1.ReleaseInfo=true;
         sub1.DateEffective=DateTime.MinValue;
         sub1.DateTerm=DateTime.MinValue;
         if(comboSubscriber1.SelectedIndex==1){
             sub1.Subscriber=guar.PatNum;
         }
         if(comboSubscriber1.SelectedIndex==2){
             sub1.Subscriber=pat2.PatNum;
         }
         if(comboSubscriber1.SelectedIndex==3){
             sub1.Subscriber=pat3.PatNum;
         }
         if(comboSubscriber1.SelectedIndex==4){
             sub1.Subscriber=pat4.PatNum;
         }
         if(comboSubscriber1.SelectedIndex==5){
             sub1.Subscriber=pat5.PatNum;
         }
         sub1.SubscriberID=textSubscriberID1.Text;
         InsSubs.Insert(sub1);
     }
     if(insComplete2){
         if(selectedCarrier2==null){
             selectedCarrier2=Carriers.GetByNameAndPhone(textCarrier2.Text,textPhone2.Text);
         }
         long empNum2=Employers.GetEmployerNum(textEmployer2.Text);
         if(selectedPlan2==null){
             //don't try to get a copy of an existing plan. Instead, start from scratch.
             selectedPlan2=new InsPlan();
             selectedPlan2.EmployerNum=empNum2;
             selectedPlan2.CarrierNum=selectedCarrier2.CarrierNum;
             selectedPlan2.GroupName=textGroupName2.Text;
             selectedPlan2.GroupNum=textGroupNum2.Text;
             selectedPlan2.PlanType="";
             InsPlans.Insert(selectedPlan2);
             Benefit ben;
             for(int i=0;i<CovCatC.ListShort.Count;i++){
                 if(CovCatC.ListShort[i].DefaultPercent==-1){
                     continue;
                 }
                 ben=new Benefit();
                 ben.BenefitType=InsBenefitType.CoInsurance;
                 ben.CovCatNum=CovCatC.ListShort[i].CovCatNum;
                 ben.PlanNum=selectedPlan2.PlanNum;
                 ben.Percent=CovCatC.ListShort[i].DefaultPercent;
                 ben.TimePeriod=BenefitTimePeriod.CalendarYear;
                 ben.CodeNum=0;
                 Benefits.Insert(ben);
             }
         }
         sub2=new InsSub();
         sub2.PlanNum=selectedPlan2.PlanNum;
         sub2.AssignBen=true;
         sub2.ReleaseInfo=true;
         sub2.DateEffective=DateTime.MinValue;
         sub2.DateTerm=DateTime.MinValue;
         if(comboSubscriber2.SelectedIndex==1){
             sub2.Subscriber=guar.PatNum;
         }
         if(comboSubscriber2.SelectedIndex==2){
             sub2.Subscriber=pat2.PatNum;
         }
         if(comboSubscriber2.SelectedIndex==3){
             sub2.Subscriber=pat3.PatNum;
         }
         if(comboSubscriber2.SelectedIndex==4){
             sub2.Subscriber=pat4.PatNum;
         }
         if(comboSubscriber2.SelectedIndex==5){
             sub2.Subscriber=pat5.PatNum;
         }
         sub2.SubscriberID=textSubscriberID2.Text;
         InsSubs.Insert(sub2);
     }
     PatPlan patplan;
     //attach insurance to subscriber--------------------------------------------------------------------------------
     if(checkInsOne1.Checked){
         patplan=new PatPlan();
         //the only situation where ordinal would be 2 is if ins2 has this patient as the subscriber.
         if(comboSubscriber2.SelectedIndex==1){
             patplan.Ordinal=2;
         }
         else{
             patplan.Ordinal=1;
         }
         patplan.PatNum=guar.PatNum;
         patplan.InsSubNum=sub1.InsSubNum;
         if(comboSubscriber1.SelectedIndex==1){
             patplan.Relationship=Relat.Self;
         }
         else if(comboSubscriber1.SelectedIndex==2){
             patplan.Relationship=Relat.Spouse;
         }
         else{
             //the subscriber would never be a child
         }
         PatPlans.Insert(patplan);
     }
     if(checkInsTwo1.Checked){
         patplan=new PatPlan();
         //the only situations where ordinal would be 1 is if ins1 is not checked or if ins2 has this patient as subscriber.
         if(comboSubscriber2.SelectedIndex==1){
             patplan.Ordinal=1;
         }
         else if(!checkInsOne1.Checked){
             patplan.Ordinal=1;
         }
         else{
             patplan.Ordinal=2;
         }
         patplan.PatNum=guar.PatNum;
         patplan.InsSubNum=sub2.InsSubNum;
         if(comboSubscriber2.SelectedIndex==1){
             patplan.Relationship=Relat.Self;
         }
         else if(comboSubscriber2.SelectedIndex==2){
             patplan.Relationship=Relat.Spouse;
         }
         else{
             //the subscriber would never be a child
         }
         PatPlans.Insert(patplan);
     }
     //attach insurance to patient 2, the other parent----------------------------------------------------------------------
     if(checkInsOne2.Checked){
         patplan=new PatPlan();
         //the only situation where ordinal would be 2 is if ins2 has this patient as the subscriber.
         if(comboSubscriber2.SelectedIndex==2){
             patplan.Ordinal=2;
         }
         else{
             patplan.Ordinal=1;
         }
         patplan.PatNum=pat2.PatNum;
         patplan.InsSubNum=sub1.InsSubNum;
         if(comboSubscriber1.SelectedIndex==2){
             patplan.Relationship=Relat.Self;
         }
         else if(comboSubscriber1.SelectedIndex==1){
             patplan.Relationship=Relat.Spouse;
         }
         else{
             //the subscriber would never be a child
         }
         PatPlans.Insert(patplan);
     }
     if(checkInsTwo2.Checked){
         patplan=new PatPlan();
         //the only situations where ordinal would be 1 is if ins1 is not checked or if ins2 has this patient as subscriber.
         if(comboSubscriber2.SelectedIndex==2){
             patplan.Ordinal=1;
         }
         else if(!checkInsOne2.Checked){
             patplan.Ordinal=1;
         }
         else{
             patplan.Ordinal=2;
         }
         patplan.PatNum=pat2.PatNum;
         patplan.InsSubNum=sub2.InsSubNum;
         if(comboSubscriber2.SelectedIndex==2){
             patplan.Relationship=Relat.Self;
         }
         else if(comboSubscriber2.SelectedIndex==1){
             patplan.Relationship=Relat.Spouse;
         }
         else{
             //the subscriber would never be a child
         }
         PatPlans.Insert(patplan);
     }
     //attach insurance to patient 3, a child----------------------------------------------------------------------
     if(checkInsOne3.Checked){
         patplan=new PatPlan();
         patplan.Ordinal=1;
         patplan.PatNum=pat3.PatNum;
         patplan.InsSubNum=sub1.InsSubNum;
         patplan.Relationship=Relat.Child;
         PatPlans.Insert(patplan);
     }
     if(checkInsTwo3.Checked){
         patplan=new PatPlan();
         //the only situation where ordinal would be 1 is if ins1 is not checked.
         if(!checkInsOne3.Checked){
             patplan.Ordinal=1;
         }
         else{
             patplan.Ordinal=2;
         }
         patplan.PatNum=pat3.PatNum;
         patplan.InsSubNum=sub2.InsSubNum;
         patplan.Relationship=Relat.Child;
         PatPlans.Insert(patplan);
     }
     //attach insurance to patient 4, a child----------------------------------------------------------------------
     if(checkInsOne4.Checked){
         patplan=new PatPlan();
         patplan.Ordinal=1;
         patplan.PatNum=pat4.PatNum;
         patplan.InsSubNum=sub1.InsSubNum;
         patplan.Relationship=Relat.Child;
         PatPlans.Insert(patplan);
     }
     if(checkInsTwo4.Checked){
         patplan=new PatPlan();
         //the only situation where ordinal would be 1 is if ins1 is not checked.
         if(!checkInsOne4.Checked){
             patplan.Ordinal=1;
         }
         else{
             patplan.Ordinal=2;
         }
         patplan.PatNum=pat4.PatNum;
         patplan.InsSubNum=sub2.InsSubNum;
         patplan.Relationship=Relat.Child;
         PatPlans.Insert(patplan);
     }
     //attach insurance to patient 5, a child----------------------------------------------------------------------
     if(checkInsOne5.Checked){
         patplan=new PatPlan();
         patplan.Ordinal=1;
         patplan.PatNum=pat5.PatNum;
         patplan.InsSubNum=sub1.InsSubNum;
         patplan.Relationship=Relat.Child;
         PatPlans.Insert(patplan);
     }
     if(checkInsTwo5.Checked){
         patplan=new PatPlan();
         //the only situation where ordinal would be 1 is if ins1 is not checked.
         if(!checkInsOne5.Checked){
             patplan.Ordinal=1;
         }
         else{
             patplan.Ordinal=2;
         }
         patplan.PatNum=pat5.PatNum;
         patplan.InsSubNum=sub2.InsSubNum;
         patplan.Relationship=Relat.Child;
         PatPlans.Insert(patplan);
     }
     SelectedPatNum=guar.PatNum;
     MessageBox.Show("Done");
     DialogResult=DialogResult.OK;
 }
Пример #10
0
 public static string Validate(Clearinghouse clearhouse,Carrier carrier,Provider billProv,Clinic clinic,InsPlan insPlan,Patient subscriber,InsSub insSub)
 {
     StringBuilder strb=new StringBuilder();
     X12Validate.ISA(clearhouse,strb);
     X12Validate.Carrier(carrier,strb);
     if(carrier.ElectID.Length<2) {
         if(strb.Length!=0) {
             strb.Append(",");
         }
         strb.Append("Electronic ID");
     }
     if(billProv.SSN.Length!=9) {
         if(strb.Length!=0) {
             strb.Append(",");
         }
         strb.Append("Prov TIN 9 digits");
     }
     X12Validate.BillProv(billProv,strb);
     if(clinic==null) {
         X12Validate.PracticeAddress(strb);
     }
     else {
         X12Validate.Clinic(clinic,strb);
     }
     if(insSub.SubscriberID.Length<2) {
         if(strb.Length!=0) {
             strb.Append(",");
         }
         strb.Append("SubscriberID");
     }
     if(subscriber.Birthdate.Year<1880) {
         if(strb.Length!=0) {
             strb.Append(",");
         }
         strb.Append("Subscriber Birthdate");
     }
     if(insPlan.GroupNum=="") {
         if(strb.Length!=0) {
             strb.Append(",");
         }
         strb.Append("Group Number");
     }
     return strb.ToString();
 }
Пример #11
0
		private void butOK_Click(object sender, System.EventArgs e) {
			//only visible if IsSelectMode
			if(gridMain.SelectedIndices.Length==0) {
				MessageBox.Show(Lan.g(this,"Please select an item first."));
				return;
			}
			if(gridMain.SelectedIndices.Length>1) {
				MessageBox.Show(Lan.g(this,"Please select only one item first."));
				return;
			}
			SelectedCarrier=Carriers.GetCarrier(PIn.Long(table.Rows[gridMain.SelectedIndices[0]]["CarrierNum"].ToString()));
			DialogResult=DialogResult.OK;
		}
Пример #12
0
		private void gridMain_CellDoubleClick(object sender,ODGridClickEventArgs e) {
			Carrier carrier=Carriers.GetCarrier(PIn.Long(table.Rows[e.Row]["CarrierNum"].ToString()));
			if(IsSelectMode) {
				SelectedCarrier=carrier;
				DialogResult=DialogResult.OK;
				return;
			}
			FormCarrierEdit FormCE=new FormCarrierEdit();
			FormCE.CarrierCur=carrier;
			FormCE.ShowDialog();
			if(FormCE.DialogResult!=DialogResult.OK){
				return;
			}
			changed=true;
			FillGrid();
		}
Пример #13
0
		///<summary>Only used for Canadian messages. If carrier is not null, then returns the first clearinghouse with a payorid matching the carrier if one exists. If no carrier specific clearinghouses are located, then returns the default clearinghouse if it is Canadian. Otherwise, in the worst case, will return the first Canadian clearinghouse that it can find. If for some reason no Canadian clearinghouses exist, then null is returned.</summary>
		public static Clearinghouse GetCanadianClearinghouse(Carrier carrier){
			string payerid="";
			if(carrier!=null) {
				payerid=carrier.ElectID;
			}
			//Returns the default dental clearinghouse if the payerid is not associated to any clearinghouses.
			long clearinghouseNum=Clearinghouses.AutomateClearinghouseSelection(payerid,EnumClaimMedType.Dental);
			if(clearinghouseNum!=0) {
				Clearinghouse clearhouse=Clearinghouses.GetClearinghouse(clearinghouseNum);
				if(clearhouse.Eformat==ElectronicClaimFormat.Canadian) {//Might not be Canadian, if for instance they accidentally set their default clearinghouse to an American clearinghouse.
					return clearhouse;
				}
			}
			//Return the default dental clearinghouse if it is a Canadian clearinghouse.
			for(int i=0;i<Clearinghouses.Listt.Length;i++) {
				if(PrefC.GetLong(PrefName.ClearinghouseDefaultDent)==Clearinghouses.Listt[i].ClearinghouseNum && Clearinghouses.Listt[i].Eformat==ElectronicClaimFormat.Canadian) {
					return Clearinghouses.Listt[i];
				}
			}
			//Return the first Canadian clearinghouse if one exists.
			for(int i=0;i<Clearinghouses.Listt.Length;i++) {
				if(Clearinghouses.Listt[i].Eformat==ElectronicClaimFormat.Canadian) {
					return Clearinghouses.Listt[i];
				}
			}
			//No Canadian clearinghouses exist. Should never happen, unless the user manually changes the ITRANS and ClaimStream clearinghouses to another electronic format.
			return null;
		}
		private static string Run(int scriptNum,Carrier carrier,Provider treatProv,Provider billingProv,DateTime reconciliationDate,out List<Etrans> etransAcks) { 
			string retVal="";
			etransAcks=CanadianOutput.GetPaymentReconciliations(carrier,treatProv,billingProv,reconciliationDate);
			retVal+="Payment Reconciliation#"+scriptNum.ToString()+" successful.\r\n";
			return retVal;
		}
Пример #15
0
		///<summary>Used from butGetElectronic_Click and from butOK_Click.  Returns false if unable to complete.  Also fills SubCur if not null.</summary>
		private bool FillPlanCurFromForm(){
			if(textDateEffect.errorProvider1.GetError(textDateEffect)!=""
				||textDateTerm.errorProvider1.GetError(textDateTerm)!=""
				||textDentaide.errorProvider1.GetError(textDentaide)!=""
				) {
				MsgBox.Show(this,"Please fix data entry errors first.");
				return false;
			}
			if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
				if(textPlanFlag.Text!="" && textPlanFlag.Text!="A" && textPlanFlag.Text!="V" && textPlanFlag.Text!="N") {
					MsgBox.Show(this,"Plan flag must be A, V, N, or blank.");
					return false;
				}
				if(textPlanFlag.Text=="") {
					if(checkIsPMP.Checked) {
						MsgBox.Show(this,"The provincial medical plan checkbox must be unchecked when the plan flag is blank.");
						return false;
					}
				}
				else {
					if(!checkIsPMP.Checked) {
						MsgBox.Show(this,"The provincial medical plan checkbox must be checked when the plan flag is not blank.");
						return false;
					}
					if(textPlanFlag.Text=="A") {
						if(textCanadianDiagCode.Text=="" || textCanadianDiagCode.Text!=Eclaims.Canadian.TidyAN(textCanadianDiagCode.Text,textCanadianDiagCode.Text.Length,true)) {
							MsgBox.Show(this,"When plan flag is set to A, diagnostic code must be set and must be 6 characters or less in length.");
							return false;
						}
						if(textCanadianInstCode.Text=="" || textCanadianInstCode.Text!=Eclaims.Canadian.TidyAN(textCanadianInstCode.Text,textCanadianInstCode.Text.Length,true)) {
							MsgBox.Show(this,"When plan flag is set to A, institution code must be set and must be 6 characters or less in length.");
							return false;
						}
					}
				}
			}
			if(textSubscriberID.Text=="" && SubCur!=null) {
				MsgBox.Show(this,"Subscriber ID not allowed to be blank.");
				return false;
			}
			if(textCarrier.Text=="") {
				MsgBox.Show(this,"Carrier not allowed to be blank.");
				return false;
			}
			if(PatPlanCur!=null && textOrdinal.errorProvider1.GetError(textOrdinal)!=""){
				MsgBox.Show(this,"Please fix data entry errors first.");
				return false;
			}
			if(SubCur!=null) {
				//Subscriber: Only changed when user clicks change button.
				SubCur.SubscriberID=textSubscriberID.Text;
				SubCur.DateEffective=PIn.Date(textDateEffect.Text);
				SubCur.DateTerm=PIn.Date(textDateTerm.Text);
				SubCur.ReleaseInfo=checkRelease.Checked;
				SubCur.AssignBen=checkAssign.Checked;
				SubCur.SubscNote=textSubscNote.Text;
				//MonthRenew already handled inside benefit window.
			}
			GetEmployerNum();
			PlanCur.GroupName=textGroupName.Text;
			PlanCur.GroupNum=textGroupNum.Text;
			PlanCur.RxBIN=textBIN.Text;
			PlanCur.DivisionNo=textDivisionNo.Text;//only visible in Canada
			//carrier-----------------------------------------------------------------------------------------------------
			CarrierCur=new Carrier();
			CarrierCur.CarrierName=textCarrier.Text;
			CarrierCur.Phone=textPhone.Text;
			CarrierCur.Address=textAddress.Text;
			CarrierCur.Address2=textAddress2.Text;
			CarrierCur.City=textCity.Text;
			CarrierCur.State=textState.Text;
			CarrierCur.Zip=textZip.Text;
			CarrierCur.ElectID=textElectID.Text;
			CarrierCur.NoSendElect=checkNoSendElect.Checked;
			if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
				bool carrierFound=true;
				try {
					CarrierCur=Carriers.GetIndentical(CarrierCur);
				}
				catch {//match not found
					carrierFound=false;
				}
				if(!carrierFound) {
					if(!MsgBox.Show(this,MsgBoxButtons.OKCancel,"Carrier not found.  Create new carrier?")) {
						return false;
					}
					FormCarrierEdit formCE=new FormCarrierEdit();
					formCE.IsNew=true;
					formCE.CarrierCur=CarrierCur;
					formCE.ShowDialog();
					if(formCE.DialogResult!=DialogResult.OK) {
						return false;
					}
				}
			}
			else {
				CarrierCur=Carriers.GetIndentical(CarrierCur);
			}
			PlanCur.CarrierNum=CarrierCur.CarrierNum;
			//plantype already handled.
			if(comboClaimForm.SelectedIndex!=-1){
				PlanCur.ClaimFormNum=ClaimForms.ListShort[comboClaimForm.SelectedIndex].ClaimFormNum;
			}
			PlanCur.UseAltCode=checkAlternateCode.Checked;
			PlanCur.CodeSubstNone=checkCodeSubst.Checked;
			PlanCur.IsMedical=checkIsMedical.Checked;
			PlanCur.ClaimsUseUCR=checkClaimsUseUCR.Checked;
			PlanCur.IsHidden=checkIsHidden.Checked;
			PlanCur.ShowBaseUnits=checkShowBaseUnits.Checked;
			if(comboFeeSched.SelectedIndex==0){
				PlanCur.FeeSched=0;
			}
			else{
				PlanCur.FeeSched=FeeSchedsStandard[comboFeeSched.SelectedIndex-1].FeeSchedNum;
			}
			if(comboCopay.SelectedIndex==0){
				PlanCur.CopayFeeSched=0;
			}
			else{
				PlanCur.CopayFeeSched=FeeSchedsCopay[comboCopay.SelectedIndex-1].FeeSchedNum;
			}
			if(comboAllowedFeeSched.SelectedIndex==0){
				if(IsNewPlan
					&& PlanCur.PlanType==""//percentage
					&& PrefC.GetBool(PrefName.AllowedFeeSchedsAutomate)){
					//add a fee schedule if needed
					FeeSched sched=FeeScheds.GetByExactName(CarrierCur.CarrierName,FeeScheduleType.Allowed);
					if(sched==null){
						sched=new FeeSched();
						sched.Description=CarrierCur.CarrierName;
						sched.FeeSchedType=FeeScheduleType.Allowed;
						//sched.IsNew=true;
						sched.ItemOrder=FeeSchedC.ListLong.Count;
						FeeScheds.Insert(sched);
						DataValid.SetInvalid(InvalidType.FeeScheds);
					}
					PlanCur.AllowedFeeSched=sched.FeeSchedNum;
				}
				else{
					PlanCur.AllowedFeeSched=0;
				}
			}
			else{
				PlanCur.AllowedFeeSched=FeeSchedsAllowed[comboAllowedFeeSched.SelectedIndex-1].FeeSchedNum;
			}
			PlanCur.CobRule=(EnumCobRule)comboCobRule.SelectedIndex;
			if(comboFilingCode.SelectedIndex==-1) {
				PlanCur.FilingCode=0;
			}
			else {
				PlanCur.FilingCode=InsFilingCodeC.Listt[comboFilingCode.SelectedIndex].InsFilingCodeNum;
			}
			PlanCur.FilingCodeSubtype=0;
			List<InsFilingCodeSubtype> subtypeList=InsFilingCodeSubtypes.GetForInsFilingCode(PlanCur.FilingCode);
			if(comboFilingCodeSubtype.SelectedIndex != -1 && comboFilingCodeSubtype.SelectedIndex < subtypeList.Count) {
				PlanCur.FilingCodeSubtype=subtypeList[comboFilingCodeSubtype.SelectedIndex].InsFilingCodeSubtypeNum;
			}
			//Canadian------------------------------------------------------------------------------------------
			PlanCur.DentaideCardSequence=PIn.Byte(textDentaide.Text);
			PlanCur.CanadianPlanFlag=textPlanFlag.Text;//validated
			PlanCur.CanadianDiagnosticCode=textCanadianDiagCode.Text;//validated
			PlanCur.CanadianInstitutionCode=textCanadianInstCode.Text;//validated
			//Canadian end---------------------------------------------------------------------------------------
			PlanCur.TrojanID=textTrojanID.Text;
			PlanCur.PlanNote=textPlanNote.Text;
			return true;
		}
Пример #16
0
		private void butLabel_Click(object sender,System.EventArgs e) {
			//LabelSingle label=new LabelSingle();
			PrintDocument pd=new PrintDocument();//only used to pass printerName
			if(!PrinterL.SetPrinter(pd,PrintSituation.LabelSingle,PatPlanCur.PatNum,textCarrier.Text+" insurance plan label printed")) {
				return;
			}
			Carrier carrier=new Carrier();
			carrier.CarrierName=textCarrier.Text;
			carrier.Phone=textPhone.Text;
			carrier.Address=textAddress.Text;
			carrier.Address2=textAddress2.Text;
			carrier.City=textCity.Text;
			carrier.State=textState.Text;
			carrier.Zip=textZip.Text;
			carrier.ElectID=textElectID.Text;
			carrier.NoSendElect=checkNoSendElect.Checked;
			try {
				carrier=Carriers.GetIndentical(carrier);
			}
			catch(ApplicationException ex) {
				//the catch is just to display a message to the user.  It doesn't affect the success of the function.
				MessageBox.Show(ex.Message);
			}	
			LabelSingle.PrintCarrier(carrier.CarrierNum);//,pd.PrinterSettings.PrinterName);
		}
Пример #17
0
 public static string InsPlanInvalidCarrier(bool verbose,bool isCheck)
 {
     if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
         return Meth.GetString(MethodBase.GetCurrentMethod(),verbose,isCheck);
     }
     string log="";
     //Gets a list of insurance plans that do not have a carrier attached. The list should be blank. If not, then you need to go to the plan listed and add a carrier. Missing carriers will cause the send claims function to give an error.
     command="SELECT PlanNum FROM insplan WHERE CarrierNum NOT IN (SELECT CarrierNum FROM carrier)";
     table=Db.GetTable(command);
     if(isCheck) {
         if(table.Rows.Count>0 || verbose) {
             log+=Lans.g("FormDatabaseMaintenance","Ins plans with carrier missing found: ")+table.Rows.Count+"\r\n";
         }
     }
     else {
         if(table.Rows.Count>0) {
             Carrier carrier=new Carrier();
             carrier.CarrierName="unknown";
             Carriers.Insert(carrier);
             command="UPDATE insplan SET CarrierNum="+POut.Long(carrier.CarrierNum)
             +" WHERE CarrierNum NOT IN (SELECT CarrierNum FROM carrier)";
             Db.NonQ(command);
         }
         int numberFixed=table.Rows.Count;
         if(numberFixed>0 || verbose) {
             log+=Lans.g("FormDatabaseMaintenance","Ins plans with carrier missing fixed: ")+numberFixed.ToString()+"\r\n";
         }
     }
     return log;
 }
Пример #18
0
		///<summary>Gets all necessary info from db based on ThisPatNum and ThisClaimNum.  Then fills displayStrings with the actual text that will display on claim.  The isRenaissance flag is very temporary.</summary>
		private void FillDisplayStrings(bool isRenaissance){
			if(PrintBlank){
				if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
					ClaimFormCur=ClaimForms.GetClaimFormByUniqueId("OD6");//CDA claim form
				}
				else { //Assume USA
					ClaimFormCur=ClaimForms.GetClaimFormByUniqueId("OD8");//ADA claim form
				}
				//ClaimFormItems.GetListForForm(ClaimFormCur.ClaimFormNum);
				displayStrings=new string[ClaimFormCur.Items.Length];
				ListClaimProcs=new List<ClaimProc>();
				return;
			}
			Family FamCur=Patients.GetFamily(PatNumCur);
			Patient PatCur=FamCur.GetPatient(PatNumCur);
			List<Claim> ClaimList=Claims.Refresh(PatCur.PatNum);
			ClaimCur=Claims.GetFromList(ClaimList,ClaimNumCur);
				//((Claim)Claims.HList[ThisClaimNum]).Clone();
			ListInsSub2=InsSubs.RefreshForFam(FamCur);
			ListInsPlan=InsPlans.RefreshForSubList(ListInsSub2);
			ListPatPlans=PatPlans.Refresh(ClaimCur.PatNum);
			InsPlan otherPlan=InsPlans.GetPlan(ClaimCur.PlanNum2,ListInsPlan);
			InsSub otherSub=InsSubs.GetSub(ClaimCur.InsSubNum2,ListInsSub2);
			if(otherPlan==null){
				otherPlan=new InsPlan();//easier than leaving it null
			}
			Carrier otherCarrier=new Carrier();
			if(otherPlan.PlanNum!=0){
				otherCarrier=Carriers.GetCarrier(otherPlan.CarrierNum);
			}
			//Employers.GetEmployer(otherPlan.EmployerNum);
			//Employer otherEmployer=Employers.Cur;//not actually used
			//then get the main plan
			subCur=InsSubs.GetSub(ClaimCur.InsSubNum,ListInsSub2);
			planCur=InsPlans.GetPlan(ClaimCur.PlanNum,ListInsPlan);
			Clinic clinic=Clinics.GetClinic(ClaimCur.ClinicNum);
			carrier=Carriers.GetCarrier(planCur.CarrierNum);
			//Employers.GetEmployer(InsPlans.Cur.EmployerNum);
			Patient subsc;
			if(FamCur.GetIndex(subCur.Subscriber)==-1) {//from another family
				subsc=Patients.GetPat(subCur.Subscriber);
				//Patients.Cur;
				//Patients.GetFamily(ThisPatNum);//return to current family
			}
			else{
				subsc=FamCur.ListPats[FamCur.GetIndex(subCur.Subscriber)];
			}
			Patient otherSubsc=new Patient();
			if(otherPlan.PlanNum!=0){//if secondary insurance exists
				if(FamCur.GetIndex(otherSub.Subscriber)==-1) {//from another family
					otherSubsc=Patients.GetPat(otherSub.Subscriber);
					//Patients.Cur;
					//Patients.GetFamily(ThisPatNum);//return to current family
				}
				else{
					otherSubsc=FamCur.ListPats[FamCur.GetIndex(otherSub.Subscriber)];
				}				
			}	
			if(ClaimCur.ReferringProv>0){
				ClaimReferral=Referrals.GetReferral(ClaimCur.ReferringProv);
			}
			ListProc=Procedures.Refresh(PatCur.PatNum);
			List<ToothInitial> initialList=ToothInitials.Refresh(PatCur.PatNum);
      //List<ClaimProc> ClaimProcList=ClaimProcs.Refresh(PatCur.PatNum);
			ClaimProcsForPat=ClaimProcs.Refresh(ClaimCur.PatNum);
      ClaimProcsForClaim=ClaimProcs.RefreshForClaim(ClaimCur.ClaimNum); 
			ListClaimProcs=new List<ClaimProc>();
			bool includeThis;
			Procedure proc;
			for(int i=0;i<ClaimProcsForClaim.Count;i++){//fill the arraylist
				if(ClaimProcsForClaim[i].ProcNum==0){
					continue;//skip payments
				}
				if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
					proc=Procedures.GetProcFromList(ListProc,ClaimProcsForClaim[i].ProcNum);
					if(proc.ProcNumLab!=0) { //This is a lab fee procedure.
						continue;//skip lab fee procedures in Canada, because they will show up on the same line as the procedure that they are attached to.
					}
				}
				includeThis=true;
				for(int j=0;j<ListClaimProcs.Count;j++){//loop through existing claimprocs
					if(ListClaimProcs[j].ProcNum==ClaimProcsForClaim[i].ProcNum){
						includeThis=false;//skip duplicate procedures
					}
				}
				if(includeThis){
					ListClaimProcs.Add(ClaimProcsForClaim[i]);	
				}
			}
			List<string> missingTeeth=ToothInitials.GetMissingOrHiddenTeeth(initialList);
			ProcedureCode procCode;
			for(int j=missingTeeth.Count-1;j>=0;j--) {//loop backwards to keep index accurate as items are removed
				//if the missing tooth is missing because of an extraction being billed here, then exclude it
				for(int p=0;p<ListClaimProcs.Count;p++) {
					proc=Procedures.GetProcFromList(ListProc,ListClaimProcs[p].ProcNum);
					procCode=ProcedureCodes.GetProcCode(proc.CodeNum);
					if(procCode.PaintType==ToothPaintingType.Extraction && proc.ToothNum==missingTeeth[j]) {
						missingTeeth.RemoveAt(j);
						break;
					}
				}
			}
			//diagnoses---------------------------------------------------------------------------------------
			diagnoses=new string[4];
			for(int i=0;i<4;i++){
				diagnoses[i]="";
			}
			for(int i=0;i<ListClaimProcs.Count;i++){
				proc=Procedures.GetProcFromList(ListProc,ListClaimProcs[i].ProcNum);
				if(proc.DiagnosticCode==""){
					continue;
				}
				for(int d=0;d<4;d++){
					if(diagnoses[d]==proc.DiagnosticCode){
						break;//if it's already been added
					}
					if(diagnoses[d]==""){//we're at the end of the list of existing diagnoses, and no match
						diagnoses[d]=proc.DiagnosticCode;//so add it.
						break;
					}
				}
				//There's still a chance that the diagnosis didn't get added, if there were more than 4.
			}
			Provider treatDent=ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvTreat)];
			if(ClaimFormCur==null){
				if(ClaimCur.ClaimForm>0){
					ClaimFormCur=ClaimForms.GetClaimForm(ClaimCur.ClaimForm);
				} 
				else {
					ClaimFormCur=ClaimForms.GetClaimForm(planCur.ClaimFormNum);
				}
			}
			List<PatPlan> patPlans=null;
			displayStrings=new string[ClaimFormCur.Items.Length];
			//a value is set for every item, but not every case will have a matching claimform item.
			for(int i=0;i<ClaimFormCur.Items.Length;i++){
				if(ClaimFormCur.Items[i]==null){//Renaissance does not use [0]
					displayStrings[i]="";
					continue;
				}
				switch(ClaimFormCur.Items[i].FieldName){
					default://image. or procedure which gets filled in FillProcStrings.
						displayStrings[i]="";
						break;
					case "FixedText":
						displayStrings[i]=ClaimFormCur.Items[i].FormatString;
						break;
					case "IsPreAuth":
						if(ClaimCur.ClaimType=="PreAuth") {
							displayStrings[i]="X";
						}
						break;
					case "IsStandardClaim":
						if(ClaimCur.ClaimType!="PreAuth") {
							displayStrings[i]="X";
						}
						break;
					case "ShowPreauthorizationIfPreauth":
						if(ClaimCur.ClaimType=="PreAuth") {
							displayStrings[i]="Preauthorization";
						}
						break;
					case "IsMedicaidClaim"://this should later be replaced with an insplan field.
						if(PatCur.MedicaidID!="") {
							displayStrings[i]="X";
						}
						break;
					case "IsGroupHealthPlan":
						string eclaimcode=InsFilingCodes.GetEclaimCode(planCur.FilingCode);
						if(PatCur.MedicaidID=="" 
							&& eclaimcode != "MC"//medicaid
							&& eclaimcode != "CH"//champus
							&& eclaimcode != "VA")//veterans
							//&& eclaimcode != ""//medicare?
						{
							displayStrings[i]="X";
						}
						break;
					case "PreAuthString":
						displayStrings[i]=ClaimCur.PreAuthString;
						break;
					case "PriorAuthString":
						displayStrings[i]=ClaimCur.PriorAuthorizationNumber;
						break;
					case "PriInsCarrierName":
						displayStrings[i]=carrier.CarrierName;
						break;
					case "PriInsAddress":
						displayStrings[i]=carrier.Address;
						break;
					case "PriInsAddress2":
						displayStrings[i]=carrier.Address2;
						break;
					case "PriInsAddressComplete":
						displayStrings[i]=carrier.Address+" "+carrier.Address2;
						break;
					case "PriInsCity":
						displayStrings[i]=carrier.City;
						break;
					case "PriInsST":
						displayStrings[i]=carrier.State;
						break;
					case "PriInsZip":
						displayStrings[i]=carrier.Zip;
						break;
					case "OtherInsExists":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]="X";
						}
						break;
					case "OtherInsNotExists":
						if(otherPlan.PlanNum==0) {
							displayStrings[i]="X";
						}
						break;
					case "OtherInsExistsDent":
						if(otherPlan.PlanNum!=0) {
							if(!otherPlan.IsMedical) {
								displayStrings[i]="X";
							}
						}
						break;
					case "OtherInsExistsMed":
						if(otherPlan.PlanNum!=0) {
							if(otherPlan.IsMedical) {
								displayStrings[i]="X";
							}
						}
						break;
					case "OtherInsSubscrLastFirst":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]=otherSubsc.LName+", "+otherSubsc.FName+" "+otherSubsc.MiddleI;
						}
						break;
					case "OtherInsSubscrDOB":
						if(otherPlan.PlanNum!=0) {
							if(ClaimFormCur.Items[i].FormatString=="") {
								displayStrings[i]=otherSubsc.Birthdate.ToShortDateString();
							}
							else {
								displayStrings[i]=otherSubsc.Birthdate.ToString(ClaimFormCur.Items[i].FormatString);
							}
						}
						break;
					case "OtherInsSubscrIsMale":
						if(otherPlan.PlanNum!=0 && otherSubsc.Gender==PatientGender.Male) {
							displayStrings[i]="X";
						}
						break;
					case "OtherInsSubscrIsFemale":
						if(otherPlan.PlanNum!=0 && otherSubsc.Gender==PatientGender.Female) {
							displayStrings[i]="X";
						}
						break;
					case "OtherInsSubscrID":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]=otherSub.SubscriberID;
						}
						break;
						//if(otherPlan.PlanNum!=0 && otherSubsc.SSN.Length==9){
						//	displayStrings[i]=otherSubsc.SSN.Substring(0,3)
						//		+"-"+otherSubsc.SSN.Substring(3,2)
						//		+"-"+otherSubsc.SSN.Substring(5);
						//}
						//break;
					case "OtherInsGroupNum":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]=otherPlan.GroupNum;
						}
						break;
					case "OtherInsRelatIsSelf":
						if(otherPlan.PlanNum!=0 && ClaimCur.PatRelat2==Relat.Self) {
							displayStrings[i]="X";
						}
						break;
					case "OtherInsRelatIsSpouse":
						if(otherPlan.PlanNum!=0 && ClaimCur.PatRelat2==Relat.Spouse) {
							displayStrings[i]="X";
						}
						break;
					case "OtherInsRelatIsChild":
						if(otherPlan.PlanNum!=0 && ClaimCur.PatRelat2==Relat.Child) {
							displayStrings[i]="X";
						}
						break;
					case "OtherInsRelatIsOther":
						if(otherPlan.PlanNum!=0 && (
							ClaimCur.PatRelat2==Relat.Dependent
							|| ClaimCur.PatRelat2==Relat.Employee
							|| ClaimCur.PatRelat2==Relat.HandicapDep
							|| ClaimCur.PatRelat2==Relat.InjuredPlaintiff
							|| ClaimCur.PatRelat2==Relat.LifePartner
							|| ClaimCur.PatRelat2==Relat.SignifOther
							))
							displayStrings[i]="X";
						break;
					case "OtherInsCarrierName":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]=otherCarrier.CarrierName;
						}
						break;
					case "OtherInsAddress":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]=otherCarrier.Address;
						}
						break;
					case "OtherInsCity":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]=otherCarrier.City;
						}
						break;
					case "OtherInsST":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]=otherCarrier.State;
						}
						break;
					case "OtherInsZip":
						if(otherPlan.PlanNum!=0) {
							displayStrings[i]=otherCarrier.Zip;
						}
						break;
					case "SubscrLastFirst":
						displayStrings[i]=subsc.LName+", "+subsc.FName+" "+subsc.MiddleI;
						break;
					case "SubscrAddress":
						displayStrings[i]=subsc.Address;
						break;
					case "SubscrAddress2":
						displayStrings[i]=subsc.Address2;
						break;
					case "SubscrAddressComplete":
						displayStrings[i]=subsc.Address+" "+subsc.Address2;
						break;
					case "SubscrCity":
						displayStrings[i]=subsc.City;
						break;
					case "SubscrST":
						displayStrings[i]=subsc.State;
						break;
					case "SubscrZip":
						displayStrings[i]=subsc.Zip;
						break;
					case "SubscrPhone"://needs work.  Only used for 1500
						if(isRenaissance) {
							//Expecting (XXX)XXX-XXXX
							displayStrings[i]=subsc.HmPhone;
							if(subsc.HmPhone.Length>14) {//Might have a note following the number.
								displayStrings[i]=subsc.HmPhone.Substring(0,14);
							}
						}
						else {
							string phone=subsc.HmPhone.Replace("(","");
							phone=phone.Replace(")","    ");
							phone=phone.Replace("-","  ");
							displayStrings[i]=phone;
						}
						break;
					case "SubscrDOB":
						if(ClaimFormCur.Items[i].FormatString=="") {
							displayStrings[i]=subsc.Birthdate.ToShortDateString();//MM/dd/yyyy
						}
						else {
							displayStrings[i]=subsc.Birthdate.ToString(ClaimFormCur.Items[i].FormatString);
						}
						break;
					case "SubscrIsMale":
						if(subsc.Gender==PatientGender.Male) {
							displayStrings[i]="X";
						}
						break;
					case "SubscrIsFemale":
						if(subsc.Gender==PatientGender.Female) {
							displayStrings[i]="X";
						}
						break;
					case "SubscrGender":
						if(subsc.Gender==PatientGender.Male) {
							displayStrings[i]="M";
						}
						else {
							displayStrings[i]="F";
						}
						break;
					case "SubscrIsMarried":
						if(subsc.Position==PatientPosition.Married) {
							displayStrings[i]="X";
						}
						break;
					case "SubscrIsSingle":
						if(subsc.Position==PatientPosition.Single
							|| subsc.Position==PatientPosition.Child
							|| subsc.Position==PatientPosition.Widowed) {
							displayStrings[i]="X";
						}
						break;
					case "SubscrID":
						patPlans=PatPlans.Refresh(PatNumCur);
						string patID=PatPlans.GetPatID(subCur.InsSubNum,patPlans);
						if(patID=="") {
							displayStrings[i]=subCur.SubscriberID;
						}
						else {
							displayStrings[i]=patID;
						}
						break;
					case "SubscrIDStrict":
						displayStrings[i]=subCur.SubscriberID;
						break;
					case "SubscrIsFTStudent":
						if(subsc.StudentStatus=="F") {
							displayStrings[i]="X";
						}
						break;
					case "SubscrIsPTStudent":
						if(subsc.StudentStatus=="P") {
							displayStrings[i]="X";
						}
						break;
					case "GroupName":
						displayStrings[i]=planCur.GroupName;
						break;
					case "GroupNum":
						displayStrings[i]=planCur.GroupNum;
						break;
					case "DivisionNo":
						displayStrings[i]=planCur.DivisionNo;
						break;
					case "EmployerName":
						displayStrings[i]=Employers.GetEmployer(planCur.EmployerNum).EmpName;;
						break;
					case "RelatIsSelf":
						if(ClaimCur.PatRelat==Relat.Self) {
							displayStrings[i]="X";
						}
						break;
					case "RelatIsSpouse":
						if(ClaimCur.PatRelat==Relat.Spouse) {
							displayStrings[i]="X";
						}
						break;
					case "RelatIsChild":
						if(ClaimCur.PatRelat==Relat.Child) {
							displayStrings[i]="X";
						}
						break;
					case "RelatIsOther":
						if(ClaimCur.PatRelat==Relat.Dependent
							|| ClaimCur.PatRelat==Relat.Employee
							|| ClaimCur.PatRelat==Relat.HandicapDep
							|| ClaimCur.PatRelat==Relat.InjuredPlaintiff
							|| ClaimCur.PatRelat==Relat.LifePartner
							|| ClaimCur.PatRelat==Relat.SignifOther) {
							displayStrings[i]="X";
						}
						break;
					case "Relationship":
						if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
							if(ClaimCur.PatRelat==Relat.Self) {
								displayStrings[i]="Self";
							}
							else if(ClaimCur.PatRelat==Relat.Spouse) {
								displayStrings[i]="Spouse";
							}
							else if(ClaimCur.PatRelat==Relat.Child) {
								displayStrings[i]="Child";
							}
							else if(ClaimCur.PatRelat==Relat.SignifOther || ClaimCur.PatRelat==Relat.LifePartner) {
								displayStrings[i]="Common Law Spouse";
							}
							else {
								displayStrings[i]="Other";
							}
						}
						else {
							displayStrings[i]=ClaimCur.PatRelat.ToString();
						}
						break;
					case "IsFTStudent":
						if(PatCur.StudentStatus=="F") {
							displayStrings[i]="X";
						}
						break;
					case "IsPTStudent":
						if(PatCur.StudentStatus=="P") {
							displayStrings[i]="X";
						}
						break;
					case "IsStudent":
						if(PatCur.StudentStatus=="P" || PatCur.StudentStatus=="F") {
							displayStrings[i]="X";
						}
						break;
					case "CollegeName":
						displayStrings[i]=PatCur.SchoolName;
						break;
					case "PatientLastFirst":
						displayStrings[i]=PatCur.LName+", "+PatCur.FName+" "+PatCur.MiddleI;
						break;
					case "PatientFirstMiddleLast":
						displayStrings[i]=PatCur.FName+" "+PatCur.MiddleI+" "+PatCur.LName;
						break;
					case "PatientFirstName":
						displayStrings[i] = PatCur.FName;
						break;
					case "PatientMiddleName":
						displayStrings[i] = PatCur.MiddleI;
						break;
					case "PatientLastName":
						displayStrings[i] = PatCur.LName;
						break;
					case "PatientAddress":
						displayStrings[i]=PatCur.Address;
						break;
					case "PatientAddress2":
						displayStrings[i]=PatCur.Address2;
						break;
					case "PatientAddressComplete":
						displayStrings[i]=PatCur.Address+" "+PatCur.Address2;
						break;
					case "PatientCity":
						displayStrings[i]=PatCur.City;
						break;
					case "PatientST":
						displayStrings[i]=PatCur.State;
						break;
					case "PatientZip":
						displayStrings[i]=PatCur.Zip;
						break;
					case "PatientPhone"://needs work.  Only used for 1500
						if(isRenaissance) {
							//Expecting (XXX)XXX-XXXX
							displayStrings[i]=PatCur.HmPhone;
							if(PatCur.HmPhone.Length>14) {//Might have a note following the number.
								displayStrings[i]=PatCur.HmPhone.Substring(0,14);
							}
						}
						else {
							string phonep=PatCur.HmPhone.Replace("(","");
							phonep=phonep.Replace(")","    ");
							phonep=phonep.Replace("-","  ");
							displayStrings[i]=phonep;
						}
						break;
					case "PatientDOB":
						if(ClaimFormCur.Items[i].FormatString=="") {
							displayStrings[i]=PatCur.Birthdate.ToShortDateString();//MM/dd/yyyy
						}
						else {
							displayStrings[i]=PatCur.Birthdate.ToString
								(ClaimFormCur.Items[i].FormatString);
						}
						break;
					case "PatientIsMale":
						if(PatCur.Gender==PatientGender.Male) {
							displayStrings[i]="X";
						}
						break;
					case "PatientIsFemale":
						if(PatCur.Gender==PatientGender.Female) {
							displayStrings[i]="X";
						}
						break;
					case "PatientGender":
						if(PatCur.Gender==PatientGender.Male) {
							displayStrings[i]="Male";
						}
						else if(PatCur.Gender==PatientGender.Female) {
							displayStrings[i]="Female";
						}
						break;
					case "PatientGenderLetter":
						if(subsc.Gender==PatientGender.Male) {
							displayStrings[i]="M";
						}
						else {
							displayStrings[i]="F";
						}
						break;
					case "PatientIsMarried":
						if(PatCur.Position==PatientPosition.Married) {
							displayStrings[i]="X";
						}
						break;
					case "PatientIsSingle":
						if(PatCur.Position==PatientPosition.Single
							|| PatCur.Position==PatientPosition.Child
							|| PatCur.Position==PatientPosition.Widowed) {
							displayStrings[i]="X";
						}
						break;
					case "PatIDFromPatPlan": //Dependant Code for Canada
						patPlans=PatPlans.Refresh(PatNumCur);
						if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
							if(carrier.ElectID=="000064") { //Pacific Blue Cross (PBC)
								displayStrings[i]=subCur.SubscriberID+"-"+PatPlans.GetPatID(subCur.InsSubNum,patPlans);
							}
						}
						else {
							displayStrings[i]=PatPlans.GetPatID(subCur.InsSubNum,patPlans);
						}
						break;
					case "PatientSSN":
						if(PatCur.SSN.Length==9) {
							displayStrings[i]=PatCur.SSN.Substring(0,3)
								+"-"+PatCur.SSN.Substring(3,2)
								+"-"+PatCur.SSN.Substring(5);
						}
						else {
							displayStrings[i]=PatCur.SSN;
						}
						break;
					case "PatientMedicaidID":
						displayStrings[i]=PatCur.MedicaidID;
						break;
					case "PatientID-MedicaidOrSSN":
						if(PatCur.MedicaidID!="") {
							displayStrings[i]=PatCur.MedicaidID;
						}
						else {
							displayStrings[i]=PatCur.SSN;
						}
						break;
					case "PatientChartNum":
						displayStrings[i]=PatCur.ChartNumber;
						break;
					case "PatientPatNum":
						displayStrings[i]=PatCur.PatNum.ToString();
						break;
					case "Diagnosis1":
						if(ClaimFormCur.Items[i].FormatString=="") {
							displayStrings[i]=diagnoses[0];
						}
						else if(ClaimFormCur.Items[i].FormatString=="NoDec") {
							displayStrings[i]=diagnoses[0].Replace(".","");
						}
						break;
					case "Diagnosis2":
						if(ClaimFormCur.Items[i].FormatString=="") {
							displayStrings[i]=diagnoses[1];
						}
						else if(ClaimFormCur.Items[i].FormatString=="NoDec") {
							displayStrings[i]=diagnoses[1].Replace(".","");
						}
						break;
					case "Diagnosis3":
						if(ClaimFormCur.Items[i].FormatString=="") {
							displayStrings[i]=diagnoses[2];
						}
						else if(ClaimFormCur.Items[i].FormatString=="NoDec") {
							displayStrings[i]=diagnoses[2].Replace(".","");
						}
						break;
					case "Diagnosis4":
						if(ClaimFormCur.Items[i].FormatString=="") {
							displayStrings[i]=diagnoses[3];
						}
						else if(ClaimFormCur.Items[i].FormatString=="NoDec") {
							displayStrings[i]=diagnoses[3].Replace(".","");
						}
						break;
			//this is where the procedures used to be
					case "Miss1":
						if(missingTeeth.Contains("1")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss2":
						if(missingTeeth.Contains("2")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss3":
						if(missingTeeth.Contains("3")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss4":
						if(missingTeeth.Contains("4")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss5":
						if(missingTeeth.Contains("5")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss6":
						if(missingTeeth.Contains("6")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss7":
						if(missingTeeth.Contains("7")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss8":
						if(missingTeeth.Contains("8")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss9":
						if(missingTeeth.Contains("9")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss10":
						if(missingTeeth.Contains("10")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss11":
						if(missingTeeth.Contains("11")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss12":
						if(missingTeeth.Contains("12")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss13":
						if(missingTeeth.Contains("13")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss14":
						if(missingTeeth.Contains("14")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss15":
						if(missingTeeth.Contains("15")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss16":
						if(missingTeeth.Contains("16")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss17":
						if(missingTeeth.Contains("17")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss18":
						if(missingTeeth.Contains("18")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss19":
						if(missingTeeth.Contains("19")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss20":
						if(missingTeeth.Contains("20")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss21":
						if(missingTeeth.Contains("21")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss22":
						if(missingTeeth.Contains("22")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss23":
						if(missingTeeth.Contains("23")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss24":
						if(missingTeeth.Contains("24")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss25":
						if(missingTeeth.Contains("25")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss26":
						if(missingTeeth.Contains("26")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss27":
						if(missingTeeth.Contains("27")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss28":
						if(missingTeeth.Contains("28")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss29":
						if(missingTeeth.Contains("29")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss30":
						if(missingTeeth.Contains("30")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss31":
						if(missingTeeth.Contains("31")) {
							displayStrings[i]="X";
						}
						break;
					case "Miss32":
						if(missingTeeth.Contains("32")) {
							displayStrings[i]="X";
						}
						break;
					case "Remarks":
						displayStrings[i]="";
						if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
							if(carrier.ElectID=="000064") { //Pacific Blue Cross (PBC)
								if(ClaimCur.ClaimType=="PreAuth") {
									displayStrings[i]+="Predetermination only."+Environment.NewLine;
								}
								else {
									if(subCur.AssignBen) {
										displayStrings[i]+="Please pay provider."+Environment.NewLine;
									}
									else {
										displayStrings[i]+="Please pay patient."+Environment.NewLine;
									}
								}
							}
						}
						if(ClaimCur.AttachmentID!="" && !ClaimCur.ClaimNote.StartsWith(ClaimCur.AttachmentID)){
							displayStrings[i]=ClaimCur.AttachmentID+" ";
						}
						displayStrings[i]+=ClaimCur.ClaimNote;
						break;
					case "PatientRelease":
						if(subCur.ReleaseInfo) {
							displayStrings[i]="Signature on File";
						}
						break;
					case "PatientReleaseDate":
						if(subCur.ReleaseInfo && ClaimCur.DateSent.Year > 1860) {
							if(ClaimFormCur.Items[i].FormatString=="") {
								displayStrings[i]=ClaimCur.DateSent.ToShortDateString();
							}
							else {
								displayStrings[i]=ClaimCur.DateSent.ToString(ClaimFormCur.Items[i].FormatString);
							}
						} 
						break;
					case "PatientAssignment":
						if(subCur.AssignBen) {
							displayStrings[i]="Signature on File";
						}
						break;
					case "PatientAssignmentDate":
						if(subCur.AssignBen && ClaimCur.DateSent.Year > 1860) {
							if(ClaimFormCur.Items[i].FormatString=="") {
								displayStrings[i]=ClaimCur.DateSent.ToShortDateString();
							}
							else {
								displayStrings[i]=ClaimCur.DateSent.ToString(ClaimFormCur.Items[i].FormatString);
							}
						}
						break;
					case "PlaceIsOffice":
						if(ClaimCur.PlaceService==PlaceOfService.Office) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsHospADA2002":
						if(ClaimCur.PlaceService==PlaceOfService.InpatHospital
							|| ClaimCur.PlaceService==PlaceOfService.OutpatHospital) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsExtCareFacilityADA2002":
						if(ClaimCur.PlaceService==PlaceOfService.CustodialCareFacility
							|| ClaimCur.PlaceService==PlaceOfService.SkilledNursFac) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsOtherADA2002":
						if(ClaimCur.PlaceService==PlaceOfService.PatientsHome
							|| ClaimCur.PlaceService==PlaceOfService.OtherLocation) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsInpatHosp":
						if(ClaimCur.PlaceService==PlaceOfService.InpatHospital) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsOutpatHosp":
						if(ClaimCur.PlaceService==PlaceOfService.OutpatHospital) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsAdultLivCareFac":
						if(ClaimCur.PlaceService==PlaceOfService.CustodialCareFacility) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsSkilledNursFac":
						if(ClaimCur.PlaceService==PlaceOfService.SkilledNursFac) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsPatientsHome":
						if(ClaimCur.PlaceService==PlaceOfService.PatientsHome) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceIsOtherLocation":
						if(ClaimCur.PlaceService==PlaceOfService.OtherLocation) {
							displayStrings[i]="X";
						}
						break;
					case "PlaceNumericCode":
						displayStrings[i]=GetPlaceOfServiceNum(ClaimCur.PlaceService);
						break;
					case "IsRadiographsAttached":
						if(ClaimCur.Radiographs>0) {
							displayStrings[i]="X";
						}
						break;
					case "RadiographsNumAttached":
						displayStrings[i]=ClaimCur.Radiographs.ToString();
						break;
					case "RadiographsNotAttached":
						if(ClaimCur.Radiographs==0) {
							displayStrings[i]="X";
						}
						break;
					case "IsEnclosuresAttached":
						if(ClaimCur.Radiographs>0 || ClaimCur.AttachedImages>0 || ClaimCur.AttachedModels>0) {
							displayStrings[i]="X";
						}
						break;
					case "AttachedImagesNum":
						displayStrings[i]=ClaimCur.AttachedImages.ToString();
						break;
					case "AttachedModelsNum":
						displayStrings[i]=ClaimCur.AttachedModels.ToString();
						break;
					case "IsNotOrtho":
						if(!ClaimCur.IsOrtho) {
							displayStrings[i]="X";
						}
						break;
					case "IsOrtho":
						if(ClaimCur.IsOrtho) {
							displayStrings[i]="X";
						}
						break;
					case "DateOrthoPlaced":
						if(ClaimCur.OrthoDate.Year > 1880){
							if(ClaimFormCur.Items[i].FormatString=="") {
								displayStrings[i]=ClaimCur.OrthoDate.ToShortDateString();
							}
							else {
								displayStrings[i]=ClaimCur.OrthoDate.ToString(ClaimFormCur.Items[i].FormatString);
							}
						}
						break;
					case "MonthsOrthoRemaining":
						if(ClaimCur.OrthoRemainM > 0) {
							displayStrings[i]=ClaimCur.OrthoRemainM.ToString();
						}
						break;
					case "IsNotProsth":
						if(ClaimCur.IsProsthesis=="N") {
							displayStrings[i]="X";
						}
						break;
					case "IsInitialProsth":
						if(ClaimCur.IsProsthesis=="I") {
							displayStrings[i]="X";
						}
						break;
					case "IsNotReplacementProsth":
						if(ClaimCur.IsProsthesis!="R") {//=='I'nitial or 'N'o
							displayStrings[i]="X";
						}
						break;
					case "IsReplacementProsth":
						if(ClaimCur.IsProsthesis=="R") {
							displayStrings[i]="X";
						}
						break;
					case "DatePriorProsthPlaced":
						if(ClaimCur.PriorDate.Year > 1860){
							if(ClaimFormCur.Items[i].FormatString=="") {
								displayStrings[i]=ClaimCur.PriorDate.ToShortDateString();
							}
							else {
								displayStrings[i]=ClaimCur.PriorDate.ToString(ClaimFormCur.Items[i].FormatString);
							}
						}
						break;
					case "IsOccupational":
						if(ClaimCur.AccidentRelated=="E") {
							displayStrings[i]="X";
						}
						break;
					case "IsNotOccupational":
						if(ClaimCur.AccidentRelated!="E") {
							displayStrings[i]="X";
						}
						break;
					case "IsAutoAccident":
						if(ClaimCur.AccidentRelated=="A") {
							displayStrings[i]="X";
						}
						break;
					case "IsNotAutoAccident":
						if(ClaimCur.AccidentRelated!="A") {
							displayStrings[i]="X";
						}
						break;
					case "IsOtherAccident":
						if(ClaimCur.AccidentRelated=="O") {
							displayStrings[i]="X";
						}
						break;
					case "IsNotOtherAccident":
						if(ClaimCur.AccidentRelated!="O") {
							displayStrings[i]="X";
						}
						break;
					case "IsNotAccident":
						if(ClaimCur.AccidentRelated!="O" && ClaimCur.AccidentRelated!="A") {
							displayStrings[i]="X";
						}
						break;
					case "IsAccident":
						if(ClaimCur.AccidentRelated!="") {
							displayStrings[i]="X";
						}
						break;
					case "AccidentDate":
						if(ClaimCur.AccidentDate.Year > 1860){
							if(ClaimFormCur.Items[i].FormatString=="") {
								displayStrings[i]=ClaimCur.AccidentDate.ToShortDateString();
							}
							else {
								displayStrings[i]=ClaimCur.AccidentDate.ToString(ClaimFormCur.Items[i].FormatString);
							}
						}
						break;
					case "AccidentST":
						displayStrings[i]=ClaimCur.AccidentST;
						break;
					case "BillingDentist":
						Provider P=ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvBill)];
						displayStrings[i]=P.FName+" "+P.MI+" "+P.LName+" "+P.Suffix;
						break;
					//case "BillingDentistAddress":
					//  if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)){
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingAddress);
					//  }
					//  else if(clinic==null) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeAddress);
					//  }
					//  else {
					//    displayStrings[i]=clinic.Address;
					//  }
					//  break;
					//case "BillingDentistAddress2":
					//  if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingAddress2);
					//  }
					//  else if(clinic==null) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeAddress2);
					//  }
					//  else {
					//    displayStrings[i]=clinic.Address2;
					//  }
					//  break;
					//case "BillingDentistCity":
					//  if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingCity);
					//  }
					//  else if(clinic==null) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeCity);
					//  }
					//  else {
					//    displayStrings[i]=clinic.City;
					//  }
					//  break;
					//case "BillingDentistST":
					//  if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingST);
					//  }
					//  else if(clinic==null) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeST);
					//  }
					//  else {
					//    displayStrings[i]=clinic.State;
					//  }
					//  break;
					//case "BillingDentistZip":
					//  if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingZip);
					//  }
					//  else if(clinic==null) {
					//    displayStrings[i]=PrefC.GetString(PrefName.PracticeZip);
					//  }
					//  else {
					//    displayStrings[i]=clinic.Zip;
					//  }
					//  break;
					case "BillingDentistMedicaidID":
						displayStrings[i]=ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvBill)].MedicaidID;
						break;
					case "BillingDentistProviderID":
						ProviderIdent[] provIdents=ProviderIdents.GetForPayor(ClaimCur.ProvBill,carrier.ElectID);
						if(provIdents.Length>0){
							displayStrings[i]=provIdents[0].IDNumber;//just use the first one we find
						}
						break;
					case "BillingDentistNPI":
						displayStrings[i]=ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvBill)].NationalProvID;
						if(CultureInfo.CurrentCulture.Name.EndsWith("CA") && //Canadian. en-CA or fr-CA
							carrier.ElectID=="000064" && //Pacific Blue Cross (PBC)
							ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvBill)].NationalProvID!= ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvTreat)].NationalProvID && //Billing and treating providers are different
							displayStrings[i].Length==9) { //Only for provider numbers which have been entered correctly (to prevent and indexing exception).
							displayStrings[i]="00"+displayStrings[i].Substring(2,5)+"00";
						}
						break;
					case "BillingDentistLicenseNum":
						displayStrings[i]=ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvBill)].StateLicense;
						break;
					case "BillingDentistSSNorTIN":
						displayStrings[i]=ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvBill)].SSN;
						break;
					case "BillingDentistNumIsSSN":
						if(!ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvBill)].UsingTIN) {
							displayStrings[i]="X";
						}
						break;
					case "BillingDentistNumIsTIN":
						if(ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvBill)].UsingTIN) {
							displayStrings[i]="X";
						}
						break;
					case "BillingDentistPh123":
						if(clinic==null){
							if(PrefC.GetString(PrefName.PracticePhone).Length==10){
								displayStrings[i]=PrefC.GetString(PrefName.PracticePhone).Substring(0,3);
							}
						}
						else{
							if(clinic.Phone.Length==10){
								displayStrings[i]=clinic.Phone.Substring(0,3);
							}
						}
						break;
					case "BillingDentistPh456":
						if(clinic==null){
							if(PrefC.GetString(PrefName.PracticePhone).Length==10){
								displayStrings[i]=PrefC.GetString(PrefName.PracticePhone).Substring(3,3);
							}
						}
						else{
							if(clinic.Phone.Length==10){
								displayStrings[i]=clinic.Phone.Substring(3,3);
							}
						}
						break;
					case "BillingDentistPh78910":
						if(clinic==null){
							if(PrefC.GetString(PrefName.PracticePhone).Length==10){
								displayStrings[i]=PrefC.GetString(PrefName.PracticePhone).Substring(6);
							}
						}
						else{
							if(clinic.Phone.Length==10){
								displayStrings[i]=clinic.Phone.Substring(6);
							}
						}
						break;
					case "BillingDentistPhoneFormatted":
						if(clinic==null){
							if(PrefC.GetString(PrefName.PracticePhone).Length==10){
								displayStrings[i]="("+PrefC.GetString(PrefName.PracticePhone).Substring(0,3)
									+")"+PrefC.GetString(PrefName.PracticePhone).Substring(3,3)
									+"-"+PrefC.GetString(PrefName.PracticePhone).Substring(6);
							}
						}
						else{
							if(clinic.Phone.Length==10){
								displayStrings[i]="("+clinic.Phone.Substring(0,3)
									+")"+clinic.Phone.Substring(3,3)
									+"-"+clinic.Phone.Substring(6);
							}
						}
						break;
					case "BillingDentistPhoneRaw":
						if(clinic==null) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticePhone);
						}
						else {
							displayStrings[i]=clinic.Phone;
						}
						break;
					case "PayToDentistAddress": //Behaves just like the old BillingDentistAddress field, but is overridden by the Pay-To address if the Pay-To address has been specified.
						if(PrefC.GetString(PrefName.PracticePayToAddress)!="") { //All Pay-To address fields are used in 5010 eclaims when Pay-To address line 1 is not blank.
						  displayStrings[i]=PrefC.GetString(PrefName.PracticePayToAddress);
						}
						else if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)){
						  displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingAddress);
						}
						else if(clinic==null) {
						  displayStrings[i]=PrefC.GetString(PrefName.PracticeAddress);
						}
						else {
						  displayStrings[i]=clinic.Address;
						}
						break;
					case "PayToDentistAddress2": //Behaves just like the old BillingDentistAddress2 field, but is overridden by the Pay-To address if the Pay-To address has been specified.
						if(PrefC.GetString(PrefName.PracticePayToAddress)!="") { //All Pay-To address fields are used in 5010 eclaims when Pay-To address line 1 is not blank.
						  displayStrings[i]=PrefC.GetString(PrefName.PracticePayToAddress2);
						}
						else if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)){
						  displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingAddress2);
						}
						else if(clinic==null) {
						  displayStrings[i]=PrefC.GetString(PrefName.PracticeAddress2);
						}
						else {
						  displayStrings[i]=clinic.Address2;
						}
						break;
					case "PayToDentistCity": //Behaves just like the old BillingDentistCity field, but is overridden by the Pay-To address if the Pay-To address has been specified.
						if(PrefC.GetString(PrefName.PracticePayToAddress)!="") { //All Pay-To address fields are used in 5010 eclaims when Pay-To address line 1 is not blank.
							displayStrings[i]=PrefC.GetString(PrefName.PracticePayToCity);
						}
						else if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingCity);
						}
						else if(clinic==null) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeCity);
						}
						else {
							displayStrings[i]=clinic.City;
						}
						break;
					case "PayToDentistST": //Behaves just like the old BillingDentistST field, but is overridden by the Pay-To address if the Pay-To address has been specified.
						if(PrefC.GetString(PrefName.PracticePayToAddress)!="") { //All Pay-To address fields are used in 5010 eclaims when Pay-To address line 1 is not blank.
							displayStrings[i]=PrefC.GetString(PrefName.PracticePayToST);
						}
						else if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingST);
						}
						else if(clinic==null) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeST);
						}
						else {
							displayStrings[i]=clinic.State;
						}
						break;
					case "PayToDentistZip": //Behaves just like the old BillingDentistZip field, but is overridden by the Pay-To address if the Pay-To address has been specified.
						if(PrefC.GetString(PrefName.PracticePayToAddress)!="") { //All Pay-To address fields are used in 5010 eclaims when Pay-To address line 1 is not blank.
							displayStrings[i]=PrefC.GetString(PrefName.PracticePayToZip);
						}
						else if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeBillingZip);
						}
						else if(clinic==null) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeZip);
						}
						else {
							displayStrings[i]=clinic.Zip;
						}
						break;
					case "TreatingDentistFName":
						displayStrings[i]=treatDent.FName;
						break;
					case "TreatingDentistLName":
						displayStrings[i]=treatDent.LName;
						break;
					case "TreatingDentistSignature":
						if(treatDent.SigOnFile){
							if(PrefC.GetBool(PrefName.ClaimFormTreatDentSaysSigOnFile)){
								displayStrings[i]="Signature on File";
							}
							else{
								displayStrings[i]=treatDent.FName+" "+treatDent.MI+" "+treatDent.LName+" "+treatDent.Suffix;
							}
						}
						break;
					case "TreatingDentistSigDate":
						if(treatDent.SigOnFile && ClaimCur.DateSent.Year > 1860){
							if(ClaimFormCur.Items[i].FormatString=="") {
								displayStrings[i]=ClaimCur.DateSent.ToShortDateString();
							}
							else {
								displayStrings[i]=ClaimCur.DateSent.ToString(ClaimFormCur.Items[i].FormatString);
							}
						}
						break;
					case "TreatingDentistMedicaidID":
						displayStrings[i]=treatDent.MedicaidID;
						break;
					case "TreatingDentistProviderID":
						provIdents=ProviderIdents.GetForPayor(ClaimCur.ProvTreat,carrier.ElectID);
						if(provIdents.Length>0) {
							displayStrings[i]=provIdents[0].IDNumber;//just use the first one we find
						}
						break;
					case "TreatingDentistNPI":
						displayStrings[i]=treatDent.NationalProvID;
						break;
					case "TreatingDentistLicense":
						displayStrings[i]=treatDent.StateLicense;
						break;
					case "TreatingDentistAddress":
						if(clinic==null) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeAddress);
						}
						else {
							displayStrings[i]=clinic.Address;
						}
						break;
					case "TreatingDentistCity":
						if(clinic==null) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeCity);
						}
						else {
							displayStrings[i]=clinic.City;
						}
						break;
					case "TreatingDentistST":
						if(clinic==null) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeST);
						}
						else {
							displayStrings[i]=clinic.State;
						}
						break;
					case "TreatingDentistZip":
						if(clinic==null) {
							displayStrings[i]=PrefC.GetString(PrefName.PracticeZip);
						}
						else {
							displayStrings[i]=clinic.Zip;
						}
						break;
					case "TreatingDentistPh123":
						if(clinic==null){
							if(PrefC.GetString(PrefName.PracticePhone).Length==10){
								displayStrings[i]=PrefC.GetString(PrefName.PracticePhone).Substring(0,3);
							}
						}
						else{
							if(clinic.Phone.Length==10){
								displayStrings[i]=clinic.Phone.Substring(0,3);
							}
						}
						break;
					case "TreatingDentistPh456":
						if(clinic==null){
							if(PrefC.GetString(PrefName.PracticePhone).Length==10){
								displayStrings[i]=PrefC.GetString(PrefName.PracticePhone).Substring(3,3);
							}
						}
						else{
							if(clinic.Phone.Length==10){
								displayStrings[i]=clinic.Phone.Substring(3,3);
							}
						}
						break;
					case "TreatingDentistPh78910":
						if(clinic==null){
							if(PrefC.GetString(PrefName.PracticePhone).Length==10){
								displayStrings[i]=PrefC.GetString(PrefName.PracticePhone).Substring(6);
							}
						}
						else{
							if(clinic.Phone.Length==10){
								displayStrings[i]=clinic.Phone.Substring(6);
							}
						}
						break;
					case "TreatingProviderSpecialty":
						displayStrings[i]=X12Generator.GetTaxonomy
							(ProviderC.ListLong[Providers.GetIndexLong(ClaimCur.ProvTreat)]);
						break;
					case "TotalPages":
						displayStrings[i]="";//totalPages.ToString();//bugs with this field that we can't fix since we didn't write that code.
						break;
					case "ReferringProvNPI":
						if(ClaimReferral==null){
							displayStrings[i]="";
						}
						else{
							displayStrings[i]=ClaimReferral.NationalProvID;
						}
						break;
					case "ReferringProvNameFL":
						if(ClaimReferral==null){
							displayStrings[i]="";
						}
						else{
							displayStrings[i]=ClaimReferral.GetNameFL();
						}
						break;
					case "MedUniformBillType":
						displayStrings[i]=ClaimCur.UniformBillType;
						break;
					case "MedAdmissionTypeCode":
						displayStrings[i]=ClaimCur.AdmissionTypeCode;
						break;
					case "MedAdmissionSourceCode":
						displayStrings[i]=ClaimCur.AdmissionSourceCode;
						break;
					case "MedPatientStatusCode":
						displayStrings[i]=ClaimCur.PatientStatusCode;
						break;
					case "MedAccidentCode": //For UB04.
						if(ClaimCur.AccidentRelated=="A") { //Auto accident
							displayStrings[i]="01";
						}
						else if(ClaimCur.AccidentRelated=="E") { //Employment related accident
							displayStrings[i]="04";
						}
						break;
				}//switch
				if(CultureInfo.CurrentCulture.Name=="nl-BE"	&& displayStrings[i]==""){//Dutch Belgium
					displayStrings[i]="*   *   *";
				}
				//Renaissance eclaims only: Remove newlines from display strings to prevent formatting issues, because the .rss file format requires each field on a single line.
				if(isRenaissance && displayStrings[i]!=null) {
					displayStrings[i]=displayStrings[i].Replace("\r","").Replace("\n","");
				}
			}//for
		}
Пример #19
0
		///<summary>The insplan that's passed in need not be properly updated to the database first.</summary>
		public static void RequestBenefits(Clearinghouse clearhouse,InsPlan plan,long patNum,Carrier carrier,List<Benefit> benList,long patPlanNum,InsSub insSub) {
			Patient pat=Patients.GetPat(patNum);
			Patient subsc=Patients.GetPat(insSub.Subscriber);
			Clinic clinic=Clinics.GetClinic(pat.ClinicNum);
			Provider billProv=Providers.GetProv(Providers.GetBillingProvNum(pat.PriProv,pat.ClinicNum));
			//validation.  Throw exception if missing info----------------------------------------
			string validationResult=X270.Validate(clearhouse,carrier,billProv,clinic,plan,subsc,insSub);
			if(validationResult != "") {
				throw new Exception(Lan.g("FormInsPlan","Please fix the following errors first:")+"\r\n"+validationResult);
			}
			//create a 270 message---------------------------------------------------------------
			string x12message=X270.GenerateMessageText(clearhouse,carrier,billProv,clinic,plan,subsc,insSub);
			EtransMessageText etransMessageText=new EtransMessageText();
			etransMessageText.MessageText=x12message;
			EtransMessageTexts.Insert(etransMessageText);
			//attach it to an etrans-------------------------------------------------------------
			Etrans etrans=new Etrans();
			etrans.DateTimeTrans=DateTime.Now;
			etrans.ClearingHouseNum=clearhouse.ClearinghouseNum;
			etrans.Etype=EtransType.BenefitInquiry270;
			etrans.PlanNum=plan.PlanNum;
			etrans.InsSubNum=insSub.InsSubNum;
			etrans.EtransMessageTextNum=etransMessageText.EtransMessageTextNum;
			Etranss.Insert(etrans);
			//send the 270----------------------------------------------------------------------
			string x12response="";
			//a connection error here needs to bubble up
			try {
				if(clearhouse.CommBridge==EclaimsCommBridge.ClaimConnect) {
					x12response=ClaimConnect.Benefits270(clearhouse,x12message);
				}
				if(clearhouse.CommBridge==EclaimsCommBridge.EDS) {
					x12response=EDS.Benefits270(clearhouse,x12message);
				}
			}
			catch(Exception ex) {
				EtransMessageTexts.Delete(etrans.EtransMessageTextNum);
				Etranss.Delete(etrans.EtransNum);
				throw new ApplicationException(Lan.g("FormInsPlan","Connection Error:")+"\r\n"+ex.GetType().Name+"\r\n"+ex.Message);
			}
			//start to process the 271----------------------------------------------------------
			X271 x271=null;
			if(X12object.IsX12(x12response)) {
				X12object x12obj=new X12object(x12response);
				if(x12obj.Is271()) {
					x271=new X271(x12response);
				}
			}
			else {//not a 997, 999, 277 or 271
				EtransMessageTexts.Delete(etrans.EtransMessageTextNum);
				Etranss.Delete(etrans.EtransNum);
				throw new ApplicationException(Lan.g("FormInsPlan","Error:")+"\r\n"+x12response);
			}
			/*
			//In realtime mode, X12 limits the request to one patient.
			//We will always use the subscriber.
			//So all EB segments are for the subscriber.
			List<EB271> listEB=new List<EB271>();
			EB271 eb;
			if(x271 != null) {
				for(int i=0;i<x271.Segments.Count;i++) {
					if(x271.Segments[i].SegmentID != "EB") {
						continue;
					}
					eb=new EB271(x271.Segments[i]);
					listEB.Add(eb);
				}
			}*/
			//create an etrans for the 271------------------------------------------------------
			etransMessageText=new EtransMessageText();
			etransMessageText.MessageText=x12response;
			EtransMessageTexts.Insert(etransMessageText);
			Etrans etrans271=new Etrans();
			etrans271.DateTimeTrans=DateTime.Now;
			etrans271.ClearingHouseNum=clearhouse.ClearinghouseNum;
			etrans271.Etype=EtransType.TextReport;
			if(X12object.IsX12(x12response)) {//this shouldn't need to be tested because it was tested above.
				if(x271==null){
					X12object Xobj=new X12object(x12response);
					if(Xobj.Is997()) {
						etrans271.Etype=EtransType.Acknowledge_997;
					}
					else if(Xobj.Is999()) {
						etrans271.Etype=EtransType.Acknowledge_999;
					}
					else if(X277.Is277(Xobj)) {
						etrans271.Etype=EtransType.StatusNotify_277;
					}
					else if(X835.Is835(Xobj)) {
						etrans271.Etype=EtransType.ERA_835;
					}
				}
				else{
					etrans271.Etype=EtransType.BenefitResponse271;
				}
			}
			etrans271.PlanNum=plan.PlanNum;
			etrans271.InsSubNum=insSub.InsSubNum;
			etrans271.EtransMessageTextNum=etransMessageText.EtransMessageTextNum;
			Etranss.Insert(etrans271);
			etrans.AckEtransNum=etrans271.EtransNum;
			if(etrans271.Etype==EtransType.Acknowledge_997) {
				X997 x997=new X997(x12response);
				string error997=x997.GetHumanReadable();
				etrans.Note="Error: "+error997;//"Malformed document sent.  997 error returned.";
				Etranss.Update(etrans);
				MessageBox.Show(etrans.Note);
				//CodeBase.MsgBoxCopyPaste msgbox=new CodeBase.MsgBoxCopyPaste(etrans.Note);
				//msgbox.ShowDialog();
				//don't show the 270 interface.
				return;
			}
			else if(etrans271.Etype==EtransType.Acknowledge_999) {
				X999 x999=new X999(x12response);
				string error999=x999.GetHumanReadable();
				etrans.Note="Error: "+error999;//"Malformed document sent.  999 error returned.";
				Etranss.Update(etrans);
				MessageBox.Show(etrans.Note);
				//CodeBase.MsgBoxCopyPaste msgbox=new CodeBase.MsgBoxCopyPaste(etrans.Note);
				//msgbox.ShowDialog();
				//don't show the 270 interface.
				return;
			}
			else if(etrans271.Etype==EtransType.StatusNotify_277) { 
				X277 x277=new X277(x12response);
				string error277=x277.GetHumanReadable();
				etrans.Note="Error: "+error277;//"Malformed document sent.  277 error returned.";
				Etranss.Update(etrans);
				MessageBox.Show(etrans.Note);
				//CodeBase.MsgBoxCopyPaste msgbox=new CodeBase.MsgBoxCopyPaste(etrans.Note);
				//msgbox.ShowDialog();
				//don't show the 277 interface.
				return;
			}
			else if(etrans271.Etype==EtransType.ERA_835) {
				X835 x835=new X835(x12response,"");
				string error835=x835.GetHumanReadable();
				etrans.Note="Error: "+error835;//"Malformed document sent.  835 error returned.";
				Etranss.Update(etrans);
				MessageBox.Show(etrans.Note);
				//CodeBase.MsgBoxCopyPaste msgbox=new CodeBase.MsgBoxCopyPaste(etrans.Note);
				//msgbox.ShowDialog();
				//don't show the 835 interface.
				return;
			}
			else { //271
				string processingerror=x271.GetProcessingError();
				if(processingerror != "") {
					etrans.Note=processingerror;
					Etranss.Update(etrans);
					MessageBox.Show(etrans.Note);
					//CodeBase.MsgBoxCopyPaste msgbox=new CodeBase.MsgBoxCopyPaste(etrans.Note);
					//msgbox.ShowDialog();
					//don't show the 270 interface.
					return;
				}
				else {
					etrans.Note="Normal 271 response.";//change this later to be explanatory of content.
				}
			}
			Etranss.Update(etrans);
			//show the user a list of benefits to pick from for import--------------------------
			FormEtrans270Edit formE=new FormEtrans270Edit(patPlanNum,plan.PlanNum,insSub.InsSubNum);
			formE.EtransCur=etrans;
			formE.IsInitialResponse=true;
			formE.benList=benList;
			formE.ShowDialog();
		}
Пример #20
0
 ///<summary>Returns the list of etrans requests. The etrans.AckEtransNum can be used to get the etrans ack. The following are the only possible formats that can be returned in the acks: 21 EOB Response, 11 Claim Ack, 14 Outstanding Transactions Response, 23 Predetermination EOB, 13 Predetermination Ack, 24 E-Mail Response. Set version2 to true if version 02 request and false for version 04 request. Set sendToItrans to true only when sending to carrier 999999 representing the entire ITRANS network. When version2 is false and sendToItrans is false then carrier must be set to a valid Canadian carrier, otherwise it can be set to null. Prov must be validated as a CDANet provider before calling this function.</summary>
 public static List<Etrans> GetOutstandingTransactions(bool version2,bool sendToItrans,Carrier carrier,Provider prov)
 {
     List<Etrans> etransAcks=new List<Etrans>();
     Clearinghouse clearhouse=Canadian.GetClearinghouse();
     if(clearhouse==null) {
         throw new ApplicationException("Canadian clearinghouse not found.");
     }
     string saveFolder=clearhouse.ExportPath;
     if(!Directory.Exists(saveFolder)) {
         throw new ApplicationException(saveFolder+" not found.");
     }
     //We are required to send the request for outstanding transactions over and over until we get back an outstanding transactions ack format (Transaction type 14), because
     //there may be more than one item in the mailbox and we can only get one item at time.
     bool exit=false;
     do {
         StringBuilder strb=new StringBuilder();
         Etrans etrans=null;
         if(version2 || sendToItrans) {
             etrans=Etranss.CreateCanadianOutput(0,0,0,clearhouse.ClearinghouseNum,EtransType.RequestOutstand_CA,0,0);
         }
         else {
             if((carrier.CanadianSupportedTypes&CanSupTransTypes.RequestForOutstandingTrans_04)!=CanSupTransTypes.RequestForOutstandingTrans_04) {
                 throw new ApplicationException("The carrier does not support request for outstanding transactions.");
             }
             etrans=Etranss.CreateCanadianOutput(0,carrier.CarrierNum,carrier.CanadianNetworkNum,
                 clearhouse.ClearinghouseNum,EtransType.RequestOutstand_CA,0,0);
         }
         //A01 transaction prefix 12 AN
         if(version2 || sendToItrans) {
             strb.Append("            ");
         }
         else {
             if(carrier.CanadianNetworkNum==0) {
                 throw new ApplicationException("Carrier network not set.");
             }
             CanadianNetwork network=CanadianNetworks.GetNetwork(carrier.CanadianNetworkNum);
             strb.Append(Canadian.TidyAN(network.CanadianTransactionPrefix,12));
         }
         //A02 office sequence number 6 N
         strb.Append(Canadian.TidyN(etrans.OfficeSequenceNumber,6));
         //A03 format version number 2 N
         if(version2) {
             strb.Append("02");
         }
         else {
             strb.Append("04");
         }
         //A04 transaction code 2 N
         strb.Append("04");//outstanding transactions request
         if(!version2) {//version 04
             //A05 carrier id number 6 N
             if(sendToItrans) {
                 strb.Append("999999");
             }
             else {
                 strb.Append(carrier.ElectID);//already validated as 6 digit number.
             }
         }
         //A06 software system id 3 AN
         strb.Append(Canadian.SoftwareSystemId());
         if(!version2) { //version 04
             //A10 encryption method 1 N
             if(sendToItrans) {
                 strb.Append("1");
             }
             else {
                 strb.Append(carrier.CanadianEncryptionMethod);//validated in UI
             }
         }
         //A07 message length N4
         if(!version2) { //version 04
             strb.Append(Canadian.TidyN("64",5));
         }
         else {
             strb.Append(Canadian.TidyN("42",4));
         }
         if(!version2) { //version 04
             //A09 carrier transaction counter 5 N
             strb.Append(Canadian.TidyN(etrans.CarrierTransCounter,5));
         }
         //According to the documentation for the outstanding transactions ack format, B01 only has to be a valid provider for the practice,
         //and that will trigger acknowledgements for all providers of the practice. I am assuming here that the same is true for the
         //billing provider in field B03, because there is no real reason to limit the request to any particular provider.
         //B01 CDA provider number 9 AN
         strb.Append(Canadian.TidyAN(prov.NationalProvID,9));//already validated
         //B02 (treating) provider office number 4 AN
         strb.Append(Canadian.TidyAN(prov.CanadianOfficeNum,4));//already validated
         if(!version2) { //version 04
             //B03 billing provider number 9 AN
             //might need to account for possible 5 digit prov id assigned by carrier
             strb.Append(Canadian.TidyAN(prov.NationalProvID,9));//already validated
         }
         string result="";
         bool resultIsError=false;
         try {
             result=Canadian.PassToIca(strb.ToString(),clearhouse);
         }
         catch(ApplicationException ex) {
             result=ex.Message;
             resultIsError=true;
             //Etranss.Delete(etrans.EtransNum);//we don't want to do this, because we want the incremented etrans.OfficeSequenceNumber to be saved
             //Attach an ack indicating failure.
         }
         //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.DateTimeTrans=DateTime.Now;
         CCDFieldInputter fieldInputter=null;
         if(resultIsError) {
             etransAck.Etype=EtransType.AckError;
             etrans.Note="failed";
         }
         else {
             if(result.Substring(12).StartsWith("NO MORE ITEMS")) {
                 etransAck.Etype=EtransType.OutstandingAck_CA;
                 exit=true;
             }
             else {
                 fieldInputter=new CCDFieldInputter(result);
                 CCDField fieldG05=fieldInputter.GetFieldById("G05");
                 if(fieldG05!=null) {
                     etransAck.AckCode=fieldG05.valuestr;
                 }
                 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());
         etransAcks.Add(etransAck);
         if(resultIsError) {
             throw new ApplicationException(result);
         }
         if(fieldInputter==null) { //happens in version 02 when a terminating message containing the text "NO MORE ITEMS" is received.
             break;
         }
         CCDField fieldA04=fieldInputter.GetFieldById("A04");//message format
         if(version2) {
             //In this case, there are only 4 possible responses: EOB, Claim Ack, Claim Ack with an error code, or Claim Ack with literal "NO MORE ITEMS" starting at character 13.
             if(fieldA04.valuestr=="11") {
                 CCDField fieldG08=fieldInputter.GetFieldById("G08");
                 if(fieldG08!=null && (fieldG08.valuestr=="004" || fieldG08.valuestr=="049")) { //Exit conditions specified in the documentation.
                     etransAck.Etype=EtransType.OutstandingAck_CA;
                     exit=true;
                 }
             }
         }
         else { //version 04
             //Remember, the only allowed response transaction types are: 21 EOB Response, 11 Claim Ack, 14 Outstanding Transactions Response, 23 Predetermination EOB, 13 Predetermination Ack, 24 E-Mail Response
             if(fieldA04.valuestr=="14") {//Outstanding Transaction Ack Format
                 CCDField fieldG05=fieldInputter.GetFieldById("G05");//response status
                 if(fieldG05.valuestr=="R") { //We only expect the result to be 'R' or 'X' as specified in the documentation.
                     CCDField fieldG07=fieldInputter.GetFieldById("G07");//disposition message
                     CCDField fieldG08=fieldInputter.GetFieldById("G08");//error code
                     MessageBox.Show(Lan.g("","Failed to receive outstanding transactions. Messages from CDANet")+": "+Environment.NewLine+
                         fieldG07.valuestr.Trim()+Environment.NewLine+((fieldG08!=null)?CCDerror.message(Convert.ToInt32(fieldG08.valuestr),false):""));
                 }
                 etransAck.Etype=EtransType.OutstandingAck_CA;
                 exit=true;
             }
         }
         //Field A02 exists in all of the possible formats (21,11,14,23,13,24).
         CCDField fieldA02=fieldInputter.GetFieldById("A02");//office sequence number
         //We use the Office Sequence Number to find the original etrans entry so that we can discover which patient the response is referring to.
         Etrans etranOriginal=Etranss.GetForSequenceNumberCanada(fieldA02.valuestr);
         if(etranOriginal!=null) { //Null will happen when testing, but should not happen in production.
             etrans.PatNum=etranOriginal.PatNum;
             etrans.PlanNum=etranOriginal.PlanNum;
             etrans.InsSubNum=etranOriginal.InsSubNum;
             etrans.ClaimNum=etranOriginal.ClaimNum;
             Etranss.Update(etrans);
             etransAck.PatNum=etranOriginal.PatNum;
             etransAck.PlanNum=etranOriginal.PlanNum;
             etransAck.InsSubNum=etranOriginal.InsSubNum;
             etransAck.ClaimNum=etranOriginal.ClaimNum;
             Etranss.Update(etransAck);
             if(!exit) {
                 if(etransAck.ClaimNum!=0) {
                     Claim claim=Claims.GetClaim(etransAck.ClaimNum);
                     if(etransAck.AckCode=="A") {
                         claim.ClaimStatus="R";
                         claim.DateReceived=MiscData.GetNowDateTime();
                     }
                     else if(etransAck.AckCode=="H" || etransAck.AckCode=="B" || etransAck.AckCode=="C" || etransAck.AckCode=="N") {
                         claim.ClaimStatus="S";
                     }
                     else if(etransAck.AckCode=="M") {
                         Canadian.PrintManualClaimForm(claim);
                     }
                     Claims.Update(claim);
                 }
             }
         }
         if(!exit) {
             try {
                 new FormCCDPrint(etrans,result,true);
             }
             catch(Exception ex) {
                 MessageBox.Show(Lan.g("CanadianOutput","Failed to display one of the ROT responses")+": "+Environment.NewLine+ex.ToString());
             }
         }
     } while(!exit);
     return etransAcks;
 }
Пример #21
0
		private void butAdd_Click(object sender, System.EventArgs e) {
			FormCarrierEdit FormCE=new FormCarrierEdit();
			FormCE.IsNew=true;
			Carrier carrier=new Carrier();
			if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA
				carrier.IsCDA=true;
			}
			carrier.CarrierName=textCarrier.Text;
			//The phone number will get formated while the user types inside the carrier edit window.
			//However, the user could have typed in a poorly formatted number so we will reformat the number once before load.
			string phoneFormatted=TelephoneNumbers.ReFormat(textPhone.Text);
			carrier.Phone=phoneFormatted;
			FormCE.CarrierCur=carrier;
			FormCE.ShowDialog();
			if(FormCE.DialogResult!=DialogResult.OK){
				return;
			}
			changed=true;
			//Load the name and phone number of the newly added carrier to the search fields so that the new carrier shows up in the grid.
			textCarrier.Text=FormCE.CarrierCur.CarrierName;
			textPhone.Text=FormCE.CarrierCur.Phone;
			FillGrid();
			for(int i=0;i<table.Rows.Count;i++){
				if(FormCE.CarrierCur.CarrierNum.ToString()==table.Rows[i]["CarrierNum"].ToString()){
					gridMain.SetSelected(i,true);
				}
			}
		}
Пример #22
0
 ///<summary>Each payment reconciliation request can return up to 9 pages. This function will return one etrans ack for each page in the result, since each page must be requested individually. Only for version 04, no such transaction exists for version 02. The provTreat and provBilling must be validated as CDANet providers before calling this function.</summary>
 public static List<Etrans> GetPaymentReconciliations(Carrier carrier,Provider provTreat,Provider provBilling,DateTime reconciliationDate)
 {
     Clearinghouse clearhouse=Canadian.GetClearinghouse();
     if(clearhouse==null) {
         throw new ApplicationException("Canadian clearinghouse not found.");
     }
     string saveFolder=clearhouse.ExportPath;
     if(!Directory.Exists(saveFolder)) {
         throw new ApplicationException(saveFolder+" not found.");
     }
     List<Etrans> etransAcks=new List<Etrans>();
     int pageNumber=1;
     int totalPages=1;
     do{
         StringBuilder strb=new StringBuilder();
         if((carrier.CanadianSupportedTypes&CanSupTransTypes.RequestForPaymentReconciliation_06)!=CanSupTransTypes.RequestForPaymentReconciliation_06) {
             throw new ApplicationException("The carrier does not support payment reconciliation transactions.");
         }
         if(carrier.CanadianNetworkNum==0) {
             throw new ApplicationException("Carrier network not set.");
         }
         CanadianNetwork network=CanadianNetworks.GetNetwork(carrier.CanadianNetworkNum);
         Etrans etrans=Etranss.CreateCanadianOutput(0,carrier.CarrierNum,carrier.CanadianNetworkNum,clearhouse.ClearinghouseNum,EtransType.RequestPay_CA,0,0);
         //A01 transaction prefix 12 AN
         strb.Append(Canadian.TidyAN(network.CanadianTransactionPrefix,12));
         //A02 office sequence number 6 N
         strb.Append(Canadian.TidyN(etrans.OfficeSequenceNumber,6));
         //A03 format version number 2 N
         strb.Append("04");
         //A04 transaction code 2 N
         strb.Append("06");//payment reconciliation request
         //A05 carrier id number 6 N
         if(network.CanadianIsRprHandler) {
             strb.Append("999999");//Always 999999 if the network handles the RPR requests instead of the carriers in the network.
         }
         else {
             strb.Append(carrier.ElectID);//already validated as 6 digit number.
         }
         //A06 software system id 3 AN
         strb.Append(Canadian.SoftwareSystemId());
         //A10 encryption method 1 N
         if(carrier!=null) {
             strb.Append(carrier.CanadianEncryptionMethod);//validated in UI
         }
         else {
             strb.Append("1");//No encryption when sending to a network.
         }
         //A07 message length N4
         strb.Append(Canadian.TidyN("77",5));
         //A09 carrier transaction counter 5 N
         strb.Append(Canadian.TidyN(etrans.CarrierTransCounter,5));
         //B01 CDA provider number 9 AN
         strb.Append(Canadian.TidyAN(provTreat.NationalProvID,9));//already validated
         //B02 (treating) provider office number 4 AN
         strb.Append(Canadian.TidyAN(provTreat.CanadianOfficeNum,4));//already validated
         //B03 billing provider number 9 AN
         //might need to account for possible 5 digit prov id assigned by carrier
         strb.Append(Canadian.TidyAN(provBilling.NationalProvID,9));//already validated
         //B04 billing provider office number 4 AN
         strb.Append(Canadian.TidyAN(provBilling.CanadianOfficeNum,4));//already validated
         //F33 Reconciliation Date 8 N
         strb.Append(reconciliationDate.ToString("yyyyMMdd"));
         //F38 Current Reconciliation Page Number N 1
         strb.Append(Canadian.TidyN(pageNumber,1));
         //End of message construction.
         string result="";
         bool resultIsError=false;
         try {
             result=Canadian.PassToIca(strb.ToString(),clearhouse);
         }
         catch(ApplicationException ex) {
             result=ex.Message;
             resultIsError=true;
             //Etranss.Delete(etrans.EtransNum);//we don't want to do this, because we want the incremented etrans.OfficeSequenceNumber to be saved
             //Attach an ack indicating failure.
         }
         //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.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;
             }
             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());
         etransAcks.Add(etransAck);
         if(resultIsError) {
             throw new ApplicationException(result);
         }
         CCDField fieldG62=fieldInputter.GetFieldById("G62");//Last reconciliation page number.
         totalPages=PIn.Int(fieldG62.valuestr);
         new FormCCDPrint(etrans,result,true);
         pageNumber++;
     } while(pageNumber<=totalPages);
     return etransAcks;
 }
Пример #23
0
        ///<summary>In progress.  Probably needs a different name.  Info must be validated first.</summary>
        public static string GenerateMessageText(Clearinghouse clearhouse,Carrier carrier,Provider billProv,Clinic clinic,InsPlan insPlan,Patient subscriber,InsSub insSub)
        {
            int batchNum=Clearinghouses.GetNextBatchNumber(clearhouse);
            string groupControlNumber=batchNum.ToString();//Must be unique within file.  We will use batchNum
            int transactionNum=1;
            StringBuilder strb=new StringBuilder();
            //Interchange Control Header
            strb.AppendLine("ISA*00*          *"//ISA01,ISA02: 00 + 10 spaces
                +"00*          *"//ISA03,ISA04: 00 + 10 spaces
                +clearhouse.ISA05+"*"//ISA05: Sender ID type: ZZ=mutually defined. 30=TIN. Validated
                +X12Generator.GetISA06(clearhouse)+"*"//ISA06: Sender ID(TIN). Or might be TIN of Open Dental
                +clearhouse.ISA07+"*"//ISA07: Receiver ID type: ZZ=mutually defined. 30=TIN. Validated
                +Sout(clearhouse.ISA08,15,15)+"*"//ISA08: Receiver ID. Validated to make sure length is at least 2.
                +DateTime.Today.ToString("yyMMdd")+"*"//ISA09: today's date
                +DateTime.Now.ToString("HHmm")+"*"//ISA10: current time
                +"U*00401*"//ISA11 and ISA12.
                //ISA13: interchange control number, right aligned:
                +batchNum.ToString().PadLeft(9,'0')+"*"
                +"0*"//ISA14: no acknowledgment requested
                +clearhouse.ISA15+"*"//ISA15: T=Test P=Production. Validated.
                +":~");//ISA16: use ':'
            //Functional Group Header
            strb.AppendLine("GS*HS*"//GS01: HS for 270 benefit inquiry
                +X12Generator.GetGS02(clearhouse)+"*"//GS02: Senders Code. Sometimes Jordan Sparks.  Sometimes the sending clinic.
                +Sout(clearhouse.GS03,15,2)+"*"//GS03: Application Receiver's Code
                +DateTime.Today.ToString("yyyyMMdd")+"*"//GS04: today's date
                +DateTime.Now.ToString("HHmm")+"*"//GS05: current time
                +groupControlNumber+"*"//GS06: Group control number. Max length 9. No padding necessary.
                +"X*"//GS07: X
                +"004010X092~");//GS08: Version
            //Beginning of transaction--------------------------------------------------------------------------------
            int seg=0;//count segments for the ST-SE transaction
            //Transaction Set Header
            //ST02 Transact. control #. Must be unique within ISA
            seg++;
            strb.AppendLine("ST*270*"//ST01
                +transactionNum.ToString().PadLeft(4,'0')+"~");//ST02
            seg++;
            strb.AppendLine("BHT*0022*13*"//BHT02: 13=request
                +transactionNum.ToString().PadLeft(4,'0')+"*"//BHT03. Can be same as ST02
                +DateTime.Now.ToString("yyyyMMdd")+"*"//BHT04: Date
                +DateTime.Now.ToString("HHmmss")+"~");//BHT05: Time, BHT06: not used
            //HL Loops-----------------------------------------------------------------------------------------------
            int HLcount=1;
            //2000A HL: Information Source--------------------------------------------------------------------------
            seg++;
            strb.AppendLine("HL*"+HLcount.ToString()+"*"//HL01: Heirarchical ID.  Here, it's always 1.
                +"*"//HL02: No parent. Not used
                +"20*"//HL03: Heirarchical level code. 20=Information source
                +"1~");//HL04: Heirarchical child code. 1=child HL present
            //2100A NM1
            seg++;
            strb.AppendLine("NM1*PR*"//NM101: PR=Payer
                +"2*"//NM102: 2=Non person
                +Sout(carrier.CarrierName,35)+"*"//NM103: Name Last.
                +"****"//NM104-07 not used
                +"PI*"//NM108: PI=PayorID
                +Sout(carrier.ElectID,80,2)+"~");//NM109: PayorID. Validated to be at least length of 2.
            HLcount++;
            //2000B HL: Information Receiver------------------------------------------------------------------------
            seg++;
            strb.AppendLine("HL*"+HLcount.ToString()+"*"//HL01: Heirarchical ID.  Here, it's always 2.
                +"1*"//HL02: Heirarchical parent id number.  1 in this simple message.
                +"21*"//HL03: Heirarchical level code. 21=Information receiver
                +"1~");//HL04: Heirarchical child code. 1=child HL present
            seg++;
            //2100B NM1: Information Receiver Name
            strb.AppendLine("NM1*1P*"//NM101: 1P=Provider
                +(billProv.IsNotPerson?"2":"1")+"*"//NM102: 1=person,2=non-person
                +Sout(billProv.LName,35)+"*"//NM103: Last name
                +Sout(billProv.FName,25)+"*"//NM104: First name
                +Sout(billProv.MI,25,1)+"*"//NM105: Middle name
                +"*"//NM106: not used
                +"*"//NM107: Name suffix. not used
                +"XX*"//NM108: ID code qualifier. 24=EIN. 34=SSN, XX=NPI
                +Sout(billProv.NationalProvID,80)+"~");//NM109: ID code. NPI validated
            //2100B REF: Information Receiver ID
            seg++;
            strb.Append("REF*");
            if(billProv.UsingTIN) {
                strb.Append("TJ*");//REF01: qualifier. TJ=Federal TIN
            }
            else {//SSN
                strb.Append("SY*");//REF01: qualifier. SY=SSN
            }
            strb.AppendLine(Sout(billProv.SSN,30)+"~");//REF02: ID
            //2100B N3: Information Receiver Address
            seg++;
            if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
                strb.Append("N3*"+Sout(PrefC.GetString(PrefName.PracticeBillingAddress),55));//N301: Address
            }
            else if(clinic==null) {
                strb.Append("N3*"+Sout(PrefC.GetString(PrefName.PracticeAddress),55));//N301: Address
            }
            else {
                strb.Append("N3*"+Sout(clinic.Address,55));//N301: Address
            }
            if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
                if(PrefC.GetString(PrefName.PracticeBillingAddress2)=="") {
                    strb.AppendLine("~");
                }
                else {
                    //N302: Address2. Optional.
                    strb.AppendLine("*"+Sout(PrefC.GetString(PrefName.PracticeBillingAddress2),55)+"~");
                }
            }
            else if(clinic==null) {
                if(PrefC.GetString(PrefName.PracticeAddress2)=="") {
                    strb.AppendLine("~");
                }
                else {
                    //N302: Address2. Optional.
                    strb.AppendLine("*"+Sout(PrefC.GetString(PrefName.PracticeAddress2),55)+"~");
                }
            }
            else {
                if(clinic.Address2=="") {
                    strb.AppendLine("~");
                }
                else {
                    //N302: Address2. Optional.
                    strb.AppendLine("*"+Sout(clinic.Address2,55)+"~");
                }
            }
            //2100B N4: Information Receiver City/State/Zip
            seg++;
            if(PrefC.GetBool(PrefName.UseBillingAddressOnClaims)) {
                strb.AppendLine("N4*"+Sout(PrefC.GetString(PrefName.PracticeBillingCity),30)+"*"//N401: City
                    +Sout(PrefC.GetString(PrefName.PracticeBillingST),2)+"*"//N402: State
                    +Sout(PrefC.GetString(PrefName.PracticeBillingZip).Replace("-",""),15)+"~");//N403: Zip
            }
            else if(clinic==null) {
                strb.AppendLine("N4*"+Sout(PrefC.GetString(PrefName.PracticeCity),30)+"*"//N401: City
                    +Sout(PrefC.GetString(PrefName.PracticeST),2)+"*"//N402: State
                    +Sout(PrefC.GetString(PrefName.PracticeZip).Replace("-",""),15)+"~");//N403: Zip
            }
            else {
                strb.AppendLine("N4*"+Sout(clinic.City,30)+"*"//N401: City
                    +Sout(clinic.State,2)+"*"//N402: State
                    +Sout(clinic.Zip.Replace("-",""),15)+"~");//N403: Zip
            }
            //2100B PRV: Information Receiver Provider Info
            seg++;
            //PRV*PE*ZZ*1223G0001X~
            strb.AppendLine("PRV*PE*"//PRV01: Provider Code. PE=Performing.  There are many other choices.
                +"ZZ*"//PRV02: ZZ=Mutually defined = health care provider taxonomy code
                +X12Generator.GetTaxonomy(billProv)+"~");//PRV03: Specialty code
            HLcount++;
            //2000C HL: Subscriber-----------------------------------------------------------------------------------
            seg++;
            strb.AppendLine("HL*"+HLcount.ToString()+"*"//HL01: Heirarchical ID.  Here, it's always 3.
                +"2*"//HL02: Heirarchical parent id number.  2 in this simple message.
                +"22*"//HL03: Heirarchical level code. 22=Subscriber
                +"0~");//HL04: Heirarchical child code. 0=no child HL present (no dependent)
            //2000C TRN: Subscriber Trace Number
            seg++;
            strb.AppendLine("TRN*1*"//TRN01: Trace Type Code.  1=Current Transaction Trace Numbers
                +"1*"//TRN02: Trace Number.  We don't really have a good primary key yet.  Keep it simple. Use 1.
                +"1"+billProv.SSN+"~");//TRN03: Entity Identifier. First digit is 1=EIN.  Next 9 digits are EIN.  Length validated.
            //2100C NM1: Subscriber Name
            seg++;
            strb.AppendLine("NM1*IL*"//NM101: IL=Insured or Subscriber
                +"1*"//NM102: 1=Person
                +Sout(subscriber.LName,35)+"*"//NM103: LName
                +Sout(subscriber.FName,25)+"*"//NM104: FName
                +Sout(subscriber.MiddleI,25)+"*"//NM105: MiddleName
                +"*"//NM106: not used
                +"*"//NM107: suffix. Not present in Open Dental yet.
                +"MI*"//NM108: MI=MemberID
                +Sout(insSub.SubscriberID.Replace("-",""),80)+"~");//NM109: Subscriber ID. Validated to be L>2.
            //2100C REF: Subscriber Additional Information.  Without this, old plans seem to be frequently returned.
            seg++;
            strb.AppendLine("REF*6P*"//REF01: 6P=GroupNumber
                +Sout(insPlan.GroupNum,30)+"~");//REF02: Supplemental ID. Validated.
            //2100C DMG: Subscriber Demographic Information
            seg++;
            strb.AppendLine("DMG*D8*"//DMG01: Date Time Period Qualifier.  D8=CCYYMMDD
                +subscriber.Birthdate.ToString("yyyyMMdd")+"~");//DMG02: Subscriber birthdate.  Validated
                //DMG03: Gender code.  Situational.  F or M.  Since this was left out in the example,
                //and since we don't want to send the wrong gender, we will not send this element.
            //2100C DTP: Subscriber Date.  Deduced through trial and error that this is required by EHG even though not by X12 specs.
            seg++;
            strb.AppendLine("DTP*307*"//DTP01: Qualifier.  307=Eligibility
                +"D8*"//DTP02: Format Qualifier.
                +DateTime.Today.ToString("yyyyMMdd")+"~");//DTP03: Date
            //2110C EQ: Subscriber Eligibility or Benefit Enquiry Information
            //We can loop this 99 times to request very specific benefits.
            //strb.AppendLine("EQ*30~");//EQ01: 30=General Coverage
            seg++;
            strb.AppendLine("EQ*23~");//Diagnostic
            seg++;
            strb.AppendLine("EQ*4~");//Diagnostic Xray
            seg++;
            strb.AppendLine("EQ*41~");//Routine Preventive
            seg++;
            strb.AppendLine("EQ*25~");//Restorative
            seg++;
            strb.AppendLine("EQ*26~");//Endo
            seg++;
            strb.AppendLine("EQ*24~");//Perio
            seg++;
            strb.AppendLine("EQ*40~");//Oral Surgery
            seg++;
            strb.AppendLine("EQ*36~");//Crowns
            seg++;
            strb.AppendLine("EQ*39~");//Prosth
            seg++;
            strb.AppendLine("EQ*27~");//Maxillofacial Prosth
            seg++;
            strb.AppendLine("EQ*37~");//Accident
            seg++;
            strb.AppendLine("EQ*38~");//Ortho
            seg++;
            strb.AppendLine("EQ*28~");//Adjunctive
            //
            //2000D If we add a dependent loop it would go here.  It would be about 20 lines.
            //2100D, etc
            //EQ series, etc.
            //Not allowed to send this unless subscriber and dependent are different
            //We would also have to add code to process the EBs which distinguishes between subscribers and dependents.
            //
            //Transaction Trailer
            seg++;
            strb.AppendLine("SE*"
                +seg.ToString()+"*"//SE01: Total segments, including ST & SE
                +transactionNum.ToString().PadLeft(4,'0')+"~");
            //End of transaction--------------------------------------------------------------------------------------
            //Functional Group Trailer
            strb.AppendLine("GE*"+transactionNum.ToString()+"*"//GE01: Number of transaction sets included
                +groupControlNumber+"~");//GE02: Group Control number. Must be identical to GS06
            //Interchange Control Trailer
            strb.AppendLine("IEA*1*"//IEA01: number of functional groups
                +batchNum.ToString().PadLeft(9,'0')+"~");//IEA02: Interchange control number
            return strb.ToString();
            /*
            return @"
            ISA*00*          *00*          *30*AA0989922      *30*330989922      *030519*1608*U*00401*000012145*1*T*:~
            GS*HS*AA0989922*330989922*20030519*1608*12145*X*004010X092~
            ST*270*0001~
            BHT*0022*13*ASX012145WEB*20030519*1608~
            HL*1**20*1~
            NM1*PR*2*Metlife*****PI*65978~
            HL*2*1*21*1~
            NM1*1P*1*PROVLAST*PROVFIRST****XX*1234567893~
            REF*TJ*200384584~
            N3*JUNIT ROAD~
            N4*CHICAGO*IL*60602~
            PRV*PE*ZZ*1223G0001X~
            HL*3*2*22*0~
            TRN*1*12145*1AA0989922~
            NM1*IL*1*SUBLASTNAME*SUBFIRSTNAME****MI*123456789~
            DMG*D8*19750323~
            DTP*307*D8*20030519~
            EQ*30~
            SE*17*0001~
            GE*1*12145~
            IEA*1*000012145~";
            */

            //return "ISA*00*          *00*          *30*AA0989922      *30*330989922      *030519*1608*U*00401*000012145*1*T*:~GS*HS*AA0989922*330989922*20030519*1608*12145*X*004010X092~ST*270*0001~BHT*0022*13*ASX012145WEB*20030519*1608~HL*1**20*1~NM1*PR*2*Metlife*****PI*65978~HL*2*1*21*1~NM1*1P*1*PROVLAST*PROVFIRST****XX*1234567893~REF*TJ*200384584~N3*JUNIT ROAD~N4*CHICAGO*IL*60602~PRV*PE*ZZ*1223G0001X~HL*3*2*22*0~TRN*1*12145*1AA0989922~NM1*IL*1*SUBLASTNAME*SUBFIRSTNAME****MI*123456789~DMG*D8*19750323~DTP*307*D8*20030519~EQ*30~SE*17*0001~GE*1*12145~IEA*1*000012145~";
        }
Пример #24
0
 //THIS TRANSACTION TYPE IS NOT USED BY ANY CANADIAN CARRIERS, AND IS NOT PART OF CERTIFICATION, EVEN THOUGH IT IS IN THE SPECIFICATIONS. WE NEED TO FIX BELOW COMMENTS AND MAKE THIS CODE FUNCTION MORE LIKE THE GetPaymentReconciliations() FUNCTION ABOVE.
 ///<summary>Does not exist in version 02 so only supported for version 04. Returns the request Etrans record. Usually pass in a carrier with network null.  If sending to a network, carrier will be null and we still don't see anywhere in the message format to specify network.  We expect to get clarification on this issue later. Validate provTreat as a CDANet provider before calling this function.</summary>
 public static Etrans GetSummaryReconciliation(Carrier carrier,CanadianNetwork network,Provider provTreat,DateTime reconciliationDate)
 {
     Clearinghouse clearhouse=Canadian.GetClearinghouse();
     if(clearhouse==null) {
         throw new ApplicationException("Canadian clearinghouse not found.");
     }
     string saveFolder=clearhouse.ExportPath;
     if(!Directory.Exists(saveFolder)) {
         throw new ApplicationException(saveFolder+" not found.");
     }
     StringBuilder strb=new StringBuilder();
     Etrans etrans=null;
     if(carrier!=null) {
         if((carrier.CanadianSupportedTypes&CanSupTransTypes.RequestForSummaryReconciliation_05)!=CanSupTransTypes.RequestForSummaryReconciliation_05) {
             throw new ApplicationException("The carrier does not support summary reconciliation transactions.");
         }
         etrans=Etranss.CreateCanadianOutput(0,carrier.CarrierNum,carrier.CanadianNetworkNum,
             clearhouse.ClearinghouseNum,EtransType.RequestSumm_CA,0,0);
     }
     else {//Assume network!=null
         etrans=Etranss.CreateCanadianOutput(0,0,network.CanadianNetworkNum,
             clearhouse.ClearinghouseNum,EtransType.RequestSumm_CA,0,0);
     }
     //A01 transaction prefix 12 AN
     strb.Append(Canadian.TidyAN(network.CanadianTransactionPrefix,12));
     //A02 office sequence number 6 N
     strb.Append(Canadian.TidyN(etrans.OfficeSequenceNumber,6));
     //A03 format version number 2 N
     strb.Append("04");
     //A04 transaction code 2 N
     strb.Append("05");//payment reconciliation request
     //A05 carrier id number 6 N
     if(carrier!=null) {
         strb.Append(carrier.ElectID);//already validated as 6 digit number.
     }
     else { //Assume network!=null
         strb.Append("999999");//Always 999999 when sending to a network.
     }
     //A06 software system id 3 AN
     strb.Append(Canadian.SoftwareSystemId());
     //A10 encryption method 1 N
     if(carrier!=null) {
         strb.Append(carrier.CanadianEncryptionMethod);//validated in UI
     }
     else { //Assume network!=null
         strb.Append("1");//No encryption when sending to a network.
     }
     //A07 message length N4
     strb.Append(Canadian.TidyN("63",5));
     //A09 carrier transaction counter 5 N
     strb.Append(Canadian.TidyN(etrans.CarrierTransCounter,5));
     //B01 CDA provider number 9 AN
     strb.Append(Canadian.TidyAN(provTreat.NationalProvID,9));//already validated
     //B02 (treating) provider office number 4 AN
     strb.Append(Canadian.TidyAN(provTreat.CanadianOfficeNum,4));//already validated
     //F33 Reconciliation Date 8 N
     strb.Append(reconciliationDate.ToString("yyyyMMdd"));
     //End of message construction.
     string result="";
     bool resultIsError=false;
     try {
         if(carrier!=null) {
             result=Canadian.PassToIca(strb.ToString(),clearhouse);
         }
         else { //Assume network!=null
             result=Canadian.PassToIca(strb.ToString(),clearhouse);
         }
     }
     catch(ApplicationException ex) {
         result=ex.Message;
         resultIsError=true;
         //Etranss.Delete(etrans.EtransNum);//we don't want to do this, because we want the incremented etrans.OfficeSequenceNumber to be saved
         //Attach an ack indicating failure.
     }
     //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.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;
         }
         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);
     }
     new FormCCDPrint(etrans,result,true);
     return etrans;
 }
		private static string Run(int scriptNum,Carrier carrier,CanadianNetwork network,Provider prov,out Etrans etrans,DateTime reconciliationDate) {
			string retVal="";
			etrans=CanadianOutput.GetSummaryReconciliation(carrier,network,prov,reconciliationDate);
			retVal+="Summary Reconciliation#"+scriptNum.ToString()+" successful.\r\n";
			return retVal;
		}
Пример #26
0
		///<summary>Returns number of subscribers affected.  Can throw an exception if user clicks cancel in a note box.</summary>
		private static int ProcessTrojanPlan(string trojanPlan,bool updateBenefits,bool updateNoteAutomatic){
			TrojanObject troj=ProcessTextToObject(trojanPlan);
			Carrier carrier=new Carrier();
			carrier.Phone=troj.ELIGPHONE;
			carrier.ElectID=troj.PAYERID;
			carrier.CarrierName=troj.MAILTO;
			carrier.Address=troj.MAILTOST;
			carrier.City=troj.MAILCITYONLY;
			carrier.State=troj.MAILSTATEONLY;
			carrier.Zip=troj.MAILZIPONLY;
			carrier.NoSendElect=false;//regardless of what Trojan says.  Nobody sends paper anymore.
			if(carrier.CarrierName==null || carrier.CarrierName=="") {
				//if, for some reason, carrier is absent from the file, we can't do a thing with it.
				return 0;
			}
			carrier=Carriers.GetIndentical(carrier);
			//now, save this all to the database.
			troj.CarrierNum=carrier.CarrierNum;
			InsPlan plan=TrojanQueries.GetPlanWithTrojanID(troj.TROJANID);
			if(plan==null) {
				return 0;
			}
			TrojanQueries.UpdatePlan(troj,plan.PlanNum,updateBenefits);
			plan=InsPlans.RefreshOne(plan.PlanNum);
			if(updateNoteAutomatic) {
				if(plan.PlanNote!=troj.PlanNote) {
					plan.PlanNote=troj.PlanNote;
					InsPlans.Update(plan);
				}
			}
			else {
				//let user pick note
				if(plan.PlanNote!=troj.PlanNote) {
					string[] notes=new string[2];
					notes[0]=plan.PlanNote;
					notes[1]=troj.PlanNote;
					FormNotePick FormN=new FormNotePick(notes);
					FormN.ShowDialog();
					if(FormN.DialogResult==DialogResult.OK) {
						if(plan.PlanNote!=FormN.SelectedNote) {
							plan.PlanNote=FormN.SelectedNote;
							InsPlans.Update(plan);
						}
					}
				}
			}
			return 1;
		}
Пример #27
0
 ///<summary>Fills the carrier fields on the form based on the specified carrierNum.</summary>
 private void FillCarrier1(long carrierNum)
 {
     selectedCarrier1=Carriers.GetCarrier(carrierNum);
     textCarrier1.Text=selectedCarrier1.CarrierName;
     textPhone1.Text=selectedCarrier1.Phone;
 }
Пример #28
0
 private void FormSheetImport_Load(object sender,EventArgs e)
 {
     if(SheetCur!=null) {
         pat=Patients.GetPat(SheetCur.PatNum);
     }
     else {
         throw new NotImplementedException();//js this broke with the move to dot net 4.0.
         /*
         pat=Patients.GetPat(DocCur.PatNum);
         CAcroApp acroApp=null;
         try {
             acroApp=new AcroAppClass();//Initialize Acrobat by creating App object
         }
         catch {
             MsgBox.Show(this,"Requires Acrobat 9 Pro to be installed on this computer.");
             DialogResult=DialogResult.Cancel;
             return;
         }
         //acroApp.Show();// Show Acrobat Viewer
         //acroApp.Hide();//This is annoying if Acrobat is already open for some other reason.
         CAcroAVDoc avDoc=new AcroAVDocClass();
         string pathToPdf=CodeBase.ODFileUtils.CombinePaths(ImageStore.GetPatientFolder(pat),DocCur.FileName);
         if(!avDoc.Open(pathToPdf,"")){
             MessageBox.Show(Lan.g(this,"Could not open")+" "+pathToPdf);
             DialogResult=DialogResult.Cancel;
             return;
         }
         IAFormApp formApp=new AFormAppClass();//Create a IAFormApp object so we can access the form fields in the open document
         IFields myFields=(IFields)formApp.Fields;// Get the IFields object associated with the form
         IEnumerator myEnumerator = myFields.GetEnumerator();// Get the IEnumerator object for myFields
         dictAcrobatFields=new Dictionary<string,string>();
         IField myField;
         string nameClean;
         string valClean;
         while(myEnumerator.MoveNext()) {
             myField=(IField)myEnumerator.Current;// Get the IField object
             if(myField.Value==null){
                 continue;
             }
             //if the form was designed in LiveCycle, the names will look like this: topmostSubform[0].page1[0].SSN[0]
             //Whereas, if it was designed in Acrobat, the names will look like this: SSN
             //So...
             nameClean=myField.Name;
             if(nameClean.Contains("[") && nameClean.Contains(".")) {
                 nameClean=nameClean.Substring(nameClean.LastIndexOf(".")+1);
                 nameClean=nameClean.Substring(0,nameClean.IndexOf("["));
             }
             if(nameClean=="misc") {
                 int suffix=1;
                 nameClean=nameClean+suffix.ToString();
                 while(dictAcrobatFields.ContainsKey(nameClean)) {//untested.
                     suffix++;
                     nameClean=nameClean+suffix.ToString();
                 }
             }
             valClean=myField.Value;
             if(valClean=="Off") {
                 valClean="";
             }
             //myField.Type//possible values include text,radiobutton,checkbox
             //MessageBox.Show("Raw:"+myField.Name+"  Name:"+nameClean+"  Value:"+myField.Value);
             if(dictAcrobatFields.ContainsKey(nameClean)) {
                 continue;
             }
             dictAcrobatFields.Add(nameClean,valClean);
             //name:topmostSubform[0].page1[0].SSN[0]
         }
         //acroApp.Hide();//Doesn't work well enough
         //this.BringToFront();//Doesn't work
         //acroApp.Minimize();
         acroApp.Exit();
         acroApp=null;
         */
     }
     fam=Patients.GetFamily(pat.PatNum);
     AddressSameForFam=true;
     for(int i=0;i<fam.ListPats.Length;i++) {
         if(pat.HmPhone!=fam.ListPats[i].HmPhone
             || pat.Address!=fam.ListPats[i].Address
             || pat.Address2!=fam.ListPats[i].Address2
             || pat.City!=fam.ListPats[i].City
             || pat.State!=fam.ListPats[i].State
             || pat.Zip!=fam.ListPats[i].Zip)
         {
             AddressSameForFam=false;
             break;
         }
     }
     patPlanList=PatPlans.Refresh(pat.PatNum);
     subList=InsSubs.RefreshForFam(fam);
     planList=InsPlans.RefreshForSubList(subList);
     if(patPlanList.Count==0) {
         patPlan1=null;
         plan1=null;
         sub1=null;
         ins1Relat=null;
         carrier1=null;
     }
     else {
         patPlan1=patPlanList[0];
         sub1=InsSubs.GetSub(patPlan1.InsSubNum,subList);
         plan1=InsPlans.GetPlan(sub1.PlanNum,planList);
         ins1Relat=patPlan1.Relationship;
         carrier1=Carriers.GetCarrier(plan1.CarrierNum);
     }
     if(patPlanList.Count<2) {
         patPlan2=null;
         plan2=null;
         sub2=null;
         ins2Relat=null;
         carrier2=null;
     }
     else {
         patPlan2=patPlanList[1];
         sub2=InsSubs.GetSub(patPlan2.InsSubNum,subList);
         plan2=InsPlans.GetPlan(sub2.PlanNum,planList);
         ins2Relat=patPlan2.Relationship;
         carrier2=Carriers.GetCarrier(plan2.CarrierNum);
     }
     FillRows();
     FillGrid();
 }
Пример #29
0
		private void Init(){
			InitializeComponent();
			breakLinePen.Width=2;
			if(etrans.PatNum!=0) { //Some transactions are not patient specific.
				patient=Patients.GetPat(etrans.PatNum);
				patPlansForPat=PatPlans.Refresh(etrans.PatNum);
				claim=Claims.GetClaim(etrans.ClaimNum);
				primaryCarrier=Carriers.GetCarrier(etrans.CarrierNum);
				if(claim==null) {//for eligibility
					//Get primary info
					insSub=InsSubs.GetSub(etrans.InsSubNum,new List<InsSub>());
					subscriber=Patients.GetPat(insSub.Subscriber);
					insplan=InsPlans.GetPlan(etrans.PlanNum,new List<InsPlan>());
					patPlanPri=PatPlans.GetFromList(patPlansForPat,insSub.InsSubNum);
				}
				else {
					//Get primary info
					insSub=InsSubs.GetSub(claim.InsSubNum,new List<InsSub>());
					subscriber=Patients.GetPat(insSub.Subscriber);
					insplan=InsPlans.GetPlan(claim.PlanNum,new List<InsPlan>());
					patPlanPri=PatPlans.GetFromList(patPlansForPat,insSub.InsSubNum);
					//Get secondary info
					if(claim.InsSubNum2!=0) {
						patPlanSec=PatPlans.GetFromList(patPlansForPat,claim.InsSubNum2);
						insSub2=InsSubs.GetSub(claim.InsSubNum2,new List<InsSub>());
						subscriber2=Patients.GetPat(insSub2.Subscriber);
						insplan2=InsPlans.GetPlan(claim.PlanNum2,new List<InsPlan>());
						secondaryCarrier=Carriers.GetCarrier(insplan2.CarrierNum);
					}
					//Provider info
					provTreat=Providers.GetProv(claim.ProvTreat);
					provBill=Providers.GetProv(claim.ProvBill);
					//Claim related info
					claimprocs=ClaimProcs.RefreshForClaim(claim.ClaimNum);
					long clinicNum=0;
					for(int i=0;i<claimprocs.Count;i++) {
						if(claimprocs[i].ClinicNum!=0) {
							clinicNum=claimprocs[i].ClinicNum;
							break;
						}
					}
					if(clinicNum!=0) {
						clinic=Clinics.GetClinic(clinicNum);
					}
					else if(!PrefC.GetBool(PrefName.EasyNoClinics) && Clinics.List.Length>0) {
						clinic=Clinics.List[0];
					}
				}
				if(provTreat==null) {
					provTreat=Providers.GetProv(Patients.GetProvNum(patient));
				}
				if(provBill==null) {
					provBill=Providers.GetProv(Patients.GetProvNum(patient));
				}
				List<Procedure> procsAll=Procedures.Refresh(etrans.PatNum);
				extracted=Procedures.GetCanadianExtractedTeeth(procsAll);
			}
			if(MessageText==null || MessageText.Length<23) {
				throw new Exception("CCD message format too short: "+MessageText);
			}
			formData=new CCDFieldInputter(MessageText);//Input the fields of the given message.
			CCDField languageOfInsured=formData.GetFieldById("G27");
			if(languageOfInsured!=null) {
				if(languageOfInsured.valuestr=="F") {
					isFrench=true;
				}
			}
			else if(subscriber!=null && subscriber.Language=="fr") {
				isFrench=true;
			}
			formatVersionNumber=formData.GetFieldById("A03").valuestr;//Must always exist so no error checking here.
			transactionCode=formData.GetFieldById("A04").valuestr;//Must always exist so no error checking here.
			if(formatVersionNumber=="04") {//FormId field does not exist in version 02 in any of the message texts.
				CCDField formIdField=formData.GetFieldById("G42");//Usually exists in version 04 response messages.
				//Only a few response transactions don't define field G42. So far, those are transactions 15 (Summary Reconciliation), 16 (Payment Reconciliation) and 24 (Email).
				//In these cases, we simply do not use the formId field later on in the display code.
				if(formIdField!=null) {
					formId=formIdField.valuestr;
				}
			}
			else {//Version 02
				//Since there is no FormID field in version 02, we figure out what the formId should be based on the transaction type.
				if(transactionCode=="10") {//Eligibility Response.
					formId="08";//Eligibility Form
				}
				else if(transactionCode=="11") {//Claim Response.
					formId="03";//Claim Acknowledgement Form
				}
				else if(transactionCode=="21") {//EOB
					formId="01";//EOB Form
					CCDField g02=formData.GetFieldById("G02");
					if(g02!=null && g02.valuestr=="Y") {
						formId="04";//Employer Certified.
					}
				}
				else if(transactionCode=="13") {//Response to Pre-Determination.
					formId="06";//Pre-Determination Acknowledgement Form
				}
				else if(transactionCode=="12") { //Reversal response
					//There is no standard form for a reversal response, but we print the reversal response later on based on the transactioncode so we don't need to do anything here.
				}
				else {
					throw new Exception("Unhandled transactionCode '"+transactionCode+"' for version 02 message.");
				}
			}
			CCDField status=formData.GetFieldById("G05");
			if(status!=null && status.valuestr!=null) {
				responseStatus=status.valuestr.ToUpper();
			}
			transactionCode=formData.GetFieldById("A04").valuestr;
			predetermination=(transactionCode=="23"||transactionCode=="13");//Be sure to list all predetermination response types here!
			if(copiesToPrint<=0) { //Show the form on screen if there are no copies to print.
				ShowDisplayMessages();
				CCDField fieldPayTo=formData.GetFieldById("F01");
				if(fieldPayTo!=null) {
					bool paySubscriber=(fieldPayTo.valuestr=="1");//same for version 02 and version 04
					//Typically, insurance companies in Canada prefer to pay the subscriber instead of the dentist.
					if(AssignmentOfBenefits()) {//The insurance plan is set to pay the dentist
						if(paySubscriber) {//The carrier has decided to pay the subscriber.
							MsgBox.Show("Canadian","INFORMATION: The carrier changed the payee from the dentist to the subscriber.");//This check was required for certification.
						}
					}
					else {//The insurance plan is set to pay the subscriber
						if(!paySubscriber) {//The carrier has decided to pay the dentist.
							MsgBox.Show("Canadian","INFORMATION: The carrier changed the payee from the subscriber to the dentist.");//This check was required for certification.
						}
					}
				}
				CCDField paymentAdjustmentAmount=formData.GetFieldById("G33");
				if(paymentAdjustmentAmount!=null) {
					if(paymentAdjustmentAmount.valuestr.Substring(1)!="000000") {
						MessageBox.Show(Lan.g(this,"Payment adjustment amount")+": "+RawMoneyStrToDisplayMoney(paymentAdjustmentAmount.valuestr));
					}
				}
				if(autoPrint) {
					if(responseStatus!="R") { //We are not required to automatically print rejection notices.
						//Automatically print a patient copy only. We are never required to autoprint a dentist copy, but it can be done manually instead.
						new FormCCDPrint(etrans.Copy(),MessageText,1,false,true);
					}
				}
				if(formId=="05") { //Manual claim form
					Canadian.ShowManualClaimForm(claim);
					Close();
				}
				else {
					pd=CreatePrintDocument();
					printPreviewControl1.Document=pd;//Setting the document causes system to call pd_PrintPage, which will print the document in the preview window.
					ShowDialog();
				}
			}
			else {
				pd=CreatePrintDocument();
				if(formId=="05") { //Manual claim form
#if DEBUG
					Canadian.ShowManualClaimForm(claim);
#else
					Canadian.PrintManualClaimForm(claim);//Send the print job to the physical printer.
#endif
				}
				else {
#if DEBUG
					new FormCCDPrint(etrans.Copy(),MessageText,0,false,patientCopy);//Show the form on the screen.
#else
					pd.Print();//Send the print job to the physical printer.
#endif
				}
				//Print the remaining copies recursively.
				if(copiesToPrint>=2) {
					new FormCCDPrint(etrans.Copy(),MessageText,copiesToPrint-1,false,patientCopy);
				}
			}
			CCDField embeddedTransaction=formData.GetFieldById("G40");
			if(embeddedTransaction!=null) {
				new FormCCDPrint(etrans.Copy(),embeddedTransaction.valuestr,copiesToPrint,autoPrint,patientCopy);
			}
		}
Пример #30
0
		private static bool IsWashingtonMedicaid(Clearinghouse clearinghouse,Carrier carrier) {
			return ((clearinghouse.ISA08=="77045" && clearinghouse.ISA02=="00") || carrier.ElectID=="CKWA1" || carrier.ElectID=="77045");
		}