///<summary></summary> public static long Insert(HL7Msg hL7Msg) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { hL7Msg.HL7MsgNum=Meth.GetLong(MethodBase.GetCurrentMethod(),hL7Msg); return hL7Msg.HL7MsgNum; } return Crud.HL7MsgCrud.Insert(hL7Msg); }
///<summary>Gets the message control ID of the message we are attempting to send, for TCP/IP acknowledgment.</summary> public static string GetControlId(HL7Msg msg) { string retval = ""; if (msg == null) { return(retval); } int controlIdOrder = 0; MessageHL7 msgHl7 = new MessageHL7(msg.MsgText); //creates the segments HL7Def def = HL7Defs.GetOneDeepEnabled(); if (def == null) { return(retval); } HL7DefMessage hl7defmsg = null; for (int i = 0; i < def.hl7DefMessages.Count; i++) { if (def.hl7DefMessages[i].MessageType == msgHl7.MsgType) { hl7defmsg = def.hl7DefMessages[i]; break; } } if (hl7defmsg == null) //No message definition for this type of message in the enabled def { return(retval); } for (int s = 0; s < hl7defmsg.hl7DefSegments.Count; s++) //get MSH segment { if (hl7defmsg.hl7DefSegments[s].SegmentName == SegmentNameHL7.MSH) { for (int f = 0; f < hl7defmsg.hl7DefSegments[s].hl7DefFields.Count; f++) //find messageControlId field in MSH segment def { if (hl7defmsg.hl7DefSegments[s].hl7DefFields[f].FieldName == "messageControlId") { controlIdOrder = hl7defmsg.hl7DefSegments[s].hl7DefFields[f].OrdinalPos; break; } } break; } } if (controlIdOrder == 0) //No messageControlId defined for this MSH segment { return(retval); } for (int i = 0; i < msgHl7.Segments.Count; i++) //get control ID from message located in MSH segment with field determined above { if (msgHl7.Segments[i].Name == SegmentNameHL7.MSH) { retval = msgHl7.Segments[i].Fields[controlIdOrder].ToString(); break; } } return(retval); }
///<summary></summary> public static void Update(HL7Msg hL7Msg) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(),hL7Msg); return; } Crud.HL7MsgCrud.Update(hL7Msg); }
///<summary></summary> public static long Insert(HL7Msg hL7Msg) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { hL7Msg.HL7MsgNum = Meth.GetLong(MethodBase.GetCurrentMethod(), hL7Msg); return(hL7Msg.HL7MsgNum); } return(Crud.HL7MsgCrud.Insert(hL7Msg)); }
///<summary></summary> public static void Update(HL7Msg hL7Msg) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(), hL7Msg); return; } Crud.HL7MsgCrud.Update(hL7Msg); }
public static List <HL7Msg> GetOneExisting(HL7Msg hl7Msg) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <List <HL7Msg> >(MethodBase.GetCurrentMethod(), hl7Msg)); } string command = "SELECT * FROM hl7msg WHERE MsgText='" + POut.String(hl7Msg.MsgText) + "' " + DbHelper.LimitAnd(1); return(Crud.HL7MsgCrud.SelectMany(command)); //Just 0 or 1 item in list for now. }
public static void UpdateDateTStamp(HL7Msg hl7Msg) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(), hl7Msg); return; } string command = "UPDATE hl7msg SET DateTStamp=CURRENT_TIMESTAMP WHERE MsgText='" + POut.String(hl7Msg.MsgText) + "' "; Db.NonQ(command); }
public static List <HL7Msg> GetOneExisting(HL7Msg hl7Msg) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <List <HL7Msg> >(MethodBase.GetCurrentMethod(), hl7Msg)); } //Might want to change the following query to: //string command="SELECT * FROM hl7msg WHERE HL7Status IN("+POut.Long((int)HL7MessageStatus.InProcessed)+","+POut.Long((int)HL7MessageStatus.OutSent) //+") AND MsgText='"+POut.String(hl7Msg.MsgText)+"' "+DbHelper.LimitAnd(1); string command = "SELECT * FROM hl7msg WHERE MsgText='" + POut.String(hl7Msg.MsgText) + "' " + DbHelper.LimitAnd(1); return(Crud.HL7MsgCrud.SelectMany(command)); //Just 0 or 1 item in list for now. }
public static void UpdateDateTStamp(HL7Msg hl7Msg) { if (string.IsNullOrWhiteSpace(hl7Msg.MsgText)) //don't update DateTStamp if MsgText is blank, that would be all messages more than 4 months old { return; } if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(), hl7Msg); return; } string command = "UPDATE hl7msg SET DateTStamp=CURRENT_TIMESTAMP WHERE MsgText='" + POut.String(hl7Msg.MsgText) + "' "; Db.NonQ(command); }
//OD accepts commandline arguments from eCW. That's handled in FormOpenDental. //public static void SendHL7(Appointment apt,Patient pat) { // OpenDentBusiness.HL7.DFT dft=new OpenDentBusiness.HL7.DFT(apt,pat); // HL7Msg msg=new HL7Msg(); // msg.AptNum=apt.AptNum; // msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. // msg.MsgText=dft.GenerateMessage(); // HL7Msgs.Insert(msg); //} public static void SendHL7(long aptNum,long provNum,Patient pat,string pdfDataBase64,string pdfDescription,bool justPDF) { OpenDentBusiness.HL7.EcwDFT dft=new OpenDentBusiness.HL7.EcwDFT(); dft.InitializeEcw(aptNum,provNum,pat,pdfDataBase64,pdfDescription,justPDF); HL7Msg msg=new HL7Msg(); if(justPDF){ msg.AptNum=0;//Prevents the appt complete button from changing to the "Revise" button prematurely. } else{ msg.AptNum=aptNum; } msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. msg.MsgText=dft.GenerateMessage(); msg.PatNum=pat.PatNum; HL7Msgs.Insert(msg); }
///<summary>Gets the message control ID of the message we are attempting to send, for TCP/IP acknowledgment.</summary> public static string GetControlId(HL7Msg msg) { string retval=""; if(msg==null) { return retval; } int controlIdOrder=0; MessageHL7 msgHl7=new MessageHL7(msg.MsgText);//creates the segments HL7Def def=HL7Defs.GetOneDeepEnabled(); if(def==null) { return retval; } HL7DefMessage hl7defmsg=null; for(int i=0;i<def.hl7DefMessages.Count;i++) { if(def.hl7DefMessages[i].MessageType==msgHl7.MsgType) { hl7defmsg=def.hl7DefMessages[i]; break; } } if(hl7defmsg==null) {//No message definition for this type of message in the enabled def return retval; } for(int s=0;s<hl7defmsg.hl7DefSegments.Count;s++) {//get MSH segment if(hl7defmsg.hl7DefSegments[s].SegmentName==SegmentNameHL7.MSH) { for(int f=0;f<hl7defmsg.hl7DefSegments[s].hl7DefFields.Count;f++) {//find messageControlId field in MSH segment def if(hl7defmsg.hl7DefSegments[s].hl7DefFields[f].FieldName=="messageControlId") { controlIdOrder=hl7defmsg.hl7DefSegments[s].hl7DefFields[f].OrdinalPos; break; } } break; } } if(controlIdOrder==0) {//No messageControlId defined for this MSH segment return retval; } for(int i=0;i<msgHl7.Segments.Count;i++) {//get control ID from message located in MSH segment with field determined above if(msgHl7.Segments[i].Name==SegmentNameHL7.MSH) { retval=msgHl7.Segments[i].Fields[controlIdOrder].ToString(); break; } } return retval; }
///<summary>Usually dropping an appointment to a new location.</summary> private void ContrApptSheet2_MouseUp(object sender,System.Windows.Forms.MouseEventArgs e) { if(!mouseIsDown) { return; } /*if(ApptDrawing.IsWeeklyView) { ResizingAppt=false; mouseIsDown=false; TempApptSingle.Dispose(); return; }*/ int thisIndex=GetIndex(ContrApptSingle.SelectedAptNum); Appointment aptOld; //Resizing------------------------------------------------------------------------------------------------------------- if(ResizingAppt) { if(!TempApptSingle.Visible) {//click with no drag ResizingAppt=false; mouseIsDown=false; TempApptSingle.Dispose(); return; } //convert Bottom to a time int hr=ApptDrawing.ConvertToHour (TempApptSingle.Bottom-ContrApptSheet2.Location.Y-panelSheet.Location.Y); int minute=ApptDrawing.ConvertToMin (TempApptSingle.Bottom-ContrApptSheet2.Location.Y-panelSheet.Location.Y); TimeSpan bottomSpan=new TimeSpan(hr,minute,0); //subtract to get the new length of appt TimeSpan newspan=bottomSpan-PIn.DateT(TempApptSingle.DataRoww["AptDateTime"].ToString()).TimeOfDay; int newpatternL=(int)newspan.TotalMinutes/5; if(newpatternL < ApptDrawing.MinPerIncr/5) {//eg. if 1 < 10/5, would make appt too short. newpatternL=ApptDrawing.MinPerIncr/5;//sets new pattern length at one increment, typically 2 or 3 5min blocks } else if(newpatternL>78) {//max length of 390 minutes newpatternL=78; } string pattern=TempApptSingle.DataRoww["Pattern"].ToString(); if(newpatternL<pattern.Length) {//shorten to match new pattern length pattern=pattern.Substring(0,newpatternL); } else if(newpatternL>pattern.Length) {//make pattern longer. pattern=pattern.PadRight(newpatternL,'/'); } //Now, check for overlap with other appts. DateTime aptDateTime; DateTime aptDateTimeCur=PIn.DateT(TempApptSingle.DataRoww["AptDateTime"].ToString()); for(int i=0;i<DS.Tables["Appointments"].Rows.Count;i++) { if(DS.Tables["Appointments"].Rows[i]["AptNum"].ToString()==TempApptSingle.DataRoww["AptNum"].ToString()) { continue; } if(DS.Tables["Appointments"].Rows[i]["Op"].ToString()!=TempApptSingle.DataRoww["Op"].ToString()) { continue; } aptDateTime=PIn.DateT(DS.Tables["Appointments"].Rows[i]["AptDateTime"].ToString()); if(ApptDrawing.IsWeeklyView && aptDateTime.Date!=aptDateTimeCur.Date) { continue; } if(aptDateTime<aptDateTimeCur) { continue;//we don't care about appointments that are earlier than this one } if(aptDateTime.TimeOfDay < aptDateTimeCur.TimeOfDay+TimeSpan.FromMinutes(5*pattern.Length)) { newspan=aptDateTime.TimeOfDay-aptDateTimeCur.TimeOfDay; newpatternL=(int)newspan.TotalMinutes/5; pattern=pattern.Substring(0,newpatternL); } } if(pattern=="") { pattern="///"; } Appointments.SetPattern(PIn.Long(TempApptSingle.DataRoww["AptNum"].ToString()),pattern); ResizingAppt=false; mouseIsDown=false; TempApptSingle.Dispose(); RefreshModuleDataPatient(PatCur.PatNum); OnPatientSelected(PatCur); //RefreshModulePatient(PatCurNum); RefreshPeriod(); bubbleAptNum=0; SetInvalid(); return; } if((Math.Abs(e.X-mouseOrigin.X)<7) &&(Math.Abs(e.Y-mouseOrigin.Y)<7)) { boolAptMoved=false; } //it was a click with no drag----------------------------------------------------------------------------------------- if(!boolAptMoved) { mouseIsDown=false; TempApptSingle.Dispose(); return; } //dragging to pinboard, so place a copy there--------------------------------------------------------------------------- if(TempApptSingle.Location.X>ContrApptSheet2.Width) { if(!Security.IsAuthorized(Permissions.AppointmentMove)) { mouseIsDown=false; TempApptSingle.Dispose(); return; } //cannot allow moving completed procedure because it could cause completed procs to change date. Security must block this. if(TempApptSingle.DataRoww["AptStatus"].ToString()=="2") {//complete mouseIsDown=false; TempApptSingle.Dispose(); MsgBox.Show(this,"Not allowed to move completed appointments."); return; } int prevSel=GetIndex(ContrApptSingle.SelectedAptNum); List<long> list=new List<long>(); list.Add(ContrApptSingle.SelectedAptNum); SendToPinBoard(list);//sets selectedAptNum=-1. do before refresh prev if(prevSel!=-1) { CreateAptShadowsOnMain(); ContrApptSheet2.DrawShadow(); } RefreshModuleDataPatient(PatCur.PatNum); OnPatientSelected(PatCur); //RefreshModulePatient(PatCurNum); TempApptSingle.Dispose(); return; } //moving to a new location----------------------------------------------------------------------------------------------- Appointment apt=Appointments.GetOneApt(ContrApptSingle.SelectedAptNum); aptOld=apt.Clone(); int tHr=ApptDrawing.ConvertToHour (TempApptSingle.Location.Y-ContrApptSheet2.Location.Y-panelSheet.Location.Y); int tMin=ApptDrawing.ConvertToMin (TempApptSingle.Location.Y-ContrApptSheet2.Location.Y-panelSheet.Location.Y); long opNum=ApptDrawing.VisOps[ApptDrawing.ConvertToOp(TempApptSingle.Location.X-ContrApptSheet2.Location.X)].OperatoryNum; bool timeWasMoved=tHr!=apt.AptDateTime.Hour || tMin!=apt.AptDateTime.Minute; bool isOpChanged=true; if(opNum==apt.Op) { isOpChanged=false; } if(timeWasMoved || isOpChanged) {//no question for notes if(apt.AptStatus == ApptStatus.PtNote | apt.AptStatus == ApptStatus.PtNoteCompleted) { if(!Security.IsAuthorized(Permissions.AppointmentMove)) { mouseIsDown = false; boolAptMoved = false; TempApptSingle.Dispose(); return; } } else { if(!Security.IsAuthorized(Permissions.AppointmentMove) || !MsgBox.Show(this,true,"Move Appointment?")) { mouseIsDown = false; boolAptMoved = false; TempApptSingle.Dispose(); return; } } } //convert loc to new date/time DateTime tDate=apt.AptDateTime.Date; if(ApptDrawing.IsWeeklyView) { tDate=WeekStartDate.AddDays(ApptDrawing.ConvertToDay(TempApptSingle.Location.X-ContrApptSheet2.Location.X)); } apt.AptDateTime=new DateTime(tDate.Year,tDate.Month,tDate.Day,tHr,tMin,0); List<Procedure> procsMultApts=null; Procedure[] procsForOne=null; if(AppointmentRuleC.List.Length>0) { List<long> aptNums=new List<long>(); for(int i=0;i<DS.Tables["Appointments"].Rows.Count;i++) { aptNums.Add(PIn.Long(DS.Tables["Appointments"].Rows[i]["AptNum"].ToString()));//ListDay[i].AptNum; } procsMultApts=Procedures.GetProcsMultApts(aptNums); } if(AppointmentRuleC.List.Length>0) { long[] aptNums=new long[DS.Tables["Appointments"].Rows.Count]; for(int i=0;i<DS.Tables["Appointments"].Rows.Count;i++) { aptNums[i]=PIn.Long(DS.Tables["Appointments"].Rows[i]["AptNum"].ToString());//ListDay[i].AptNum; } procsForOne=Procedures.GetProcsOneApt(apt.AptNum,procsMultApts); ArrayList doubleBookedCodes= AppointmentL.GetDoubleBookedCodes(apt,DS.Tables["Appointments"].Copy(),procsMultApts,procsForOne); if(doubleBookedCodes.Count>0) {//if some codes would be double booked if(AppointmentRules.IsBlocked(doubleBookedCodes)) { MessageBox.Show(Lan.g(this,"Not allowed to double book:")+" " +AppointmentRules.GetBlockedDescription(doubleBookedCodes)); mouseIsDown = false; boolAptMoved=false; TempApptSingle.Dispose(); return; } } } Operatory curOp=ApptDrawing.VisOps[ApptDrawing.ConvertToOp(TempApptSingle.Location.X-ContrApptSheet2.Location.X)]; apt.Op=curOp.OperatoryNum; //Set providers---------------------- long assignedDent=Schedules.GetAssignedProvNumForSpot(SchedListPeriod,curOp,false,apt.AptDateTime); long assignedHyg=Schedules.GetAssignedProvNumForSpot(SchedListPeriod,curOp,true,apt.AptDateTime); List<Procedure> procsForSingleApt=null; if(apt.AptStatus!=ApptStatus.PtNote && apt.AptStatus!=ApptStatus.PtNoteCompleted) { if(timeWasMoved) { if(PatCur.AskToArriveEarly>0) { apt.DateTimeAskedToArrive=apt.AptDateTime.AddMinutes(-PatCur.AskToArriveEarly); MessageBox.Show(Lan.g(this,"Ask patient to arrive")+" "+PatCur.AskToArriveEarly +" "+Lan.g(this,"minutes early at")+" "+apt.DateTimeAskedToArrive.ToShortTimeString()+"."); } else { if(apt.DateTimeAskedToArrive.Year>1880) { MessageBox.Show(Lan.g(this,"Time asked to arrive was ")+apt.DateTimeAskedToArrive.ToShortTimeString());//OK is only option } apt.DateTimeAskedToArrive=DateTime.MinValue; } } //if no dentist/hygenist is assigned to spot, then keep the original dentist/hygenist without prompt. All appts must have prov. if((assignedDent!=0 && assignedDent!=apt.ProvNum) || (assignedHyg!=0 && assignedHyg!=apt.ProvHyg)) { object[] parameters3={ apt,assignedDent,assignedHyg,procsForSingleApt,this };//Only used in following plugin hook. if((Plugins.HookMethod(this,"ContrAppt.ContrApptSheet2_MouseUp_apptProvChangeQuestion",parameters3))) { apt=(Appointment)parameters3[0]; assignedDent=(long)parameters3[1]; assignedDent=(long)parameters3[2]; goto PluginApptProvChangeQuestionEnd; } if(MsgBox.Show(this,MsgBoxButtons.YesNo,"Change provider?")) { if(assignedDent!=0) {//the dentist will only be changed if the spot has a dentist. apt.ProvNum=assignedDent; } if(assignedHyg!=0) {//the hygienist will only be changed if the spot has a hygienist. apt.ProvHyg=assignedHyg; } if(curOp.IsHygiene) { apt.IsHygiene=true; } else {//op not marked as hygiene op if(assignedDent==0) {//no dentist assigned if(assignedHyg!=0) {//hyg is assigned (we don't really have to test for this) apt.IsHygiene=true; } } else {//dentist is assigned if(assignedHyg==0) {//hyg is not assigned apt.IsHygiene=false; } //if both dentist and hyg are assigned, it's tricky //only explicitly set it if user has a dentist assigned to the op if(curOp.ProvDentist!=0) { apt.IsHygiene=false; } } } procsForSingleApt=Procedures.GetProcsForSingle(apt.AptNum,false); List<long> codeNums=new List<long>(); for(int p=0;p<procsForSingleApt.Count;p++) { codeNums.Add(procsForSingleApt[p].CodeNum); } string calcPattern=Appointments.CalculatePattern(apt.ProvNum,apt.ProvHyg,codeNums,true); if(apt.Pattern != calcPattern && !PrefC.GetBool(PrefName.AppointmentTimeIsLocked)) { if(apt.TimeLocked) { if(MsgBox.Show(this,MsgBoxButtons.YesNo,"Appointment length is locked. Change length for new provider anyway?")) { apt.Pattern=calcPattern; } } else {//appt time not locked if(MsgBox.Show(this,MsgBoxButtons.YesNo,"Change length for new provider?")) { apt.Pattern=calcPattern; } } } } PluginApptProvChangeQuestionEnd:{} } } RefreshPeriod(); if(DoesOverlap(apt)) { int startingOp=ApptDrawing.GetIndexOp(apt.Op); bool stillOverlaps=true; for(int i=startingOp;i<ApptDrawing.VisOps.Count;i++) { apt.Op=ApptDrawing.VisOps[i].OperatoryNum; if(!DoesOverlap(apt)) { stillOverlaps=false; break; } } if(stillOverlaps) { for(int i=startingOp;i>=0;i--) { apt.Op=ApptDrawing.VisOps[i].OperatoryNum; if(!DoesOverlap(apt)) { stillOverlaps=false; break; } } } if(stillOverlaps) { MessageBox.Show(Lan.g(this,"Appointment overlaps existing appointment.")); mouseIsDown=false; boolAptMoved=false; TempApptSingle.Dispose(); return; } }//end if DoesOverlap Operatory opCur=Operatories.GetOperatory(apt.Op); Operatory opOld=Operatories.GetOperatory(aptOld.Op); if(opOld==null || opCur.SetProspective!=opOld.SetProspective) { if(opCur.SetProspective && PatCur.PatStatus!=PatientStatus.Prospective) { //Don't need to prompt if patient is already prospective. if(MsgBox.Show(this,MsgBoxButtons.OKCancel,"Patient's status will be set to Prospective.")) { Patient patOld=PatCur.Copy(); PatCur.PatStatus=PatientStatus.Prospective; Patients.Update(PatCur,patOld); } } else if(!opCur.SetProspective && PatCur.PatStatus==PatientStatus.Prospective) { //Do we need to warn about changing FROM prospective? Assume so for now. if(MsgBox.Show(this,MsgBoxButtons.OKCancel,"Patient's status will change from Prospective to Patient.")) { Patient patOld=PatCur.Copy(); PatCur.PatStatus=PatientStatus.Patient; Patients.Update(PatCur,patOld); } } } object[] parameters2 = { apt.AptDateTime,aptOld.AptDateTime,apt.AptStatus }; if((Plugins.HookMethod(this,"ContrAppt.ContrApptSheet2_MouseUp_apptDoNotUnbreakApptSameDay",parameters2))) { apt.AptStatus = (ApptStatus)parameters2[2]; goto PluginApptDoNotUnbreakApptSameDay; } if(apt.AptStatus==ApptStatus.Broken && (timeWasMoved || isOpChanged)) { apt.AptStatus=ApptStatus.Scheduled; } PluginApptDoNotUnbreakApptSameDay: { } //original location of provider code if(curOp.ClinicNum==0){ apt.ClinicNum=PatCur.ClinicNum; } else{ apt.ClinicNum=curOp.ClinicNum; } if(apt.AptDateTime!=aptOld.AptDateTime && apt.Confirmed!=DefC.Short[(int)DefCat.ApptConfirmed][0].DefNum && apt.AptDateTime.Date!=DateTime.Today) { if(MsgBox.Show(this,MsgBoxButtons.YesNo,"Reset Confirmation Status?")) { apt.Confirmed=DefC.Short[(int)DefCat.ApptConfirmed][0].DefNum;//Causes the confirmation status to be reset. } } try { Appointments.Update(apt,aptOld); } catch(ApplicationException ex) { MessageBox.Show(ex.Message); } if(apt.AptStatus!=ApptStatus.Complete) { if(procsForSingleApt==null) { procsForSingleApt=Procedures.GetProcsForSingle(apt.AptNum,false); } Procedures.SetProvidersInAppointment(apt,procsForSingleApt); } SecurityLogs.MakeLogEntry(Permissions.AppointmentMove,apt.PatNum, apt.ProcDescript+" from "+aptOld.AptDateTime.ToString()+", to "+apt.AptDateTime.ToString(), apt.AptNum); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S13 - Appt Rescheduling MessageHL7 messageHL7=MessageConstructor.GenerateSIU(PatCur,Patients.GetPat(PatCur.Guarantor),EventTypeHL7.S13,apt); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=apt.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } RefreshModuleDataPatient(PatCur.PatNum); OnPatientSelected(PatCur); //RefreshModulePatient(PatCurNum); RefreshPeriod(); SetInvalid(); mouseIsDown = false; boolAptMoved=false; TempApptSingle.Dispose(); List<string> procCodes=new List<string>(); if(procsForSingleApt!=null) { for(int i=0;i<procsForSingleApt.Count;i++) { procCodes.Add(ProcedureCodes.GetProcCode((long)procsForSingleApt[i].CodeNum).ProcCode); } } //Recalls.SynchScheduledApptLazy(apt.PatNum,apt.AptDateTime,procCodes); Recalls.SynchScheduledApptFull(apt.PatNum); }
/*private void MakeAppointment(bool toPinboard) { if(toPinboard) { SendToPinBoard(FormAO.AptNumsSelected); if(ApptDrawing.IsWeeklyView) { break; } dateSearch.Text=FormAO.DateJumpToString; if(!groupSearch.Visible) {//if search not already visible ShowSearch(); } DoSearch(); } else { RefreshModuleDataPatient(PatCur.PatNum); OnPatientSelected(PatCur.PatNum,PatCur.GetNameLF(),PatCur.Email!="",PatCur.ChartNumber); //RefreshModulePatient(FormAO.SelectedPatNum); Appointment apt=Appointments.GetOneApt(ContrApptSingle.SelectedAptNum); if(apt!=null && DoesOverlap(apt)) { Appointment aptOld=apt.Clone(); MsgBox.Show(this,"Appointment is too long and would overlap another appointment. Automatically shortened to fit."); while(DoesOverlap(apt)) { apt.Pattern=apt.Pattern.Substring(0,apt.Pattern.Length-1); if(apt.Pattern.Length==1) { break; } } try { Appointments.Update(apt,aptOld); } catch(ApplicationException ex) { MessageBox.Show(ex.Message); } } RefreshPeriod(); SetInvalid(); } }*/ private void OnUnsched_Click() { if(ContrApptSingle.SelectedAptNum==-1) { MsgBox.Show(this,"Please select an appointment first."); return; } Appointment apt = Appointments.GetOneApt(ContrApptSingle.SelectedAptNum); if(!Security.IsAuthorized(Permissions.AppointmentMove)) { return; } if(apt.AptStatus == ApptStatus.PtNote | apt.AptStatus == ApptStatus.PtNoteCompleted) { return; } if(MessageBox.Show(Lan.g(this,"Send Appointment to Unscheduled List?") ,"",MessageBoxButtons.OKCancel)!=DialogResult.OK) { return; } int thisI=GetIndex(ContrApptSingle.SelectedAptNum); if(thisI==-1) {//selected appt is on a different day MsgBox.Show(this,"Please select an appointment first."); return; } Appointments.SetAptStatus(ContrApptSingle.SelectedAptNum,ApptStatus.UnschedList); Patient pat=Patients.GetPat(PIn.Long(ContrApptSingle3[thisI].DataRoww["PatNum"].ToString())); SecurityLogs.MakeLogEntry(Permissions.AppointmentMove,pat.PatNum, ContrApptSingle3[thisI].DataRoww["procs"].ToString()+", "+ContrApptSingle3[thisI].DataRoww["AptDateTime"].ToString()+", Sent to Unscheduled List", PIn.Long(ContrApptSingle3[thisI].DataRoww["AptNum"].ToString())); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S15 - Appt Cancellation event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(pat,Patients.GetPat(pat.Guarantor),EventTypeHL7.S15,apt); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=apt.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } ModuleSelected(pat.PatNum); SetInvalid(); Recalls.SynchScheduledApptFull(apt.PatNum); }
public void MakeRecallAppointment(){ List<Procedure> procList=Procedures.Refresh(PatCur.PatNum); //List<Recall> recallList=Recalls.GetList(PatCur.PatNum);//get the recall for this pt //if(recallList.Count==0){ // MsgBox.Show(this,"This patient does not have any recall due."); // return; //} //Recall recallCur=recallList[0]; List<InsSub> subList=InsSubs.RefreshForFam(FamCur); List<InsPlan> planList=InsPlans.RefreshForSubList(subList); Appointment apt=null; try{ apt=AppointmentL.CreateRecallApt(PatCur,procList,planList,-1,subList); } catch(Exception ex){ MessageBox.Show(ex.Message); return; } AptNumsSelected.Add(apt.AptNum); if(this.InitialClick) { Appointment oldApt=apt.Clone(); DateTime d; if(ApptDrawing.IsWeeklyView) { d=ContrAppt.WeekStartDate.AddDays(ContrAppt.SheetClickedonDay); } else { d=AppointmentL.DateSelected; } int minutes=(int)(ContrAppt.SheetClickedonMin/ApptDrawing.MinPerIncr)*ApptDrawing.MinPerIncr; apt.AptDateTime=new DateTime(d.Year,d.Month,d.Day,ContrAppt.SheetClickedonHour,minutes,0); if(PatCur.AskToArriveEarly>0){ apt.DateTimeAskedToArrive=apt.AptDateTime.AddMinutes(-PatCur.AskToArriveEarly); MessageBox.Show(Lan.g(this,"Ask patient to arrive")+" "+PatCur.AskToArriveEarly +" "+Lan.g(this,"minutes early at")+" "+apt.DateTimeAskedToArrive.ToShortTimeString()+"."); } apt.AptStatus=ApptStatus.Scheduled; apt.Op=ContrAppt.SheetClickedonOp; Operatory curOp=Operatories.GetOperatory(apt.Op); if(curOp.ProvDentist!=0) { apt.ProvNum=curOp.ProvDentist; } apt.ProvHyg=curOp.ProvHygienist; apt.IsHygiene=curOp.IsHygiene; if(curOp.ClinicNum==0){ apt.ClinicNum=PatCur.ClinicNum; } else{ apt.ClinicNum=curOp.ClinicNum; } Appointments.Update(apt,oldApt); oResult=OtherResult.CreateNew; SecurityLogs.MakeLogEntry(Permissions.AppointmentCreate,apt.PatNum,apt.AptDateTime.ToString(),apt.AptNum); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S12 - New Appt Booking event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(PatCur,FamCur.GetPatient(PatCur.Guarantor),EventTypeHL7.S12,apt); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=apt.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } DialogResult=DialogResult.OK; return; } //not initialClick oResult=OtherResult.PinboardAndSearch; Recall recall=Recalls.GetRecallProphyOrPerio(PatCur.PatNum);//shouldn't return null. if(recall.DateDue<DateTime.Today){ DateJumpToString=DateTime.Today.ToShortDateString();//they are overdue } else{ DateJumpToString=recall.DateDue.ToShortDateString(); } //no securitylog entry needed here. That will happen when it's dragged off pinboard. DialogResult=DialogResult.OK; }
//private void Tool_EHR_Click_old(bool onLoadShowOrders) { // #if EHRTEST // //so we can step through for debugging. // /* // EhrQuarterlyKey keyThisQ=EhrQuarterlyKeys.GetKeyThisQuarter(); // if(keyThisQ==null) { // MessageBox.Show("No quarterly key entered for this quarter."); // return; // } // if(!((FormEHR)FormOpenDental.FormEHR).QuarterlyKeyIsValid((DateTime.Today.Year-2000).ToString(),EhrQuarterlyKeys.MonthToQuarter(DateTime.Today.Month).ToString(), // PrefC.GetString(PrefName.PracticeTitle),keyThisQ.KeyValue)) { // MessageBox.Show("Invalid quarterly key."); // return; // } // */ // ((FormEHR)FormOpenDental.FormEHR).PatNum=PatCur.PatNum; // ((FormEHR)FormOpenDental.FormEHR).OnShowLaunchOrders=onLoadShowOrders; // ((FormEHR)FormOpenDental.FormEHR).ShowDialog(); // if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.None) { // //return; // } // if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.RxEdit) { // FormRxEdit FormRXE=new FormRxEdit(PatCur,RxPats.GetRx(((FormEHR)FormOpenDental.FormEHR).LaunchRxNum)); // FormRXE.ShowDialog(); // ModuleSelected(PatCur.PatNum); // Tool_EHR_Click(false);//recursive. The only way out of the loop is EhrFormResult.None. // } // else if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.RxSelect) { // FormRxSelect FormRS=new FormRxSelect(PatCur); // FormRS.ShowDialog(); // ModuleSelected(PatCur.PatNum); // Tool_EHR_Click(false); // } // else if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.Medical) { // FormMedical formM=new FormMedical(PatientNoteCur,PatCur); // formM.ShowDialog(); // ModuleSelected(PatCur.PatNum); // Tool_EHR_Click(false); // } // else if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.PatientEdit) { // FormPatientEdit formP=new FormPatientEdit(PatCur,FamCur); // formP.ShowDialog(); // ModuleSelected(PatCur.PatNum); // Tool_EHR_Click(false); // } // else if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.Online) { // FormEhrOnlineAccess formO=new FormEhrOnlineAccess(); // formO.PatCur=PatCur; // formO.ShowDialog(); // ModuleSelected(PatCur.PatNum); // Tool_EHR_Click(false); // } // else if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.MedReconcile) { // FormMedicationReconcile FormMR=new FormMedicationReconcile(); // FormMR.PatCur=PatCur; // FormMR.ShowDialog(); // ModuleSelected(PatCur.PatNum); // Tool_EHR_Click(false); // } // else if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.Referrals) { // FormReferralsPatient formRP=new FormReferralsPatient(); // formRP.PatNum=PatCur.PatNum; // formRP.ShowDialog(); // ModuleSelected(PatCur.PatNum); // Tool_EHR_Click(false); // } // else if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.MedicationPatEdit) { // FormMedPat formMP=new FormMedPat(); // formMP.MedicationPatCur=MedicationPats.GetOne(((FormEHR)FormOpenDental.FormEHR).LaunchMedicationPatNum); // formMP.ShowDialog(); // ModuleSelected(PatCur.PatNum); // Tool_EHR_Click(true); // } // else if(((FormEHR)FormOpenDental.FormEHR).ResultOnClosing==EhrFormResult.MedicationPatNew) { // //This cannot happen unless a provider is logged in with a valid ehr key // FormMedications FormM=new FormMedications(); // FormM.IsSelectionMode=true; // FormM.ShowDialog(); // if(FormM.DialogResult==DialogResult.OK) { // Medication med=Medications.GetMedicationFromDb(FormM.SelectedMedicationNum); // if(med.RxCui==0 //if the med has no Cui, it won't trigger an alert // || RxAlertL.DisplayAlerts(PatCur.PatNum,med.RxCui,0))//user sees alert and wants to continue // { // MedicationPat medicationPat=new MedicationPat(); // medicationPat.PatNum=PatCur.PatNum; // medicationPat.MedicationNum=FormM.SelectedMedicationNum; // medicationPat.ProvNum=Security.CurUser.ProvNum; // medicationPat.DateStart=DateTime.Today; // FormMedPat FormMP=new FormMedPat(); // FormMP.MedicationPatCur=medicationPat; // FormMP.IsNew=true; // FormMP.IsNewMedOrder=true; // FormMP.ShowDialog(); // if(FormMP.DialogResult==DialogResult.OK) { // ModuleSelected(PatCur.PatNum); // } // } // } // Tool_EHR_Click(true); // } // //#else // //TODO: // //Type type=FormOpenDental.AssemblyEHR.GetType("OpenDental.ObjSomeEhrSuperClass");//namespace.class // object[] args; // EhrQuarterlyKey keyThisQ=EhrQuarterlyKeys.GetKeyThisQuarter(); // if(keyThisQ==null) { // MessageBox.Show("No quarterly key entered for this quarter."); // return; // } // args=new object[] { (DateTime.Today.Year-2000).ToString(),EhrQuarterlyKeys.MonthToQuarter(DateTime.Today.Month).ToString(), // PrefC.GetString(PrefName.PracticeTitle),keyThisQ.KeyValue }; // FormEHR Ehr = new FormEHR(); // Ehr.PatNum=PatCur.PatNum; // Ehr.PatNotCur=PatientNoteCur; // Ehr.PatFamCur=FamCur; // Ehr.ShowDialog(); // if(!(bool)type.InvokeMember("QuarterlyKeyIsValid",System.Reflection.BindingFlags.InvokeMethod,null,FormOpenDental.ObjSomeEhrSuperClass,args)) { // MessageBox.Show("Invalid quarterly key."); // return; // } // //args=new object[] {PatCur.PatNum}; // //type.InvokeMember("PatNum",System.Reflection.BindingFlags.SetField,null,FormOpenDental.ObjSomeEhrSuperClass,args); // //type.InvokeMember("ShowDialog",System.Reflection.BindingFlags.InvokeMethod,null,FormOpenDental.ObjSomeEhrSuperClass,null); // //if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.None) { // // return; // //} // //if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.RxEdit) { // // long launchRxNum=(long)type.InvokeMember("LaunchRxNum",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null); // // FormRxEdit FormRXE=new FormRxEdit(PatCur,RxPats.GetRx(launchRxNum)); // // FormRXE.ShowDialog(); // // ModuleSelected(PatCur.PatNum); // // Tool_EHR_Click(false); // //} // //else if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.RxSelect) { // // FormRxSelect FormRS=new FormRxSelect(PatCur); // // FormRS.ShowDialog(); // // ModuleSelected(PatCur.PatNum); // // Tool_EHR_Click(false); // //} // //else if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.Medical) { // // FormMedical formM=new FormMedical(PatientNoteCur,PatCur); // // formM.ShowDialog(); // // ModuleSelected(PatCur.PatNum); // // Tool_EHR_Click(false); // //} // //else if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.PatientEdit) { // // FormPatientEdit formP=new FormPatientEdit(PatCur,FamCur); // // formP.ShowDialog(); // // ModuleSelected(PatCur.PatNum); // // Tool_EHR_Click(false); // //} // //else if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.Online) { // // FormPatientPortal formPP=new FormPatientPortal(); // // formPP.PatCur=PatCur; // // formPP.ShowDialog(); // // ModuleSelected(PatCur.PatNum); // // Tool_EHR_Click(false); // //} // //else if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.MedReconcile) { // // FormMedicationReconcile FormMR=new FormMedicationReconcile(); // // FormMR.PatCur=PatCur; // // FormMR.ShowDialog(); // // ModuleSelected(PatCur.PatNum); // // Tool_EHR_Click(false); // //} // //else if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.Referrals) { // // FormReferralsPatient formRP=new FormReferralsPatient(); // // formRP.PatNum=PatCur.PatNum; // // formRP.ShowDialog(); // // ModuleSelected(PatCur.PatNum); // // Tool_EHR_Click(false); // //} // //else if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.MedicationPatEdit) { // // long medicationPatNum=(long)type.InvokeMember("LaunchMedicationPatNum",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null); // // FormMedPat formMP=new FormMedPat(); // // formMP.MedicationPatCur=MedicationPats.GetOne(medicationPatNum); // // formMP.ShowDialog(); // // ModuleSelected(PatCur.PatNum); // // Tool_EHR_Click(true); // //} // /*No longer allowed to create medication orders from the MedicalOrder (CPOE) window. // else if(((EhrFormResult)type.InvokeMember("ResultOnClosing",System.Reflection.BindingFlags.GetField,null,FormOpenDental.ObjSomeEhrSuperClass,null))==EhrFormResult.MedicationPatNew) { // //This cannot happen unless a provider is logged in with a valid ehr key // FormMedications FormM=new FormMedications(); // FormM.IsSelectionMode=true; // FormM.ShowDialog(); // if(FormM.DialogResult==DialogResult.OK) { // Medication med=Medications.GetMedicationFromDb(FormM.SelectedMedicationNum); // if(med.RxCui==0 //if the med has no Cui, it won't trigger an alert // || RxAlertL.DisplayAlerts(PatCur.PatNum,med.RxCui,0))//user sees alert and wants to continue // { // MedicationPat medicationPat=new MedicationPat(); // medicationPat.PatNum=PatCur.PatNum; // medicationPat.MedicationNum=FormM.SelectedMedicationNum; // medicationPat.ProvNum=Security.CurUser.ProvNum; // FormMedPat FormMP=new FormMedPat(); // FormMP.MedicationPatCur=medicationPat; // FormMP.IsNew=true; // FormMP.ShowDialog(); // if(FormMP.DialogResult==DialogResult.OK) { // ModuleSelected(PatCur.PatNum); // } // } // } // Tool_EHR_Click(true); // }*/ // #endif //} private void Tool_HL7_Click() { DataRow row; if(gridProg.SelectedIndices.Length==0) { //autoselect procedures for(int i=0;i<gridProg.Rows.Count;i++) {//loop through every line showing in progress notes row=(DataRow)gridProg.Rows[i].Tag; if(row["ProcNum"].ToString()=="0") { continue;//ignore non-procedures } //May want to ignore procs with zero fee? //if((decimal)row["chargesDouble"]==0) { // continue;//ignore zero fee procedures, but user can explicitly select them //} if(PIn.Date(row["ProcDate"].ToString())==DateTime.Today && PIn.Int(row["ProcStatus"].ToString())==(int)ProcStat.C) { gridProg.SetSelected(i,true); } } if(gridProg.SelectedIndices.Length==0) {//if still none selected MsgBox.Show(this,"Please select procedures first."); return; } } List<Procedure> procs=new List<Procedure>(); bool allAreProcedures=true; for(int i=0;i<gridProg.SelectedIndices.Length;i++) { row=(DataRow)gridProg.Rows[gridProg.SelectedIndices[i]].Tag; if(row["ProcNum"].ToString()=="0") { allAreProcedures=false; } else { procs.Add(Procedures.GetOneProc(PIn.Long(row["ProcNum"].ToString()),false)); } } if(!allAreProcedures) { MsgBox.Show(this,"You can only select procedures."); return; } long aptNum=0; for(int i=0;i<procs.Count;i++) { if(procs[i].AptNum==0) { continue; } aptNum=procs[i].AptNum; break; } //todo: compare with: Bridges.ECW.AptNum, no need to generate PDF segment, pdfs only with eCW and this button not available with eCW integration MessageHL7 messageHL7=MessageConstructor.GenerateDFT(procs,EventTypeHL7.P03,PatCur,FamCur.ListPats[0],aptNum,"treatment","PDF Segment"); if(messageHL7==null) { MsgBox.Show(this,"There is no DFT message type defined for the enabled HL7 definition."); return; } HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=aptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MsgBox.Show(this,messageHL7.ToString()); #endif }
private void ToolBarMainCreate_Click(){//Save TP if(gridPlans.SelectedIndices[0]!=0){ MsgBox.Show(this,"The default TP must be selected before saving a TP. You can highlight some procedures in the default TP to save a TP with only those procedures in it."); return; } //Check for duplicate procedures on the appointment before sending the DFT to eCW. if(Programs.UsingEcwTightOrFullMode() && Bridges.ECW.AptNum!=0) { List<Procedure> procs=Procedures.GetProcsForSingle(Bridges.ECW.AptNum,false); string duplicateProcs=ProcedureL.ProcsContainDuplicates(procs); if(duplicateProcs!="") { MessageBox.Show(duplicateProcs); return; } } if(gridMain.SelectedIndices.Length==0){ gridMain.SetSelected(true); } TreatPlan tp=new TreatPlan(); tp.Heading=Lan.g(this,"Proposed Treatment Plan"); tp.DateTP=DateTimeOD.Today; tp.PatNum=PatCur.PatNum; tp.Note=PrefC.GetString(PrefName.TreatmentPlanNote); tp.ResponsParty=PatCur.ResponsParty; TreatPlans.Insert(tp); ProcTP procTP; Procedure proc; int itemNo=0; List<Procedure> procList=new List<Procedure>(); for(int i=0;i<gridMain.SelectedIndices.Length;i++){ if(gridMain.Rows[gridMain.SelectedIndices[i]].Tag==null){ //user must have highlighted a subtotal row. continue; } proc=(Procedure)gridMain.Rows[gridMain.SelectedIndices[i]].Tag; procList.Add(proc); procTP=new ProcTP(); procTP.TreatPlanNum=tp.TreatPlanNum; procTP.PatNum=PatCur.PatNum; procTP.ProcNumOrig=proc.ProcNum; procTP.ItemOrder=itemNo; procTP.Priority=proc.Priority; procTP.ToothNumTP=Tooth.ToInternat(proc.ToothNum); if(ProcedureCodes.GetProcCode(proc.CodeNum).TreatArea==TreatmentArea.Surf){ procTP.Surf=Tooth.SurfTidyFromDbToDisplay(proc.Surf,proc.ToothNum); } else{ procTP.Surf=proc.Surf;//for UR, L, etc. } procTP.ProcCode=ProcedureCodes.GetStringProcCode(proc.CodeNum); procTP.Descript=RowsMain[gridMain.SelectedIndices[i]].Description; if(checkShowFees.Checked){ procTP.FeeAmt=PIn.Double(RowsMain[gridMain.SelectedIndices[i]].Fee.ToString()); } if(checkShowIns.Checked){ procTP.PriInsAmt=PIn.Double(RowsMain[gridMain.SelectedIndices[i]].PriIns.ToString()); procTP.SecInsAmt=PIn.Double(RowsMain[gridMain.SelectedIndices[i]].SecIns.ToString()); } if(checkShowDiscount.Checked){ procTP.Discount=PIn.Double(RowsMain[gridMain.SelectedIndices[i]].Discount.ToString()); } if(checkShowIns.Checked){ procTP.PatAmt=PIn.Double(RowsMain[gridMain.SelectedIndices[i]].Pat.ToString()); } procTP.Prognosis=RowsMain[gridMain.SelectedIndices[i]].Prognosis; procTP.Dx=RowsMain[gridMain.SelectedIndices[i]].Dx; ProcTPs.InsertOrUpdate(procTP,true); itemNo++; #region Canadian Lab Fees /* proc=(Procedure)gridMain.Rows[gridMain.SelectedIndices[i]].Tag; procTP=new ProcTP(); procTP.TreatPlanNum=tp.TreatPlanNum; procTP.PatNum=PatCur.PatNum; procTP.ProcNumOrig=proc.ProcNum; procTP.ItemOrder=itemNo; procTP.Priority=proc.Priority; procTP.ToothNumTP=""; procTP.Surf=""; procTP.Code=proc.LabProcCode; procTP.Descript=gridMain.Rows[gridMain.SelectedIndices[i]] .Cells[gridMain.Columns.GetIndex(Lan.g("TableTP","Description"))].Text; if(checkShowFees.Checked) { procTP.FeeAmt=PIn.PDouble(gridMain.Rows[gridMain.SelectedIndices[i]] .Cells[gridMain.Columns.GetIndex(Lan.g("TableTP","Fee"))].Text); } if(checkShowIns.Checked) { procTP.PriInsAmt=PIn.PDouble(gridMain.Rows[gridMain.SelectedIndices[i]] .Cells[gridMain.Columns.GetIndex(Lan.g("TableTP","Pri Ins"))].Text); procTP.SecInsAmt=PIn.PDouble(gridMain.Rows[gridMain.SelectedIndices[i]] .Cells[gridMain.Columns.GetIndex(Lan.g("TableTP","Sec Ins"))].Text); procTP.PatAmt=PIn.PDouble(gridMain.Rows[gridMain.SelectedIndices[i]] .Cells[gridMain.Columns.GetIndex(Lan.g("TableTP","Pat"))].Text); } ProcTPs.InsertOrUpdate(procTP,true); itemNo++;*/ #endregion Canadian Lab Fees } //Send TP DFT HL7 message to ECW with embedded PDF when using tight or full integration only. if(Programs.UsingEcwTightOrFullMode() && Bridges.ECW.AptNum!=0){ PrepImageForPrinting(); MigraDoc.Rendering.PdfDocumentRenderer pdfRenderer=new MigraDoc.Rendering.PdfDocumentRenderer(true,PdfFontEmbedding.Always); pdfRenderer.Document=CreateDocument(); pdfRenderer.RenderDocument(); MemoryStream ms=new MemoryStream(); pdfRenderer.PdfDocument.Save(ms); byte[] pdfBytes=ms.GetBuffer(); //#region Remove when testing is complete. //string tempFilePath=Path.GetTempFileName(); //File.WriteAllBytes(tempFilePath,pdfBytes); //#endregion string pdfDataStr=Convert.ToBase64String(pdfBytes); if(HL7Defs.IsExistingHL7Enabled()) { //DFT messages that are PDF's only and do not include FT1 segments, so proc list can be empty //MessageConstructor.GenerateDFT(procList,EventTypeHL7.P03,PatCur,Patients.GetPat(PatCur.Guarantor),Bridges.ECW.AptNum,"treatment",pdfDataStr); MessageHL7 messageHL7=MessageConstructor.GenerateDFT(new List<Procedure>(),EventTypeHL7.P03,PatCur,Patients.GetPat(PatCur.Guarantor),Bridges.ECW.AptNum,"treatment",pdfDataStr); if(messageHL7==null) { MsgBox.Show(this,"There is no DFT message type defined for the enabled HL7 definition."); return; } HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=0;//Prevents the appt complete button from changing to the "Revise" button prematurely. hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); } else { Bridges.ECW.SendHL7(Bridges.ECW.AptNum,PatCur.PriProv,PatCur,pdfDataStr,"treatment",true); } } ModuleSelected(PatCur.PatNum); for(int i=0;i<PlanList.Length;i++){ if(PlanList[i].TreatPlanNum==tp.TreatPlanNum){ gridPlans.SetSelected(i+1,true); FillMain(); } } }
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.Country=textCountry.Text; guar.Zip=textZip.Text; guar.AddrNote=textAddrNotes.Text; guar.ClinicNum=FormOpenDental.ClinicNum; Patients.Insert(guar,false); CustReference custRef=new CustReference(); custRef.PatNum=guar.PatNum; CustReferences.Insert(custRef); 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=DateTimeOD.Today; refAttach.ReferralNum=selectedReferral.ReferralNum; refAttach.PatNum=guar.PatNum; RefAttaches.Insert(refAttach); SecurityLogs.MakeLogEntry(Permissions.RefAttachAdd,refAttach.PatNum,"Referred From "+Referrals.GetNameFL(refAttach.ReferralNum)); } //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.Country=textCountry.Text; pat2.Zip=textZip.Text; pat2.AddrNote=textAddrNotes.Text; pat2.ClinicNum=FormOpenDental.ClinicNum;; pat2.Guarantor=guar.Guarantor; Patients.Insert(pat2,false); custRef=new CustReference(); custRef.PatNum=pat2.PatNum; CustReferences.Insert(custRef); if(textReferral.Text!=""){ //selectedReferral will already have been set in the guarantor loop refAttach=new RefAttach(); refAttach.IsFrom=true; refAttach.RefDate=DateTimeOD.Today; refAttach.ReferralNum=selectedReferral.ReferralNum; refAttach.PatNum=pat2.PatNum; RefAttaches.Insert(refAttach); SecurityLogs.MakeLogEntry(Permissions.RefAttachAdd,refAttach.PatNum,"Referred From "+Referrals.GetNameFL(refAttach.ReferralNum)); } } //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.Country=textCountry.Text; pat3.Zip=textZip.Text; pat3.AddrNote=textAddrNotes.Text; pat3.ClinicNum=FormOpenDental.ClinicNum; pat3.Guarantor=guar.Guarantor; Patients.Insert(pat3,false); custRef=new CustReference(); custRef.PatNum=pat3.PatNum; CustReferences.Insert(custRef); if(textReferral.Text!=""){ //selectedReferral will already have been set in the guarantor loop refAttach=new RefAttach(); refAttach.IsFrom=true; refAttach.RefDate=DateTimeOD.Today; refAttach.ReferralNum=selectedReferral.ReferralNum; refAttach.PatNum=pat3.PatNum; RefAttaches.Insert(refAttach); SecurityLogs.MakeLogEntry(Permissions.RefAttachAdd,refAttach.PatNum,"Referred From "+Referrals.GetNameFL(refAttach.ReferralNum)); } } //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.Country=textCountry.Text; pat4.Zip=textZip.Text; pat4.AddrNote=textAddrNotes.Text; pat4.ClinicNum=FormOpenDental.ClinicNum; pat4.Guarantor=guar.Guarantor; Patients.Insert(pat4,false); custRef=new CustReference(); custRef.PatNum=pat4.PatNum; CustReferences.Insert(custRef); if(textReferral.Text!=""){ //selectedReferral will already have been set in the guarantor loop refAttach=new RefAttach(); refAttach.IsFrom=true; refAttach.RefDate=DateTimeOD.Today; refAttach.ReferralNum=selectedReferral.ReferralNum; refAttach.PatNum=pat4.PatNum; RefAttaches.Insert(refAttach); SecurityLogs.MakeLogEntry(Permissions.RefAttachAdd,refAttach.PatNum,"Referred From "+Referrals.GetNameFL(refAttach.ReferralNum)); } } //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.Country=textCountry.Text; pat5.Zip=textZip.Text; pat5.AddrNote=textAddrNotes.Text; pat5.ClinicNum=FormOpenDental.ClinicNum; pat5.Guarantor=guar.Guarantor; Patients.Insert(pat5,false); custRef=new CustReference(); custRef.PatNum=pat5.PatNum; CustReferences.Insert(custRef); if(textReferral.Text!=""){ //selectedReferral will already have been set in the guarantor loop refAttach=new RefAttach(); refAttach.IsFrom=true; refAttach.RefDate=DateTimeOD.Today; refAttach.ReferralNum=selectedReferral.ReferralNum; refAttach.PatNum=pat5.PatNum; RefAttaches.Insert(refAttach); SecurityLogs.MakeLogEntry(Permissions.RefAttachAdd,refAttach.PatNum,"Referred From "+Referrals.GetNameFL(refAttach.ReferralNum)); } } //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); } //Zero deductible diagnostic if(CovCats.GetForEbenCat(EbenefitCategory.Diagnostic)!=null) { ben=new Benefit(); ben.CodeNum=0; ben.BenefitType=InsBenefitType.Deductible; ben.CovCatNum=CovCats.GetForEbenCat(EbenefitCategory.Diagnostic).CovCatNum; ben.PlanNum=selectedPlan1.PlanNum; ben.TimePeriod=BenefitTimePeriod.CalendarYear; ben.MonetaryAmt=0; ben.Percent=-1; ben.CoverageLevel=BenefitCoverageLevel.Individual; Benefits.Insert(ben); } //Zero deductible preventive if(CovCats.GetForEbenCat(EbenefitCategory.RoutinePreventive)!=null) { ben=new Benefit(); ben.CodeNum=0; ben.BenefitType=InsBenefitType.Deductible; ben.CovCatNum=CovCats.GetForEbenCat(EbenefitCategory.RoutinePreventive).CovCatNum; ben.PlanNum=selectedPlan1.PlanNum; ben.TimePeriod=BenefitTimePeriod.CalendarYear; ben.MonetaryAmt=0; ben.Percent=-1; ben.CoverageLevel=BenefitCoverageLevel.Individual; Benefits.Insert(ben); } } sub1=new InsSub(); sub1.PlanNum=selectedPlan1.PlanNum; sub1.AssignBen=PrefC.GetBool(PrefName.InsDefaultAssignBen); 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); } //Zero deductible diagnostic if(CovCats.GetForEbenCat(EbenefitCategory.Diagnostic)!=null) { ben=new Benefit(); ben.CodeNum=0; ben.BenefitType=InsBenefitType.Deductible; ben.CovCatNum=CovCats.GetForEbenCat(EbenefitCategory.Diagnostic).CovCatNum; ben.PlanNum=selectedPlan2.PlanNum; ben.TimePeriod=BenefitTimePeriod.CalendarYear; ben.MonetaryAmt=0; ben.Percent=-1; ben.CoverageLevel=BenefitCoverageLevel.Individual; Benefits.Insert(ben); } //Zero deductible preventive if(CovCats.GetForEbenCat(EbenefitCategory.RoutinePreventive)!=null) { ben=new Benefit(); ben.CodeNum=0; ben.BenefitType=InsBenefitType.Deductible; ben.CovCatNum=CovCats.GetForEbenCat(EbenefitCategory.RoutinePreventive).CovCatNum; ben.PlanNum=selectedPlan2.PlanNum; ben.TimePeriod=BenefitTimePeriod.CalendarYear; ben.MonetaryAmt=0; ben.Percent=-1; ben.CoverageLevel=BenefitCoverageLevel.Individual; Benefits.Insert(ben); } } sub2=new InsSub(); sub2.PlanNum=selectedPlan2.PlanNum; sub2.AssignBen=PrefC.GetBool(PrefName.InsDefaultAssignBen); 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; //If there is an existing HL7 def enabled, send an ADT message for each patient inserted if there is an outbound ADT message defined if(HL7Defs.IsExistingHL7Enabled()) { if(guar!=null) { //new patients get the A04 ADT, updating existing patients we send an A08 MessageHL7 messageHL7=MessageConstructor.GenerateADT(guar,guar,EventTypeHL7.A04); //Will be null if there is no outbound ADT message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=0; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=guar.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } if(pat2!=null) { //new patients get the A04 ADT, updating existing patients we send an A08 MessageHL7 messageHL7=MessageConstructor.GenerateADT(pat2,guar,EventTypeHL7.A04); //Will be null if there is no outbound ADT message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=0; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat2.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } if(pat3!=null) { //new patients get the A04 ADT, updating existing patients we send an A08 MessageHL7 messageHL7=MessageConstructor.GenerateADT(pat3,guar,EventTypeHL7.A04); //Will be null if there is no outbound ADT message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=0; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat3.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } if(pat4!=null) { //new patients get the A04 ADT, updating existing patients we send an A08 MessageHL7 messageHL7=MessageConstructor.GenerateADT(pat4,guar,EventTypeHL7.A04); //Will be null if there is no outbound ADT message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=0; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat4.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } if(pat5!=null) { //new patients get the A04 ADT, updating existing patients we send an A08 MessageHL7 messageHL7=MessageConstructor.GenerateADT(pat5,guar,EventTypeHL7.A04); //Will be null if there is no outbound ADT message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=0; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat5.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } } MessageBox.Show("Done"); DialogResult=DialogResult.OK; }
///<summary>Runs in a separate thread</summary> private void OnDataReceived(IAsyncResult asyncResult) { try { if(!_ecwTCPModeIsReceiving) {//this will only be false if a socket.Close() call is made, which will trigger this call back function to finish, so just return if false return; } StateObject state=(StateObject)asyncResult.AsyncState; if(state==null) { throw new Exception("Error in OnDataReceived: The IAsyncResult parameter could not be cast to a StateObject."); } Socket socketIncomingHandler=state.workSocket; int byteCountReceived=0; try { if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","EndReceive is starting.",EventLogEntryType.Information); } byteCountReceived=socketIncomingHandler.EndReceive(asyncResult);//blocks until data is recieved. } catch(Exception ex) { //Socket has been disposed or is null or something went wrong. _ecwTCPModeIsReceiving=false; socketIncomingHandler.Close(); throw new Exception("Error in OnDataReceived:\r\n"+ex.Message+"\r\n"+ex.StackTrace); } char[] chars=new char[byteCountReceived]; Decoder decoder=Encoding.UTF8.GetDecoder(); decoder.GetChars(state.buffer,0,byteCountReceived,chars,0);//doesn't necessarily get all bytes from the buffer because buffer could be half full. state.strbFullMsg.Append(chars);//sb might already have partial data Array.Clear(state.buffer,0,StateObject.BufferSize);//Clear the buffer, ready to receive more //I think we are guaranteed to have received at least one char. bool isFullMsg=false; bool isMalformed=false; if(state.strbFullMsg.Length==1 && state.strbFullMsg[0]==MLLP_ENDMSG_CHAR) {//the only char in the message is the end char state.strbFullMsg.Clear();//this must be the very end of a previously processed message. Discard. isFullMsg=false; } //else if(strbFullMsg[0]!=MLLP_START_CHAR) { else if(state.strbFullMsg.Length>0 && state.strbFullMsg[0]!=MLLP_START_CHAR) { //Malformed message. isFullMsg=true;//we're going to do this so that the error gets saved in the database further down. isMalformed=true; } else if(state.strbFullMsg.Length>=3//so that the next two lines won't crash && state.strbFullMsg[state.strbFullMsg.Length-1]==MLLP_ENDMSG_CHAR//last char is the endmsg char. && state.strbFullMsg[state.strbFullMsg.Length-2]==MLLP_END_CHAR)//the second-to-the-last char is the end char. { //we have a complete message state.strbFullMsg.Remove(0,1);//strip off the start char state.strbFullMsg.Remove(state.strbFullMsg.Length-2,2);//strip off the end chars isFullMsg=true; } else if(state.strbFullMsg.Length>=2//so that the next line won't crash && state.strbFullMsg[state.strbFullMsg.Length-1]==MLLP_END_CHAR)//the last char is the end char. { //we will treat this as a complete message, because the endmsg char is optional. //if the endmsg char gets sent in a subsequent block, the code above will discard it. state.strbFullMsg.Remove(0,1);//strip off the start char state.strbFullMsg.Remove(state.strbFullMsg.Length-1,1);//strip off the end char isFullMsg=true; } else { isFullMsg=false;//this is an incomplete message. Continue to receive more blocks. } //end of big if statement------------------------------------------------- if(!isFullMsg) { try { if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Not a full message, BeginReceive called again.",EventLogEntryType.Information); } //the buffer was cleared after appending the chars to the string builder _ecwTCPModeIsReceiving=true; IAsyncResult inResultIncomplMsg=socketIncomingHandler.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,new AsyncCallback(OnDataReceived),state); if(!inResultIncomplMsg.AsyncWaitHandle.WaitOne(new TimeSpan(0,0,30))) {//WaitOne will return true if data was received, false if the timeout is reached with no data received //if we have received part of a message and 30 seconds goes by with no additional data recieved //close the socket and set the receiveDone manual reset event. A new socket connection will be accepted. if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Setting manual reset event so the main receive thread will accept a new incoming connection.",EventLogEntryType.Information); } inResultIncomplMsg.AsyncWaitHandle.Close(); _ecwTCPModeIsReceiving=false; socketIncomingHandler.Close(); receiveDone.Set(); } else { inResultIncomplMsg.AsyncWaitHandle.Close(); } return;//get another block or in the event the 30 second timeout is reached, a new socket will be created } catch(Exception ex) { _ecwTCPModeIsReceiving=false; socketIncomingHandler.Close(); throw new Exception("An error occurred with BeginReceive on an incoming TCP/IP HL7 message.\r\nException: "+ex.Message+"\r\n"+ex.StackTrace); } } //Prepare to save message to database if malformed and not processed HL7Msg hl7Msg=new HL7Msg(); hl7Msg.MsgText=state.strbFullMsg.ToString(); state.strbFullMsg.Clear();//just in case, ready for the next message bool isProcessed=true; string messageControlId=""; string ackEvent=""; if(isMalformed) { hl7Msg.HL7Status=HL7MessageStatus.InFailed; hl7Msg.Note="This message is malformed so it was not processed."; HL7Msgs.Insert(hl7Msg); isProcessed=false; } else { if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Create the HL7 Message Object from the message text.",EventLogEntryType.Information); } MessageHL7 messageHl7Object=new MessageHL7(hl7Msg.MsgText);//this creates an entire heirarchy of objects. try { if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Process the HL7 message.",EventLogEntryType.Information); } ackEvent=messageHl7Object.AckEvent; MessageParser.Process(messageHl7Object,IsVerboseLogging);//also saves the message to the db and retrieves the control ID from the MSH segment messageControlId=messageHl7Object.ControlId; } catch(Exception ex) { EventLog.WriteEntry("OpenDentHL7","Error in OnDataRecieved when processing message:\r\n"+ex.Message+"\r\n"+ex.StackTrace,EventLogEntryType.Information); isProcessed=false; } } MessageHL7 hl7Ack=MessageConstructor.GenerateACK(messageControlId,isProcessed,ackEvent); if(hl7Ack==null) { _ecwTCPModeIsReceiving=false; socketIncomingHandler.Close(); throw new Exception("No ACK defined for the enabled HL7 definition or no HL7 definition enabled."); } byte[] ackByteOutgoing=Encoding.ASCII.GetBytes(MLLP_START_CHAR+hl7Ack.ToString()+MLLP_END_CHAR+MLLP_ENDMSG_CHAR); if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Beginning to send ACK.\r\n"+MLLP_START_CHAR+hl7Ack.ToString()+MLLP_END_CHAR+MLLP_ENDMSG_CHAR,EventLogEntryType.Information); } socketIncomingHandler.SendTimeout=5000;//timeout after 5 seconds of trying to send an acknowledgment try { socketIncomingHandler.Send(ackByteOutgoing);//this is a blocking call, timeout in 5 seconds } catch(Exception ex) { _ecwTCPModeIsReceiving=false; socketIncomingHandler.Close(); throw new Exception("Timeout or other error waiting to send an acknowledgment.\r\nException: "+ex.Message+"\r\n"+ex.StackTrace); } //eCW uses the same worker socket to send the next message. Without this call to BeginReceive, they would attempt to send again //and the send would fail since we were no longer listening in this thread. eCW would timeout after 30 seconds of waiting for their //acknowledgement, then they would close their end and create a new socket for the next message. With this call, we can accept message //after message without waiting for a new connection. //the buffer was cleared after appending the chars to the string builder //the string builder was cleared after setting the message text in the table if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Message was received and acknowledgment was sent. BeginReceive called again.",EventLogEntryType.Information); } _ecwTCPModeIsReceiving=true; IAsyncResult inSocketResult=socketIncomingHandler.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,new AsyncCallback(OnDataReceived),state); if(!inSocketResult.AsyncWaitHandle.WaitOne(new TimeSpan(0,5,0))) {//WaitOne will return true if data was received, false if the timeout is reached with no data received //if 5 minutes goes by with no recieved data, close the socket and set the receiveDone manual reset event. A new socket connection will be accepted. if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Setting manual reset event due to inactive timeout. The main receive thread will accept a new incoming connection.",EventLogEntryType.Information); } inSocketResult.AsyncWaitHandle.Close(); _ecwTCPModeIsReceiving=false; socketIncomingHandler.Close(); receiveDone.Set(); } else { inSocketResult.AsyncWaitHandle.Close(); } } catch(Exception ex) { EventLog.WriteEntry("OpenDentHL7","Error in OnDataReceived. Setting receiveDone manual reset event for main thread to accept new incoming connections.\r\n"+ex.Message+"\r\n"+ex.StackTrace,EventLogEntryType.Warning); if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Setting manual reset event so the main receive thread will accept a new incoming connection.",EventLogEntryType.Information); } _ecwTCPModeIsReceiving=false; ((StateObject)asyncResult.AsyncState).workSocket.Close(); receiveDone.Set();//this will trigger the main thread to accept a new incoming connection and try to receive data again } }
public static List<HL7Msg> GetOneExisting(HL7Msg hl7Msg) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { return Meth.GetObject<List<HL7Msg>>(MethodBase.GetCurrentMethod(),hl7Msg); } //Might want to change the following query to: //string command="SELECT * FROM hl7msg WHERE HL7Status IN("+POut.Long((int)HL7MessageStatus.InProcessed)+","+POut.Long((int)HL7MessageStatus.OutSent) //+") AND MsgText='"+POut.String(hl7Msg.MsgText)+"' "+DbHelper.LimitAnd(1); string command="SELECT * FROM hl7msg WHERE MsgText='"+POut.String(hl7Msg.MsgText)+"' "+DbHelper.LimitAnd(1); return Crud.HL7MsgCrud.SelectMany(command);//Just 0 or 1 item in list for now. }
private void butPDF_Click(object sender,EventArgs e) { //this will only happen for eCW HL7 interface users. List<Procedure> procs=Procedures.GetProcsForSingle(AptCur.AptNum,false); string duplicateProcs=ProcedureL.ProcsContainDuplicates(procs); if(duplicateProcs!="") { MessageBox.Show(duplicateProcs); return; } //Send DFT to eCW containing a dummy procedure with this appointment in a .pdf file. //no security string pdfDataStr=GenerateProceduresIntoPdf(); if(HL7Defs.IsExistingHL7Enabled()) { //PDF messages do not contain FT1 segments, so proc list can be empty //MessageHL7 messageHL7=MessageConstructor.GenerateDFT(procs,EventTypeHL7.P03,pat,Patients.GetPat(pat.Guarantor),AptCur.AptNum,"progressnotes",pdfDataStr); MessageHL7 messageHL7=MessageConstructor.GenerateDFT(new List<Procedure>(),EventTypeHL7.P03,pat,Patients.GetPat(pat.Guarantor),AptCur.AptNum,"progressnotes",pdfDataStr); if(messageHL7==null) { MsgBox.Show(this,"There is no DFT message type defined for the enabled HL7 definition."); return; } HL7Msg hl7Msg=new HL7Msg(); //hl7Msg.AptNum=AptCur.AptNum; hl7Msg.AptNum=0;//Prevents the appt complete button from changing to the "Revise" button prematurely. hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } else { Bridges.ECW.SendHL7(AptCur.AptNum,AptCur.ProvNum,pat,pdfDataStr,"progressnotes",true); } MsgBox.Show(this,"Notes PDF sent."); }
private void OnBreak_Click() { if(!PrefC.GetBool(PrefName.BrokenApptCommLogNotAdjustment) && PrefC.GetLong(PrefName.BrokenAppointmentAdjustmentType)==0) { MsgBox.Show(this,"Broken appointment adjustment type is not setup yet. Please go to Setup | Modules to fix this."); return; } int thisI=GetIndex(ContrApptSingle.SelectedAptNum); if(thisI==-1) {//selected appt is on a different day MsgBox.Show(this,"Please select an appointment first."); return; } Appointment apt = Appointments.GetOneApt(ContrApptSingle.SelectedAptNum); Patient pat=Patients.GetPat(PIn.Long(ContrApptSingle3[thisI].DataRoww["PatNum"].ToString())); if(!Security.IsAuthorized(Permissions.AppointmentEdit)) { return; } if(apt.AptStatus == ApptStatus.PtNote || apt.AptStatus == ApptStatus.PtNoteCompleted) { MsgBox.Show(this,"Only appointments may be broken, not notes."); return; } if(PrefC.GetBool(PrefName.BrokenApptCommLogNotAdjustment)) { if(!MsgBox.Show(this,true,"Break appointment?")) { return; } } Appointments.SetAptStatus(ContrApptSingle.SelectedAptNum,ApptStatus.Broken); SecurityLogs.MakeLogEntry(Permissions.AppointmentMove,pat.PatNum, ContrApptSingle3[thisI].DataRoww["procs"].ToString()+", "+ContrApptSingle3[thisI].DataRoww["AptDateTime"].ToString()+", Broken from the Appts module.", PIn.Long(ContrApptSingle3[thisI].DataRoww["AptNum"].ToString())); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S15 - Appt Cancellation event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(pat,Patients.GetPat(pat.Guarantor),EventTypeHL7.S15,apt); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=apt.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } long provNum=PIn.Long(ContrApptSingle3[thisI].DataRoww["ProvNum"].ToString());//remember before ModuleSelected ProcedureCode procCodeBrokenApt=ProcedureCodes.GetProcCode("D9986"); if(procCodeBrokenApt.CodeNum!=0) {//ADA proc code D9986 exists Procedure procedureCur=new Procedure(); procedureCur.PatNum=pat.PatNum; procedureCur.ProvNum=provNum; procedureCur.ProcFee=0; procedureCur.CodeNum=procCodeBrokenApt.CodeNum; procedureCur.ProcDate=DateTime.Today; procedureCur.DateEntryC=DateTime.Now; procedureCur.ProcStatus=ProcStat.C; procedureCur.ClinicNum=pat.ClinicNum; procedureCur.Note=Lan.g(this,"Appt BROKEN for ")+apt.ProcDescript+" "+apt.AptDateTime.ToString(); Procedures.Insert(procedureCur); //Now make a claimproc if the patient has insurance. We do this now for consistency because a claimproc could get created in the future. List<InsSub> listInsSubs=InsSubs.RefreshForFam(Patients.GetFamily(pat.PatNum)); List<InsPlan> listInsPlans=InsPlans.RefreshForSubList(listInsSubs); List<PatPlan> listPatPlans=PatPlans.Refresh(pat.PatNum); List<Benefit> listBenefits=Benefits.Refresh(listPatPlans,listInsSubs); List<ClaimProc> listClaimProcsForProc=ClaimProcs.RefreshForProc(procedureCur.ProcNum); Procedures.ComputeEstimates(procedureCur,pat.PatNum,listClaimProcsForProc,false,listInsPlans,listPatPlans,listBenefits,pat.Age,listInsSubs); FormProcEdit formP=new FormProcEdit(procedureCur,pat,Patients.GetFamily(pat.PatNum)); formP.IsNew=false; formP.ShowDialog(); if(PrefC.GetBool(PrefName.BrokenApptCommLogWithProcedure)) { Commlog CommlogCur=new Commlog(); CommlogCur.PatNum=pat.PatNum; CommlogCur.CommDateTime=DateTime.Now; CommlogCur.CommType=Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note=Lan.g(this,"Appt BROKEN for ")+apt.ProcDescript+" "+apt.AptDateTime.ToString(); CommlogCur.Mode_=CommItemMode.None; CommlogCur.UserNum=Security.CurUser.UserNum; FormCommItem FormCI=new FormCommItem(CommlogCur); FormCI.IsNew=true; FormCI.ShowDialog(); } } else {//No D9986 present if(PrefC.GetBool(PrefName.BrokenApptCommLogNotAdjustment)) { Commlog CommlogCur=new Commlog(); CommlogCur.PatNum=pat.PatNum; CommlogCur.CommDateTime=DateTime.Now; CommlogCur.CommType=Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note=Lan.g(this,"Appt BROKEN for ")+apt.ProcDescript+" "+apt.AptDateTime.ToString(); CommlogCur.Mode_=CommItemMode.None; CommlogCur.UserNum=Security.CurUser.UserNum; FormCommItem FormCI=new FormCommItem(CommlogCur); FormCI.IsNew=true; FormCI.ShowDialog(); } else { Adjustment AdjustmentCur=new Adjustment(); AdjustmentCur.DateEntry=DateTime.Today; AdjustmentCur.AdjDate=DateTime.Today; AdjustmentCur.ProcDate=DateTime.Today; AdjustmentCur.ProvNum=provNum; AdjustmentCur.PatNum=pat.PatNum; AdjustmentCur.AdjType=PrefC.GetLong(PrefName.BrokenAppointmentAdjustmentType); AdjustmentCur.ClinicNum=pat.ClinicNum; FormAdjust FormA=new FormAdjust(pat,AdjustmentCur); FormA.IsNew=true; FormA.ShowDialog(); } } ModuleSelected(pat.PatNum);//Must be ran after the "D9986" break logic due to the addition of a completed procedure. SetInvalid(); AutomationL.Trigger(AutomationTrigger.BreakAppointment,null,pat.PatNum); Recalls.SynchScheduledApptFull(apt.PatNum); }
private void OnComplete_Click() { if(!Security.IsAuthorized(Permissions.AppointmentEdit)) { return; } int thisI=GetIndex(ContrApptSingle.SelectedAptNum); if(thisI==-1) {//selected appt is on a different day MsgBox.Show(this,"Please select an appointment first."); return; } Appointment apt = Appointments.GetOneApt(ContrApptSingle.SelectedAptNum); if(apt.AptDateTime.Date>DateTime.Today) { if(!MsgBox.Show(this,MsgBoxButtons.OKCancel,"Appointment is in the future. Set complete anyway?")) { return; } } if(apt.AptStatus == ApptStatus.PtNoteCompleted) { return; } if(!Security.IsAuthorized(Permissions.ProcComplCreate,apt.AptDateTime)) { return; } //Procedures.SetDateFirstVisit(Appointments.Cur.AptDateTime.Date);//done when making appt instead Family fam = Patients.GetFamily(apt.PatNum); Patient pat = fam.GetPatient(apt.PatNum); List<InsSub> SubList=InsSubs.RefreshForFam(fam); List<InsPlan> PlanList=InsPlans.RefreshForSubList(SubList); List<PatPlan> PatPlanList = PatPlans.Refresh(apt.PatNum); if(apt.AptStatus == ApptStatus.PtNote) { Appointments.SetAptStatus(apt.AptNum,ApptStatus.PtNoteCompleted); SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit,apt.PatNum, apt.AptDateTime.ToString()+", Patient NOTE Set Complete", apt.AptNum);//shouldn't ever happen, but don't allow procedures to be completed from notes } else { InsSub sub1=InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList,PatPlans.GetOrdinal(PriSecMed.Primary,PatPlanList,PlanList,SubList)),SubList); InsSub sub2=InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList,PatPlans.GetOrdinal(PriSecMed.Secondary,PatPlanList,PlanList,SubList)),SubList); Appointments.SetAptStatusComplete(apt.AptNum,sub1.PlanNum,sub2.PlanNum); ProcedureL.SetCompleteInAppt(apt,PlanList,PatPlanList,pat.SiteNum,pat.Age,SubList);//loops through each proc SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit,apt.PatNum, ContrApptSingle3[GetIndex(apt.AptNum)].DataRoww["procs"].ToString()+", "+ apt.AptDateTime.ToString()+", Set Complete", apt.AptNum);//Log showing the appt. is set complete //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S14 - Appt Modification event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(pat,fam.GetPatient(pat.Guarantor),EventTypeHL7.S14,apt); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=apt.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } } Recalls.SynchScheduledApptFull(apt.PatNum); ModuleSelected(pat.PatNum); SetInvalid(); }
/// <summary> /// </summary> private Patient CreatePatient(String LastName,String FirstName,DateTime birthDate,WebSheets.SheetAndSheetField sAnds) { Patient newPat=new Patient(); newPat.LName=LastName; newPat.FName=FirstName; newPat.Birthdate=birthDate; newPat.ClinicNum=Security.CurUser.ClinicNum; Type t=newPat.GetType(); FieldInfo[] fi=t.GetFields(); foreach(FieldInfo field in fi) { // find match for fields in Patients in the web_sheetfieldlist var WebSheetFieldList=sAnds.web_sheetfieldlist.Where(sf=>sf.FieldName.ToLower()==field.Name.ToLower()); if(WebSheetFieldList.Count()>0) { // this loop is used to fill a field that may generate mutiple values for a single field in the patient. //for example the field gender has 2 eqivalent sheet fields in the web_sheetfieldlist for(int i=0;i<WebSheetFieldList.Count();i++) { WebSheets.webforms_sheetfield sf=WebSheetFieldList.ElementAt(i); String SheetWebFieldValue=sf.FieldValue; String RadioButtonValue=sf.RadioButtonValue; FillPatientFields(newPat,field,SheetWebFieldValue,RadioButtonValue); } } } try{ Patients.Insert(newPat,false); //set Guarantor field the same as PatNum Patient patOld=newPat.Copy(); newPat.Guarantor=newPat.PatNum; Patients.Update(newPat,patOld); //If there is an existing HL7 def enabled, send an ADT message if there is an outbound ADT message defined if(HL7Defs.IsExistingHL7Enabled()) { MessageHL7 messageHL7=MessageConstructor.GenerateADT(newPat,newPat,EventTypeHL7.A04);//patient is guarantor //Will be null if there is no outbound ADT message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=0; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=newPat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } } catch(Exception e) { gridMain.EndUpdate(); MessageBox.Show(e.Message); } return newPat; }
private void OnDelete_Click() { long selectedAptNum=ContrApptSingle.SelectedAptNum; Appointment apt = Appointments.GetOneApt(selectedAptNum); if(!Security.IsAuthorized(Permissions.AppointmentEdit)) { return; } int thisI=GetIndex(selectedAptNum); if(thisI==-1) {//selected appt is on a different day MsgBox.Show(this,"Please select an appointment first."); return; } if(apt.AptStatus == ApptStatus.PtNote | apt.AptStatus == ApptStatus.PtNoteCompleted) { if(!MsgBox.Show(this,true,"Delete Patient Note?")) { return; } if(apt.Note != "") { if(MessageBox.Show(Commlogs.GetDeleteApptCommlogMessage(apt.Note,apt.AptStatus),"Question...",MessageBoxButtons.YesNo) == DialogResult.Yes) { Commlog CommlogCur = new Commlog(); CommlogCur.PatNum = apt.PatNum; CommlogCur.CommDateTime = apt.AptDateTime; CommlogCur.CommType =Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note = "Deleted Patient NOTE from schedule, saved copy: "; CommlogCur.Note += apt.Note; CommlogCur.UserNum=Security.CurUser.UserNum; //there is no dialog here because it is just a simple entry Commlogs.Insert(CommlogCur); } } SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit,PatCur.PatNum, ContrApptSingle3[thisI].DataRoww["procs"].ToString()+", "+ContrApptSingle3[thisI].DataRoww["AptDateTime"].ToString()+", "+"NOTE Deleted", PIn.Long(ContrApptSingle3[thisI].DataRoww["AptNum"].ToString())); } else { if(!MsgBox.Show(this,true,"Delete Appointment?")) { return; } if(apt.Note != "") { if(MessageBox.Show(Commlogs.GetDeleteApptCommlogMessage(apt.Note,apt.AptStatus),"Question...",MessageBoxButtons.YesNo) == DialogResult.Yes) { Commlog CommlogCur = new Commlog(); CommlogCur.PatNum = apt.PatNum; CommlogCur.CommDateTime = apt.AptDateTime; CommlogCur.CommType =Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note = "Deleted Appointment & saved note: "; if(apt.ProcDescript != "") { CommlogCur.Note += apt.ProcDescript + ": "; } CommlogCur.Note += apt.Note; CommlogCur.UserNum=Security.CurUser.UserNum; //there is no dialog here because it is just a simple entry Commlogs.Insert(CommlogCur); } } SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit,PatCur.PatNum, ContrApptSingle3[thisI].DataRoww["procs"].ToString()+", "+ContrApptSingle3[thisI].DataRoww["AptDateTime"].ToString()+", "+"Deleted", PIn.Long(ContrApptSingle3[thisI].DataRoww["AptNum"].ToString())); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S17 - Appt Deletion event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(PatCur,Patients.GetPat(PatCur.Guarantor),EventTypeHL7.S17,apt); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=apt.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } } Appointments.Delete(selectedAptNum); ContrApptSingle.SelectedAptNum=-1; pinBoard.SelectedIndex=-1; DataRow row; for(int i=0;i<pinBoard.ApptList.Count;i++) { row=pinBoard.ApptList[i].DataRoww; if(selectedAptNum.ToString()==row["AptNum"].ToString()) { pinBoard.SelectedIndex=i; pinBoard.ClearSelected(); pinBoard.SelectedIndex=-1; } } //ContrApptSingle.PinBoardIsSelected=false; //PatCurNum=0; if(PatCur==null) { ModuleSelected(0); } else { ModuleSelected(PatCur.PatNum); } SetInvalid(); Recalls.SynchScheduledApptFull(apt.PatNum); }
///<Summary>Usually happens after a pinboard appt has been dragged onto main appt sheet.</Summary> private void pinBoard_MouseUp(object sender,MouseEventArgs e) { if(!boolAptMoved) { mouseIsDown=false; if(TempApptSingle!=null) { TempApptSingle.Dispose(); } return; } if(TempApptSingle.Location.X>ContrApptSheet2.Width) { mouseIsDown=false; boolAptMoved=false; TempApptSingle.Dispose(); return; } if(pinBoard.SelectedAppt.DataRoww["AptStatus"].ToString()==((int)ApptStatus.Planned).ToString()//if Planned appt is on pinboard && !Security.IsAuthorized(Permissions.AppointmentCreate))//and no permission to create a new appt { mouseIsDown = false; boolAptMoved=false; TempApptSingle.Dispose(); return; } //security prevents moving an appointment by preventing placing it on the pinboard, not here //We no longer ask user this question. It just slows things down: "Move Appointment?" //convert loc to new time Appointment aptCur=Appointments.GetOneApt(PIn.Long(pinBoard.SelectedAppt.DataRoww["AptNum"].ToString())); if(aptCur==null) { MsgBox.Show(this,"This appointment has been deleted since it was moved to the pinboard. It will now be cleared from the pinboard."); mouseIsDown = false; boolAptMoved=false; TempApptSingle.Dispose(); pinBoard.ClearSelected(); return; } Appointment aptOld=aptCur.Clone(); RefreshModuleDataPatient(PIn.Long(pinBoard.SelectedAppt.DataRoww["PatNum"].ToString()));//redundant? //Patient pat=Patients.GetPat(PIn.PInt(pinBoard.SelectedAppt.DataRoww["PatNum"].ToString())); if(aptCur.IsNewPatient && AppointmentL.DateSelected!=aptCur.AptDateTime) { Procedures.SetDateFirstVisit(AppointmentL.DateSelected,4,PatCur); } int tHr=ApptDrawing.ConvertToHour(TempApptSingle.Location.Y-ContrApptSheet2.Location.Y-panelSheet.Location.Y); int tMin=ApptDrawing.ConvertToMin(TempApptSingle.Location.Y-ContrApptSheet2.Location.Y-panelSheet.Location.Y); DateTime tDate=AppointmentL.DateSelected; if(ApptDrawing.IsWeeklyView) { tDate=WeekStartDate.AddDays(ApptDrawing.ConvertToDay(TempApptSingle.Location.X-ContrApptSheet2.Location.X)); } DateTime fromDate=aptCur.AptDateTime.Date; aptCur.AptDateTime=new DateTime(tDate.Year,tDate.Month,tDate.Day,tHr,tMin,0); if(AppointmentRuleC.List.Length>0) { //this is crude and temporary: List<long> aptNums=new List<long>(); for(int i=0;i<DS.Tables["Appointments"].Rows.Count;i++) { aptNums.Add(PIn.Long(DS.Tables["Appointments"].Rows[i]["AptNum"].ToString()));//ListDay[i].AptNum; } List<Procedure> procsMultApts=Procedures.GetProcsMultApts(aptNums); Procedure[] procsForOne=Procedures.GetProcsOneApt(aptCur.AptNum,procsMultApts); ArrayList doubleBookedCodes= AppointmentL.GetDoubleBookedCodes(aptCur,DS.Tables["Appointments"].Copy(),procsMultApts,procsForOne); if(doubleBookedCodes.Count>0) {//if some codes would be double booked if(AppointmentRules.IsBlocked(doubleBookedCodes)) { MessageBox.Show(Lan.g(this,"Not allowed to double book:")+" " +AppointmentRules.GetBlockedDescription(doubleBookedCodes)); mouseIsDown = false; boolAptMoved=false; TempApptSingle.Dispose(); return; } } } Operatory curOp=ApptDrawing.VisOps [ApptDrawing.ConvertToOp(TempApptSingle.Location.X-ContrApptSheet2.Location.X)]; aptCur.Op=curOp.OperatoryNum; long assignedDent=Schedules.GetAssignedProvNumForSpot(SchedListPeriod,curOp,false,aptCur.AptDateTime); long assignedHyg=Schedules.GetAssignedProvNumForSpot(SchedListPeriod,curOp,true,aptCur.AptDateTime); List<Procedure> procsForSingleApt=null; if(aptCur.AptStatus!=ApptStatus.PtNote && aptCur.AptStatus!=ApptStatus.PtNoteCompleted) { if(PatCur.AskToArriveEarly>0) { aptCur.DateTimeAskedToArrive=aptCur.AptDateTime.AddMinutes(-PatCur.AskToArriveEarly); MessageBox.Show(Lan.g(this,"Ask patient to arrive")+" "+PatCur.AskToArriveEarly +" "+Lan.g(this,"minutes early at")+" "+aptCur.DateTimeAskedToArrive.ToShortTimeString()+"."); } else { aptCur.DateTimeAskedToArrive=DateTime.MinValue; } //if no dentist/hygienist is assigned to spot, then keep the original dentist/hygienist without prompt. All appts must have prov. if((assignedDent!=0 && assignedDent!=aptCur.ProvNum) || (assignedHyg!=0 && assignedHyg!=aptCur.ProvHyg)) { if(MessageBox.Show(Lan.g(this,"Change provider?"),"",MessageBoxButtons.YesNo)==DialogResult.Yes) { if(assignedDent!=0) { aptCur.ProvNum=assignedDent; } if(assignedHyg!=0) {//the hygienist will only be changed if the spot has a hygienist. aptCur.ProvHyg=assignedHyg; } if(curOp.IsHygiene) { aptCur.IsHygiene=true; } else {//op not marked as hygiene op if(assignedDent==0) {//no dentist assigned if(assignedHyg!=0) {//hyg is assigned (we don't really have to test for this) aptCur.IsHygiene=true; } } else {//dentist is assigned if(assignedHyg==0) {//hyg is not assigned aptCur.IsHygiene=false; } //if both dentist and hyg are assigned, it's tricky //only explicitly set it if user has a dentist assigned to the op if(curOp.ProvDentist!=0) { aptCur.IsHygiene=false; } } } bool isplanned=aptCur.AptStatus==ApptStatus.Planned; procsForSingleApt=Procedures.GetProcsForSingle(aptCur.AptNum,isplanned); List<long> codeNums=new List<long>(); for(int p=0;p<procsForSingleApt.Count;p++) { codeNums.Add(procsForSingleApt[p].CodeNum); } string calcPattern=Appointments.CalculatePattern(aptCur.ProvNum,aptCur.ProvHyg,codeNums,true); if(aptCur.Pattern != calcPattern && !PrefC.GetBool(PrefName.AppointmentTimeIsLocked)) { if(aptCur.TimeLocked){ if(MsgBox.Show(this,MsgBoxButtons.YesNo,"Appointment length is locked. Change length for new provider anyway?")) { aptCur.Pattern=calcPattern; } } else {//appt time not locked if(MsgBox.Show(this,MsgBoxButtons.YesNo,"Change length for new provider?")) { aptCur.Pattern=calcPattern; } } } } } } //Appointment is ready to be placed on the schedule. Refresh all appointments to avoid overlapping. RefreshPeriod(); if(DoesOverlap(aptCur)) { int startingOp=ApptDrawing.GetIndexOp(aptCur.Op); bool stillOverlaps=true; for(int i=startingOp;i<ApptDrawing.VisOps.Count;i++) { aptCur.Op=ApptDrawing.VisOps[i].OperatoryNum; if(!DoesOverlap(aptCur)) { stillOverlaps=false; break; } } if(stillOverlaps) { for(int i=startingOp;i>=0;i--) { aptCur.Op=ApptDrawing.VisOps[i].OperatoryNum; if(!DoesOverlap(aptCur)) { stillOverlaps=false; break; } } } if(stillOverlaps) { MessageBox.Show(Lan.g(this,"Appointment overlaps existing appointment.")); mouseIsDown=false; boolAptMoved=false; TempApptSingle.Dispose(); return; } } Operatory opCur=Operatories.GetOperatory(aptCur.Op); Operatory opOld=Operatories.GetOperatory(aptOld.Op); if(opOld==null || opCur.SetProspective!=opOld.SetProspective) { if(opCur.SetProspective && PatCur.PatStatus!=PatientStatus.Prospective) { //Don't need to prompt if patient is already prospective. if(MsgBox.Show(this,MsgBoxButtons.OKCancel,"Patient's status will be set to Prospective.")) { Patient patOld=PatCur.Copy(); PatCur.PatStatus=PatientStatus.Prospective; Patients.Update(PatCur,patOld); } } else if(!opCur.SetProspective && PatCur.PatStatus==PatientStatus.Prospective) { //Do we need to warn about changing FROM prospective? Assume so for now. if(MsgBox.Show(this,MsgBoxButtons.OKCancel,"Patient's status will change from Prospective to Patient.")) { Patient patOld=PatCur.Copy(); PatCur.PatStatus=PatientStatus.Patient; Patients.Update(PatCur,patOld); } } } if(aptCur.AptStatus==ApptStatus.Broken) { aptCur.AptStatus=ApptStatus.Scheduled; } if(aptCur.AptStatus==ApptStatus.UnschedList) { aptCur.AptStatus=ApptStatus.Scheduled; } //original position of provider settings if(curOp.ClinicNum==0){ aptCur.ClinicNum=PatCur.ClinicNum; } else{ aptCur.ClinicNum=curOp.ClinicNum; } if(aptCur.AptStatus==ApptStatus.Planned) {//if Planned appt is on pinboard long plannedAptNum=aptCur.AptNum; LabCase lab=LabCases.GetForPlanned(aptCur.AptNum); aptCur.NextAptNum=aptCur.AptNum; aptCur.AptStatus=ApptStatus.Scheduled; aptCur.TimeLocked=PrefC.GetBool(PrefName.AppointmentTimeIsLocked); try { Appointments.Insert(aptCur);//now, aptnum is different. for(int i=0;i<pinBoard.SelectedAppt.TableApptFields.Rows.Count;i++) {//Duplicate the appointment fields. //in SendToPinboard, TableApptFields is refreshed for just the one planned appt instead of all appts for day. ApptField apptField=new ApptField(); apptField.AptNum=aptCur.AptNum; apptField.FieldName=PIn.String(pinBoard.SelectedAppt.TableApptFields.Rows[i]["FieldName"].ToString()); apptField.FieldValue=PIn.String(pinBoard.SelectedAppt.TableApptFields.Rows[i]["FieldValue"].ToString()); ApptFields.Insert(apptField); } //for(int i=0;i<pinBoard.SelectedAppt.TablePatFields.Rows.Count;i++) {//Duplicate the patient fields. // PatField patField=new PatField(); // patField.PatNum=aptCur.PatNum; // patField.FieldName=PIn.String(pinBoard.SelectedAppt.TablePatFields.Rows[i]["FieldName"].ToString()); // patField.FieldValue=PIn.String(pinBoard.SelectedAppt.TablePatFields.Rows[i]["FieldValue"].ToString()); // PatFields.Insert(patField); //} } catch(ApplicationException ex) { MessageBox.Show(ex.Message); return; } SecurityLogs.MakeLogEntry(Permissions.AppointmentCreate,aptCur.PatNum, aptCur.AptDateTime.ToString()+", "+aptCur.ProcDescript, aptCur.AptNum); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S12 - New Appt Booking event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(PatCur,Patients.GetPat(PatCur.Guarantor),EventTypeHL7.S12,aptCur); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=aptCur.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } List<Procedure> ProcList=Procedures.Refresh(aptCur.PatNum); bool procAlreadyAttached=false; for(int i=0;i<ProcList.Count;i++) { if(ProcList[i].PlannedAptNum==plannedAptNum) {//if on the planned apt if(ProcList[i].AptNum>0) {//already attached to another appt procAlreadyAttached=true; } else {//only update procedures not already attached to another apt Procedures.UpdateAptNum(ProcList[i].ProcNum,aptCur.AptNum); //.Update(ProcCur,ProcOld);//recall synch not required. } } } if(procAlreadyAttached) { MessageBox.Show(Lan.g(this,"One or more procedures could not be scheduled because they were already attached to another appointment. Someone probably forgot to update the Next appointment in the Chart module.")); FormApptEdit formAE=new FormApptEdit(aptCur.AptNum); CheckStatus(); formAE.IsNew=true; formAE.ShowDialog();//to force refresh of aptDescript if(formAE.DialogResult!=DialogResult.OK) {//apt gets deleted from within aptEdit window. TempApptSingle.Dispose(); RefreshModuleScreenPatient(); RefreshPeriod(); mouseIsDown = false; boolAptMoved=false; return; } } if(lab!=null) { LabCases.AttachToAppt(lab.LabCaseNum,aptCur.AptNum); } }//if planned appointment is on pinboard else {//simple drag off pinboard to a new date/time aptCur.Confirmed=DefC.Short[(int)DefCat.ApptConfirmed][0].DefNum;//Causes the confirmation status to be reset. try { Appointments.Update(aptCur,aptOld); bool isCreate=false; if(aptOld.AptStatus==ApptStatus.UnschedList && aptOld.AptDateTime==DateTime.MinValue) { //If new appt is being added to schedule from pinboard SecurityLogs.MakeLogEntry(Permissions.AppointmentCreate,aptCur.PatNum, aptCur.AptDateTime.ToString()+", "+aptCur.ProcDescript, aptCur.AptNum); isCreate=true; } else { //If existing appt is being moved SecurityLogs.MakeLogEntry(Permissions.AppointmentMove,aptCur.PatNum, aptCur.ProcDescript+", from "+aptOld.AptDateTime.ToString()+", to "+aptCur.AptDateTime.ToString(), aptCur.AptNum); } //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S12 - New Appt Booking event, S13 - Appt Rescheduling MessageHL7 messageHL7=null; if(isCreate) { messageHL7=MessageConstructor.GenerateSIU(PatCur,Patients.GetPat(PatCur.Guarantor),EventTypeHL7.S12,aptCur); } else { messageHL7=MessageConstructor.GenerateSIU(PatCur,Patients.GetPat(PatCur.Guarantor),EventTypeHL7.S13,aptCur); } //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=aptCur.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } } catch(ApplicationException ex) { MessageBox.Show(ex.Message); return; } } if(procsForSingleApt==null) { procsForSingleApt=Procedures.GetProcsForSingle(aptCur.AptNum,false); } Procedures.SetProvidersInAppointment(aptCur,procsForSingleApt); TempApptSingle.Dispose(); pinBoard.ClearSelected(); //PinApptSingle.Visible=false; //ContrApptSingle.PinBoardIsSelected=false; ContrApptSingle.SelectedAptNum=aptCur.AptNum; RefreshModuleScreenPatient(); //RefreshModulePatient(PatCurNum); RefreshPeriod();//date moving to for this computer SetInvalid();//date moving to for other computers AppointmentL.DateSelected=fromDate; SetInvalid();//for date moved from for other computers. AppointmentL.DateSelected=aptCur.AptDateTime; mouseIsDown = false; boolAptMoved=false; List<string> procCodes=new List<string>(); for(int i=0;i<procsForSingleApt.Count;i++) { procCodes.Add(ProcedureCodes.GetProcCode((long)procsForSingleApt[i].CodeNum).ProcCode); } //Recalls.SynchScheduledApptLazy(aptCur.PatNum, aptCur.AptDateTime, procCodes); Recalls.SynchScheduledApptFull(aptCur.PatNum); }
public static void UpdateDateTStamp(HL7Msg hl7Msg) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(),hl7Msg); return; } string command="UPDATE hl7msg SET DateTStamp=CURRENT_TIMESTAMP WHERE MsgText='"+POut.String(hl7Msg.MsgText)+"' "; Db.NonQ(command); }
private void butOK_Click(object sender, System.EventArgs e) { bool CDSinterventionCheckRequired=false;//checks selected values if( textBirthdate.errorProvider1.GetError(textBirthdate)!="" || textDateFirstVisit.errorProvider1.GetError(textDateFirstVisit)!="" || textAdmitDate.errorProvider1.GetError(textAdmitDate)!="" ){ MsgBox.Show(this,"Please fix data entry errors first."); return; } DateTime dateTimeDeceased=DateTime.MinValue; try { if(textDateDeceased.Text!="") { dateTimeDeceased=DateTime.Parse(textDateDeceased.Text); } } catch { MsgBox.Show(this,"Date time deceased is invalid."); return; } if(textLName.Text==""){ MsgBox.Show(this,"Last Name must be entered."); return; } //see if chartNum is a duplicate if(textChartNumber.Text!=""){ //the patNum will be 0 for new string usedBy=Patients.ChartNumUsedBy(textChartNumber.Text,PatCur.PatNum); if(usedBy!=""){ MessageBox.Show(Lan.g(this,"This chart number is already in use by:")+" "+usedBy); return; } } try{ PIn.Int(textAskToArriveEarly.Text); } catch{ MsgBox.Show(this,"Ask To Arrive Early invalid."); return; } if(textCounty.Text != "" && !Counties.DoesExist(textCounty.Text)){ MessageBox.Show(Lan.g(this,"County name invalid.")); return; } if(textSite.Text=="") { PatCur.SiteNum=0; } if(textSite.Text != "" && textSite.Text != Sites.GetDescription(PatCur.SiteNum)) { long matchingSite=Sites.FindMatchSiteNum(textSite.Text); if(matchingSite==-1) { MessageBox.Show(Lan.g(this,"Invalid Site description.")); return; } else { PatCur.SiteNum=matchingSite; } } if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA if(comboCanadianEligibilityCode.SelectedIndex==1//FT student && textSchool.Text=="" && PIn.Date(textBirthdate.Text).AddYears(18)<=DateTime.Today) { MsgBox.Show(this,"School should be entered if full-time student and patient is 18 or older."); return; } } //If HQ and this is a patient in a reseller family, do not allow the changing of the patient status. if(PrefC.GetBool(PrefName.DockPhonePanelShow) && Resellers.IsResellerFamily(PatCur.Guarantor) && PatOld.PatStatus!=(PatientStatus)listStatus.SelectedIndex) { MsgBox.Show(this,"Cannot change the status of a patient in a reseller family."); return; } PatCur.LName=textLName.Text; PatCur.FName=textFName.Text; PatCur.MiddleI=textMiddleI.Text; PatCur.Preferred=textPreferred.Text; PatCur.Title=textTitle.Text; PatCur.Salutation=textSalutation.Text; if(PrefC.GetBool(PrefName.ShowFeatureEhr)) {//Mother's maiden name UI is only used when EHR is enabled. _ehrPatientCur.MotherMaidenFname=textMotherMaidenFname.Text; _ehrPatientCur.MotherMaidenLname=textMotherMaidenLname.Text; EhrPatients.Update(_ehrPatientCur); } switch(listStatus.SelectedIndex){ case 0: PatCur.PatStatus=PatientStatus.Patient; break; case 1: PatCur.PatStatus=PatientStatus.NonPatient; break; case 2: PatCur.PatStatus=PatientStatus.Inactive; break; case 3: PatCur.PatStatus=PatientStatus.Archived; break; case 4: PatCur.PatStatus=PatientStatus.Deceased; break; case 5: PatCur.PatStatus=PatientStatus.Prospective; break; } switch(listGender.SelectedIndex){ case 0: PatCur.Gender=PatientGender.Male; break; case 1: PatCur.Gender=PatientGender.Female; break; case 2: PatCur.Gender=PatientGender.Unknown; break; } switch(listPosition.SelectedIndex){ case 0: PatCur.Position=PatientPosition.Single; break; case 1: PatCur.Position=PatientPosition.Married; break; case 2: PatCur.Position=PatientPosition.Child; break; case 3: PatCur.Position=PatientPosition.Widowed; break; case 4: PatCur.Position=PatientPosition.Divorced; break; } PatCur.Birthdate=PIn.Date(textBirthdate.Text); PatCur.DateTimeDeceased=dateTimeDeceased; if(CultureInfo.CurrentCulture.Name=="en-US"){ if(Regex.IsMatch(textSSN.Text,@"^\d\d\d-\d\d-\d\d\d\d$")){ PatCur.SSN=textSSN.Text.Substring(0,3)+textSSN.Text.Substring(4,2) +textSSN.Text.Substring(7,4); } else{ PatCur.SSN=textSSN.Text; } } else{//other cultures PatCur.SSN=textSSN.Text; } if(IsNew) {//Check if patient already exists. List<Patient> patList=Patients.GetListByName(PatCur.LName,PatCur.FName,PatCur.PatNum); for(int i=0;i<patList.Count;i++) { //If dates match or aren't entered there might be a duplicate patient. if(patList[i].Birthdate==PatCur.Birthdate || patList[i].Birthdate.Year<1880 || PatCur.Birthdate.Year<1880) { if(!MsgBox.Show(this,MsgBoxButtons.OKCancel,"This patient might already exist. Continue anyway?")) { return; } break; } } } PatCur.MedicaidID=textMedicaidID.Text; PatCur.WkPhone=textWkPhone.Text; PatCur.WirelessPhone=textWirelessPhone.Text; PatCur.TxtMsgOk=(YN)listTextOk.SelectedIndex; PatCur.Email=textEmail.Text; //PatCur.RecallInterval=PIn.PInt(textRecall.Text); PatCur.ChartNumber=textChartNumber.Text; PatCur.SchoolName=textSchool.Text; //address: PatCur.HmPhone=textHmPhone.Text; PatCur.Address=textAddress.Text; PatCur.Address2=textAddress2.Text; PatCur.City=textCity.Text; PatCur.State=textState.Text; PatCur.Country=textCountry.Text; PatCur.Zip=textZip.Text; PatCur.CreditType=textCreditType.Text; GetEmployerNum(); //PatCur.EmploymentNote=textEmploymentNote.Text; if(comboLanguage.SelectedIndex==0){ PatCur.Language=""; } else{ PatCur.Language=languageList[comboLanguage.SelectedIndex-1]; } PatCur.AddrNote=textAddrNotes.Text; PatCur.DateFirstVisit=PIn.Date(textDateFirstVisit.Text); PatCur.AskToArriveEarly=PIn.Int(textAskToArriveEarly.Text); if(comboPriProv.SelectedIndex!=-1) { PatCur.PriProv=ProviderC.ListShort[comboPriProv.SelectedIndex].ProvNum; } if(comboSecProv.SelectedIndex==0){ PatCur.SecProv=0; } else{ PatCur.SecProv=ProviderC.ListShort[comboSecProv.SelectedIndex-1].ProvNum; } if(comboFeeSched.SelectedIndex==0){ PatCur.FeeSched=0; } else{ PatCur.FeeSched=FeeSchedC.ListShort[comboFeeSched.SelectedIndex-1].FeeSchedNum; } if(comboBillType.SelectedIndex!=-1){ PatCur.BillingType=DefC.Short[(int)DefCat.BillingTypes][comboBillType.SelectedIndex].DefNum; } if(comboClinic.SelectedIndex==0) { PatCur.ClinicNum=0; } else { PatCur.ClinicNum=_listClinics[comboClinic.SelectedIndex-1].ClinicNum; } List<PatRace> listPatRaces=new List<PatRace>(); for(int i=0;i<comboBoxMultiRace.SelectedIndices.Count;i++) { int selectedIdx=(int)comboBoxMultiRace.SelectedIndices[i]; if(selectedIdx==0) {//If the none option was chosen, then ensure that no other race information is saved. listPatRaces.Clear(); break; } if(!PrefC.GetBool(PrefName.ShowFeatureEhr)) {//If not using EHR, then the comboBoxMultiRace item locations are the same as the PatRace enum locations plus 1. listPatRaces.Add((PatRace)(selectedIdx-1)); continue; } //EHR if(selectedIdx==1) { listPatRaces.Add(PatRace.AfricanAmerican); } else if(selectedIdx==2) { listPatRaces.Add(PatRace.AmericanIndian); } else if(selectedIdx==3) { listPatRaces.Add(PatRace.Asian); } else if(selectedIdx==4) { listPatRaces.Add(PatRace.DeclinedToSpecifyRace); } else if(selectedIdx==5) { listPatRaces.Add(PatRace.HawaiiOrPacIsland); } else if(selectedIdx==6) { listPatRaces.Add(PatRace.Other); } else if(selectedIdx==7) { listPatRaces.Add(PatRace.White); } } if(listPatRaces.Contains(PatRace.DeclinedToSpecifyRace)) {//If DeclinedToSpecify was chosen, then ensure that no other races are saved. listPatRaces.Clear(); listPatRaces.Add(PatRace.DeclinedToSpecifyRace); } else if(listPatRaces.Contains(PatRace.Other)) {//If Other was chosen, then ensure that no other races are saved. listPatRaces.Clear(); listPatRaces.Add(PatRace.Other); } //In order to pass EHR G2 MU testing you must be able to have an ethnicity without a race, or a race without an ethnicity. This will mean that patients will not count towards // meaningfull use demographic calculations. If we have time in the future we should probably alert EHR users when a race is chosen but no ethnicity, or a ethnicity but no race. if(comboEthnicity.SelectedIndex==1) { listPatRaces.Add(PatRace.DeclinedToSpecifyEthnicity); } else if(comboEthnicity.SelectedIndex==2){ listPatRaces.Add(PatRace.NotHispanic); } else if(comboEthnicity.SelectedIndex==3) { listPatRaces.Add(PatRace.Hispanic); } PatientRaces.Reconcile(PatCur.PatNum,listPatRaces);//Insert, Update, Delete if needed. PatCur.County=textCounty.Text; //site set when user picks from list. PatCur.GradeLevel=(PatientGrade)comboGradeLevel.SelectedIndex; PatCur.Urgency=(TreatmentUrgency)comboUrgency.SelectedIndex; //ResponsParty handled when buttons are pushed. if(Programs.IsEnabled(ProgramName.TrophyEnhanced)) { PatCur.TrophyFolder=textTrophyFolder.Text; } PatCur.Ward=textWard.Text; PatCur.PreferContactMethod=(ContactMethod)comboContact.SelectedIndex; PatCur.PreferConfirmMethod=(ContactMethod)comboConfirm.SelectedIndex; PatCur.PreferRecallMethod=(ContactMethod)comboRecall.SelectedIndex; PatCur.AdmitDate=PIn.Date(textAdmitDate.Text); if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canadian. en-CA or fr-CA PatCur.CanadianEligibilityCode=(byte)comboCanadianEligibilityCode.SelectedIndex; } if(PatCur.Guarantor==0){ PatCur.Guarantor=PatCur.PatNum; } Patients.Update(PatCur,PatOld); if(PatCur.Birthdate!=PatOld.Birthdate || PatCur.Gender!=PatOld.Gender) { CDSinterventionCheckRequired=true; } if(CDSinterventionCheckRequired && CDSPermissions.GetForUser(Security.CurUser.UserNum).ShowCDS && CDSPermissions.GetForUser(Security.CurUser.UserNum).LabTestCDS) { FormCDSIntervention FormCDSI=new FormCDSIntervention(); FormCDSI.ListCDSI=EhrTriggers.TriggerMatch(PatCur,PatCur);//both should be patCur. FormCDSI.ShowIfRequired(false); } if(checkArriveEarlySame.Checked){ Patients.UpdateArriveEarlyForFam(PatCur); } if(checkSame.Checked){ //might want to include a mechanism for comparing fields to be overwritten Patients.UpdateAddressForFam(PatCur); } if(checkNotesSame.Checked){ Patients.UpdateNotesForFam(PatCur); } if(checkEmailPhoneSame.Checked) { Patients.UpdateEmailPhoneForFam(PatCur); } //If this patient is also a referral source, //keep address info synched: for(int i=0;i<Referrals.List.Length;i++){ if(Referrals.List[i].PatNum==PatCur.PatNum){ //Referrals.Cur=Referrals.List[i]; Referrals.List[i].LName=PatCur.LName; Referrals.List[i].FName=PatCur.FName; Referrals.List[i].MName=PatCur.MiddleI; Referrals.List[i].Address=PatCur.Address; Referrals.List[i].Address2=PatCur.Address2; Referrals.List[i].City=PatCur.City; Referrals.List[i].ST=PatCur.State; Referrals.List[i].SSN=PatCur.SSN; Referrals.List[i].Zip=PatCur.Zip; Referrals.List[i].Telephone=TelephoneNumbers.FormatNumbersExactTen(PatCur.HmPhone); Referrals.List[i].EMail=PatCur.Email; Referrals.Update(Referrals.List[i]); Referrals.RefreshCache(); break; } } //if patient is inactive, then disable any recalls if(PatCur.PatStatus==PatientStatus.Archived || PatCur.PatStatus==PatientStatus.Deceased || PatCur.PatStatus==PatientStatus.Inactive || PatCur.PatStatus==PatientStatus.NonPatient || PatCur.PatStatus==PatientStatus.Prospective) { List<Recall> recalls=Recalls.GetList(PatCur.PatNum); for(int i=0;i<recalls.Count;i++){ recalls[i].IsDisabled=true; recalls[i].DateDue=DateTime.MinValue; Recalls.Update(recalls[i]); } } //if patient was re-activated, then re-enable any recalls else if(PatCur.PatStatus!=PatOld.PatStatus && PatCur.PatStatus==PatientStatus.Patient) {//if changed patstatus, and new status is Patient List<Recall> recalls=Recalls.GetList(PatCur.PatNum); for(int i=0;i<recalls.Count;i++) { if(recalls[i].IsDisabled) { recalls[i].IsDisabled=false; Recalls.Update(recalls[i]); } } Recalls.Synch(PatCur.PatNum); } //if pref for Patient Clone is enabled, check to see if this patient is part of a clone pair, either the clone or original //if part of a clone pair and the name or birthdate has been changed, synch the clone if PatCur is the original //warn the user if PatCur is the clone that the linkage will be broken and to fix the value changed on the clone patient to re-link //we do not want to synch from clone to original, so they have to fix manually if(PrefC.GetBool(PrefName.ShowFeaturePatientClone) && (PatCur.LName!=PatOld.LName || PatCur.FName!=PatOld.FName || PatCur.Birthdate!=PatOld.Birthdate)) { Patient patClone; Patient patNonClone; List<Patient> listAmbiguousMatches; Patients.GetCloneAndNonClone(PatOld,out patClone,out patNonClone,out listAmbiguousMatches); if(patClone!=null) { if(PatOld.PatNum==patClone.PatNum) {//PatOld is the clone, message box warning the user that changing the name and/or birthdate will now break the clone linkage MessageBox.Show(Lan.g(this,"Changing the name of this patient clone will unlink it from the following patient") +":\r\n"+patNonClone.PatNum+" - "+Patients.GetNameFL(patNonClone.LName,patNonClone.FName,patNonClone.Preferred,patNonClone.MiddleI)+".\r\n" +Lan.g(this,"To re-link, the birthdates must be matching valid dates and the first and last names must be identical with the clone name all uppercase.")); } else {//PatOld must be the non-clone, synch the name and birthdate changes to the clone Patient patCloneOld=patClone.Copy(); string strChngTo=" "+Lan.g(this,"changed to")+" "; string changeMsg=Lan.g(this,"The following changes were synched to the clone of this patient,\r\n") +patClone.PatNum+" - "+Patients.GetNameFL(patClone.LName,patClone.FName,patClone.Preferred,patClone.MiddleI)+":"; if(PatCur.LName!=PatOld.LName) { patClone.LName=PatCur.LName.ToUpper(); changeMsg+="\r\n"+patCloneOld.LName+strChngTo+patClone.LName; } if(PatCur.FName!=PatOld.FName) { patClone.FName=PatCur.FName.ToUpper(); changeMsg+="\r\n"+patCloneOld.FName+strChngTo+patClone.FName; } if(PatCur.Birthdate!=PatOld.Birthdate) { patClone.Birthdate=PatCur.Birthdate; changeMsg+="\r\n"+patCloneOld.Birthdate.ToShortDateString()+strChngTo+patClone.Birthdate.ToShortDateString(); } Patients.Update(patClone,patCloneOld); MessageBox.Show(changeMsg); } } } //If there is an existing HL7 def enabled, send an ADT message if there is an outbound ADT message defined if(HL7Defs.IsExistingHL7Enabled()) { //new patients get the A04 ADT, updating existing patients we send an A08 MessageHL7 messageHL7=null; if(IsNew) { messageHL7=MessageConstructor.GenerateADT(PatCur,Patients.GetPat(PatCur.Guarantor),EventTypeHL7.A04); } else { messageHL7=MessageConstructor.GenerateADT(PatCur,Patients.GetPat(PatCur.Guarantor),EventTypeHL7.A08); } //Will be null if there is no outbound ADT message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=0; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } DialogResult=DialogResult.OK; }
public static List<HL7Msg> GetOneExisting(HL7Msg hl7Msg) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { return Meth.GetObject<List<HL7Msg>>(MethodBase.GetCurrentMethod(),hl7Msg); } string command="SELECT * FROM hl7msg WHERE MsgText='"+POut.String(hl7Msg.MsgText)+"' "+DbHelper.LimitAnd(1); return Crud.HL7MsgCrud.SelectMany(command);//Just 0 or 1 item in list for now. }
///<summary>Called from butOK_Click and butPin_Click</summary> private bool UpdateToDB(){ DateTime dateTimeAskedToArrive=DateTime.MinValue; if((AptOld.AptStatus==ApptStatus.Complete && comboStatus.SelectedIndex!=1) || (AptOld.AptStatus==ApptStatus.Broken && comboStatus.SelectedIndex!=4)) //Un-completing or un-breaking the appt. We must use selectedindex due to AptCur gets updated later UpdateDB() { //If the insurance plans have changed since this appt was completed, warn the user that the historical data will be neutralized. List<PatPlan> listPatPlans=PatPlans.Refresh(pat.PatNum); InsSub sub1=InsSubs.GetSub(PatPlans.GetInsSubNum(listPatPlans,PatPlans.GetOrdinal(PriSecMed.Primary,listPatPlans,PlanList,SubList)),SubList); InsSub sub2=InsSubs.GetSub(PatPlans.GetInsSubNum(listPatPlans,PatPlans.GetOrdinal(PriSecMed.Secondary,listPatPlans,PlanList,SubList)),SubList); if(sub1.PlanNum!=AptCur.InsPlan1 || sub2.PlanNum!=AptCur.InsPlan2) { if(!MsgBox.Show(this,MsgBoxButtons.OKCancel,"The current insurance plans for this patient are different than the plans associated to this appointment. They will be updated to the patient's current insurance plans. Continue?")) { return false; } //Update the ins plans associated to this appointment so that they're the most accurate at this time. AptCur.InsPlan1=sub1.PlanNum; AptCur.InsPlan2=sub2.PlanNum; } } if(textTimeAskedToArrive.Text!=""){ try{ dateTimeAskedToArrive=AptCur.AptDateTime.Date+DateTime.Parse(textTimeAskedToArrive.Text).TimeOfDay; } catch{ MsgBox.Show(this,"Time Asked To Arrive invalid."); return false; } } DateTime dateTimeArrived=AptCur.AptDateTime.Date; if(textTimeArrived.Text!=""){ try{ dateTimeArrived=AptCur.AptDateTime.Date+DateTime.Parse(textTimeArrived.Text).TimeOfDay; } catch{ MsgBox.Show(this,"Time Arrived invalid."); return false; } } DateTime dateTimeSeated=AptCur.AptDateTime.Date; if(textTimeSeated.Text!=""){ try{ dateTimeSeated=AptCur.AptDateTime.Date+DateTime.Parse(textTimeSeated.Text).TimeOfDay; } catch{ MsgBox.Show(this,"Time Seated invalid."); return false; } } DateTime dateTimeDismissed=AptCur.AptDateTime.Date; if(textTimeDismissed.Text!=""){ try{ dateTimeDismissed=AptCur.AptDateTime.Date+DateTime.Parse(textTimeDismissed.Text).TimeOfDay; } catch{ MsgBox.Show(this,"Time Arrived invalid."); return false; } } //This change was just slightly too risky to make to 6.9, so 7.0 only if(AptCur.AptStatus!=ApptStatus.Complete//was not originally complete && AptCur.AptStatus!=ApptStatus.PtNote && AptCur.AptStatus!=ApptStatus.PtNoteCompleted && comboStatus.SelectedIndex==1 //making it complete && AptCur.AptDateTime.Date > DateTime.Today)//and future appt { MsgBox.Show(this,"Not allowed to set complete future appointments."); return false; } string aptPattern=Appointments.ConvertPatternTo5(strBTime.ToString()); //Only run appt overlap check if editing an appt not in unscheduled list and in chart module and eCW program link not enabled. if((IsInChartModule || IsInViewPatAppts) && !Programs.UsingEcwTightOrFullMode() && AptCur.AptStatus!=ApptStatus.UnschedList) { //==Travis 04/06/2015: This call was added on 04/23/2014 and backported to 14.1. It is not storing the return value and does not look to be // doing anything so it has been commented out. //Appointments.RefreshPeriod(AptCur.AptDateTime,AptCur.AptDateTime); List<Appointment> apptList=Appointments.GetForPeriodList(AptCur.AptDateTime,AptCur.AptDateTime); if(DoesOverlap(aptPattern,apptList)) { MsgBox.Show(this,"Appointment is too long and would overlap another appointment. Automatically shortened to fit."); do { aptPattern=aptPattern.Substring(0,aptPattern.Length-1); if(aptPattern.Length==1) { break; } } while(DoesOverlap(aptPattern,apptList)); } } if(AptCur.AptStatus == ApptStatus.Planned) { ; } else if(comboStatus.SelectedIndex==-1) { AptCur.AptStatus=ApptStatus.Scheduled; } else if (AptCur.AptStatus == ApptStatus.PtNote | AptCur.AptStatus == ApptStatus.PtNoteCompleted){ AptCur.AptStatus = (ApptStatus)comboStatus.SelectedIndex + 7; } else { AptCur.AptStatus=(ApptStatus)comboStatus.SelectedIndex+1; } //set procs complete was moved further down //convert from current increment into 5 minute increment //MessageBox.Show(strBTime.ToString()); AptCur.Pattern=aptPattern; if(comboUnschedStatus.SelectedIndex==0){//none AptCur.UnschedStatus=0; } else{ AptCur.UnschedStatus=DefC.Short[(int)DefCat.RecallUnschedStatus][comboUnschedStatus.SelectedIndex-1].DefNum; } if(comboConfirmed.SelectedIndex!=-1){ AptCur.Confirmed=DefC.Short[(int)DefCat.ApptConfirmed][comboConfirmed.SelectedIndex].DefNum; } AptCur.TimeLocked=checkTimeLocked.Checked; AptCur.ColorOverride=butColor.BackColor; AptCur.Note=textNote.Text; if(comboClinic.SelectedIndex==0) {//none AptCur.ClinicNum=0; } else { AptCur.ClinicNum=Clinics.List[comboClinic.SelectedIndex-1].ClinicNum; } //there should always be a non-hidden primary provider for an appt. if(comboProvNum.SelectedIndex==-1) { AptCur.ProvNum=ProviderC.ListShort[0].ProvNum; } else { AptCur.ProvNum=ProviderC.ListShort[comboProvNum.SelectedIndex].ProvNum; } if(comboProvHyg.SelectedIndex==0) {//none AptCur.ProvHyg=0; } else { AptCur.ProvHyg=ProviderC.ListShort[comboProvHyg.SelectedIndex-1].ProvNum; } AptCur.IsHygiene=checkIsHygiene.Checked; if(comboAssistant.SelectedIndex==0) {//none AptCur.Assistant=0; } else { AptCur.Assistant=Employees.ListShort[comboAssistant.SelectedIndex-1].EmployeeNum; } AptCur.IsNewPatient=checkIsNewPatient.Checked; AptCur.DateTimeAskedToArrive=dateTimeAskedToArrive; AptCur.DateTimeArrived=dateTimeArrived; AptCur.DateTimeSeated=dateTimeSeated; AptCur.DateTimeDismissed=dateTimeDismissed; //AptCur.InsPlan1 and InsPlan2 already handled //The ApptProcDescript region is also in FormProcEdit.SaveAndClose() and FormDatabaseMaintenance.butApptProcs_Click() Make any changes there as well. #region ApptProcDescript AptCur.ProcDescript=""; AptCur.ProcsColored=""; for(int i=0;i<gridProc.SelectedIndices.Length;i++) { string procDescOne=""; string procCode=DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["ProcCode"].ToString(); if(i>0){ AptCur.ProcDescript+=", "; } switch(DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["TreatArea"].ToString()) { case "1"://TreatmentArea.Surf: procDescOne+="#"+Tooth.GetToothLabel(DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["ToothNum"].ToString())+"-" +DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["Surf"].ToString()+"-";//""#12-MOD-" break; case "2"://TreatmentArea.Tooth: procDescOne+="#"+Tooth.GetToothLabel(DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["ToothNum"].ToString())+"-";//"#12-" break; default://area 3 or 0 (mouth) break; case "4"://TreatmentArea.Quad: procDescOne+=DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["Surf"].ToString()+"-";//"UL-" break; case "5"://TreatmentArea.Sextant: procDescOne+="S"+DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["Surf"].ToString()+"-";//"S2-" break; case "6"://TreatmentArea.Arch: procDescOne+=DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["Surf"].ToString()+"-";//"U-" break; case "7"://TreatmentArea.ToothRange: //strLine+=table.Rows[j][13].ToString()+" ";//don't show range break; } procDescOne+=DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["AbbrDesc"].ToString(); AptCur.ProcDescript+=procDescOne; //Color and previous date are determined by ProcApptColor object ProcApptColor pac=ProcApptColors.GetMatch(procCode); System.Drawing.Color pColor=System.Drawing.Color.Black; string prevDateString=""; if(pac!=null){ pColor=pac.ColorText; if(pac.ShowPreviousDate) { prevDateString=Procedures.GetRecentProcDateString(AptCur.PatNum,AptCur.AptDateTime,pac.CodeRange); if(prevDateString!="") { prevDateString=" ("+prevDateString+")"; } } } AptCur.ProcsColored+="<span color=\""+pColor.ToArgb().ToString()+"\">"+procDescOne+prevDateString+"</span>"; } #endregion bool isPlanned=AptCur.AptStatus==ApptStatus.Planned; if(comboApptType.SelectedIndex==0) {//0 index = none. AptCur.AppointmentTypeNum=0; } else { AptCur.AppointmentTypeNum=_listAppointmentType[comboApptType.SelectedIndex-1].AppointmentTypeNum; } try { Appointments.Update(AptCur,AptOld); //Appointments.UpdateAttached(AptCur.AptNum,procNums,isPlanned); } catch(ApplicationException ex) { MessageBox.Show(ex.Message); return false; } //if appointment is marked complete and any procedures are not, //then set the remaining procedures complete if(AptCur.AptStatus==ApptStatus.Complete) { bool allProcsComplete=true; for(int i=0;i<gridProc.SelectedIndices.Length;i++){ if(DS.Tables["Procedure"].Rows[gridProc.SelectedIndices[i]]["ProcStatus"].ToString()!="2") {//Complete allProcsComplete=false; break; } } if(!allProcsComplete) { if(!Security.IsAuthorized(Permissions.ProcComplCreate,AptCur.AptDateTime)) { return false; } List <PatPlan> PatPlanList=PatPlans.Refresh(AptCur.PatNum); ProcedureL.SetCompleteInAppt(AptCur,PlanList,PatPlanList,pat.SiteNum,pat.Age,SubList); SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit,pat.PatNum, AptCur.AptDateTime.ToShortDateString()+", "+AptCur.ProcDescript+", Procedures automatically set complete due to appt being set complete",AptCur.AptNum); } } else{ Procedures.SetProvidersInAppointment(AptCur,Procedures.GetProcsForSingle(AptCur.AptNum,false)); } //Do the appointment "break" automation for appointments that were just broken. if(AptCur.AptStatus==ApptStatus.Broken && AptOld.AptStatus!=ApptStatus.Broken) { SecurityLogs.MakeLogEntry(Permissions.AppointmentMove,pat.PatNum,AptCur.ProcDescript+", "+AptCur.AptDateTime.ToString() +", Broken by changing the Status in the Edit Appointment window.",AptCur.AptNum); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S15 - Appt Cancellation event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(pat,fam.GetPatient(pat.Guarantor),EventTypeHL7.S15,AptCur); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=AptCur.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } ProcedureCode procCodeBrokenApt=ProcedureCodes.GetProcCode("D9986"); if(procCodeBrokenApt.CodeNum!=0) {//ADA proc code D9986 exists Procedure procedureCur=new Procedure(); procedureCur.PatNum=pat.PatNum; procedureCur.ProvNum=AptCur.ProvNum; procedureCur.ProcFee=0; procedureCur.CodeNum=procCodeBrokenApt.CodeNum; procedureCur.ProcDate=DateTime.Today; procedureCur.DateEntryC=DateTime.Now; procedureCur.ProcStatus=ProcStat.C; procedureCur.ClinicNum=pat.ClinicNum; procedureCur.Note=Lan.g(this,"Appt BROKEN for ")+AptCur.ProcDescript+" "+AptCur.AptDateTime.ToString(); Procedures.Insert(procedureCur); //Now make a claimproc if the patient has insurance. We do this now for consistency because a claimproc could get created in the future. List<InsSub> listInsSubs=InsSubs.RefreshForFam(Patients.GetFamily(pat.PatNum)); List<InsPlan> listInsPlans=InsPlans.RefreshForSubList(listInsSubs); List<PatPlan> listPatPlans=PatPlans.Refresh(pat.PatNum); List<Benefit> listBenefits=Benefits.Refresh(listPatPlans,listInsSubs); List<ClaimProc> listClaimProcsForProc=ClaimProcs.RefreshForProc(procedureCur.ProcNum); Procedures.ComputeEstimates(procedureCur,pat.PatNum,listClaimProcsForProc,false,listInsPlans,listPatPlans,listBenefits,pat.Age,listInsSubs); FormProcEdit FormP=new FormProcEdit(procedureCur,pat,Patients.GetFamily(pat.PatNum)); FormP.IsNew=false; FormP.ShowDialog(); if(PrefC.GetBool(PrefName.BrokenApptCommLogWithProcedure)) { Commlog CommlogCur=new Commlog(); CommlogCur.PatNum=pat.PatNum; CommlogCur.CommDateTime=DateTime.Now; CommlogCur.CommType=Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note=Lan.g(this,"Appt BROKEN for ")+AptCur.ProcDescript+" "+AptCur.AptDateTime.ToString(); CommlogCur.Mode_=CommItemMode.None; CommlogCur.UserNum=Security.CurUser.UserNum; FormCommItem FormCI=new FormCommItem(CommlogCur); FormCI.IsNew=true; FormCI.ShowDialog(); } } else {//No D9986 present if(PrefC.GetBool(PrefName.BrokenApptCommLogNotAdjustment)) { Commlog CommlogCur=new Commlog(); CommlogCur.PatNum=pat.PatNum; CommlogCur.CommDateTime=DateTime.Now; CommlogCur.CommType=Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note=Lan.g(this,"Appt BROKEN for ")+AptCur.ProcDescript+" "+AptCur.AptDateTime.ToString(); CommlogCur.Mode_=CommItemMode.None; CommlogCur.UserNum=Security.CurUser.UserNum; FormCommItem FormCI=new FormCommItem(CommlogCur); FormCI.IsNew=true; FormCI.ShowDialog(); } else { Adjustment AdjustmentCur=new Adjustment(); AdjustmentCur.DateEntry=DateTime.Today; AdjustmentCur.AdjDate=DateTime.Today; AdjustmentCur.ProcDate=DateTime.Today; AdjustmentCur.ProvNum=AptCur.ProvNum; AdjustmentCur.PatNum=pat.PatNum; AdjustmentCur.AdjType=PrefC.GetLong(PrefName.BrokenAppointmentAdjustmentType); AdjustmentCur.ClinicNum=pat.ClinicNum; FormAdjust FormA=new FormAdjust(pat,AdjustmentCur); FormA.IsNew=true; FormA.ShowDialog(); } } AutomationL.Trigger(AutomationTrigger.BreakAppointment,null,pat.PatNum); } return true; }
private void butDelete_Click(object sender,EventArgs e) { if (AptCur.AptStatus == ApptStatus.PtNote || AptCur.AptStatus == ApptStatus.PtNoteCompleted) { if (!MsgBox.Show(this, true, "Delete Patient Note?")) { return; } if(textNote.Text != "") { if(MessageBox.Show(Commlogs.GetDeleteApptCommlogMessage(textNote.Text,AptCur.AptStatus),"Question...",MessageBoxButtons.YesNo) == DialogResult.Yes) { Commlog CommlogCur = new Commlog(); CommlogCur.PatNum = AptCur.PatNum; CommlogCur.CommDateTime = DateTime.Now; CommlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note = "Deleted Pt NOTE from schedule, saved copy: "; CommlogCur.Note += textNote.Text; CommlogCur.UserNum=Security.CurUser.UserNum; //there is no dialog here because it is just a simple entry Commlogs.Insert(CommlogCur); } } } else {//ordinary appointment if (MessageBox.Show(Lan.g(this, "Delete appointment?"), "", MessageBoxButtons.OKCancel) != DialogResult.OK) { return; } if(textNote.Text != "") { if(MessageBox.Show(Commlogs.GetDeleteApptCommlogMessage(textNote.Text,AptCur.AptStatus),"Question...",MessageBoxButtons.YesNo) == DialogResult.Yes) { Commlog CommlogCur = new Commlog(); CommlogCur.PatNum = AptCur.PatNum; CommlogCur.CommDateTime = DateTime.Now; CommlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note = "Deleted Appt. & saved note: "; if(AptCur.ProcDescript != "") { CommlogCur.Note += AptCur.ProcDescript + ": "; } CommlogCur.Note += textNote.Text; CommlogCur.UserNum=Security.CurUser.UserNum; //there is no dialog here because it is just a simple entry Commlogs.Insert(CommlogCur); } } //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S17 - Appt Deletion event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(pat,fam.GetPatient(pat.Guarantor),EventTypeHL7.S17,AptCur); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=AptCur.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } } Appointments.Delete(AptCur.AptNum); SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit,pat.PatNum, "Delete for date/time: "+AptCur.AptDateTime.ToString(), AptCur.AptNum); if(IsNew){ //The dialog is considered cancelled when a new appointment is immediately deleted. DialogResult=DialogResult.Cancel; } else{ DialogResult=DialogResult.OK; } }
private void butComplete_Click(object sender,EventArgs e) { //This is only used with eCW HL7 interface. if(butComplete.Text=="Finish && Send") { List<Procedure> procs=Procedures.GetProcsForSingle(AptCur.AptNum,false); string duplicateProcs=ProcedureL.ProcsContainDuplicates(procs); if(duplicateProcs!="") { MessageBox.Show(duplicateProcs); return; } ////check to make sure that the appointment and all attached procedures are marked complete as required. //bool procsAreComplete=true; //for(int i=0;i<gridProc.SelectedIndices.Length;i++) { // string procStat=gridProc.Rows[gridProc.SelectedIndices[i]].Cells[0].Text; // if(procStat!="C") { // procsAreComplete=false; // break; // } //} //if(!procsAreComplete) { // MsgBox.Show(this,"The procedures must all have statuses set to complete first."); // return; //} //user can only get this far if aptNum matches visit num previously passed in by eCW. if(!MsgBox.Show(this,MsgBoxButtons.OKCancel,"Send attached procedures to eClinicalWorks and exit?")) { return; } comboStatus.SelectedIndex=1;//Set the appointment status to complete. This will trigger the procedures to be completed in UpdateToDB() as well. if(!UpdateToDB()) { return; } //Send DFT to eCW containing the attached procedures for this appointment in a .pdf file. string pdfDataStr=GenerateProceduresIntoPdf(); if(HL7Defs.IsExistingHL7Enabled()) { //MessageConstructor.GenerateDFT(procs,EventTypeHL7.P03,pat,Patients.GetPat(pat.Guarantor),AptCur.AptNum,"progressnotes",pdfDataStr); MessageHL7 messageHL7=MessageConstructor.GenerateDFT(procs,EventTypeHL7.P03,pat,Patients.GetPat(pat.Guarantor),AptCur.AptNum,"progressnotes",pdfDataStr); if(messageHL7==null) { MsgBox.Show(this,"There is no DFT message type defined for the enabled HL7 definition."); return; } HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=AptCur.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat.PatNum; HL7Msgs.Insert(hl7Msg); } else { Bridges.ECW.SendHL7(AptCur.AptNum,AptCur.ProvNum,pat,pdfDataStr,"progressnotes",false); } CloseOD=true; if(IsNew) { SecurityLogs.MakeLogEntry(Permissions.AppointmentCreate,pat.PatNum, AptCur.AptDateTime.ToString()+", "+AptCur.ProcDescript, AptCur.AptNum); } DialogResult=DialogResult.OK; } else if(butComplete.Text=="Revise") { if(!Security.IsAuthorized(Permissions.EcwAppointmentRevise)) { return; } MsgBox.Show(this,"Any changes that you make will not be sent to eCW. You will also have to make the same changes in eCW."); //revise is only clickable if user has permission butOK.Enabled=true; gridProc.Enabled=true; listQuickAdd.Enabled=true; butAdd.Enabled=true; butDeleteProc.Enabled=true; } }
private void butOK_Click(object sender, System.EventArgs e) { if(comboProvNum.SelectedIndex==-1) { MsgBox.Show(this,"Please select a dentist."); return; } if(!UpdateToDB()){ return; } bool isCreateAppt=false; bool sendHL7=false; if(IsNew) { if(AptCur.AptStatus==ApptStatus.UnschedList && AptCur.AptDateTime==DateTime.MinValue) { //If new appt is being added directly to pinboard //Do nothing. Log will be created when appointment is dragged off the pinboard. } else { SecurityLogs.MakeLogEntry(Permissions.AppointmentCreate,pat.PatNum, AptCur.AptDateTime.ToString()+", "+AptCur.ProcDescript, AptCur.AptNum); sendHL7=true; isCreateAppt=true; } } else { string logEntryMessage=""; if(AptCur.AptStatus==ApptStatus.Complete) { string newCarrierName1=InsPlans.GetCarrierName(AptCur.InsPlan1,PlanList); string newCarrierName2=InsPlans.GetCarrierName(AptCur.InsPlan2,PlanList); string oldCarrierName1=InsPlans.GetCarrierName(AptOld.InsPlan1,PlanList); string oldCarrierName2=InsPlans.GetCarrierName(AptOld.InsPlan2,PlanList); if(AptOld.InsPlan1!=AptCur.InsPlan1) { if(AptCur.InsPlan1==0) { logEntryMessage+="\r\nRemoved "+oldCarrierName1+" for InsPlan1"; } else if(AptOld.InsPlan1==0) { logEntryMessage+="\r\nAdded "+newCarrierName1+" for InsPlan1"; } else { logEntryMessage+="\r\nChanged "+oldCarrierName1+" to "+newCarrierName1+" for InsPlan1"; } } if(AptOld.InsPlan2!=AptCur.InsPlan2) { if(AptCur.InsPlan2==0) { logEntryMessage+="\r\nRemoved "+oldCarrierName2+" for InsPlan2"; } else if(AptOld.InsPlan2==0) { logEntryMessage+="\r\nAdded "+newCarrierName2+" for InsPlan2"; } else { logEntryMessage+="\r\nChanged "+oldCarrierName2+" to "+newCarrierName2+" for InsPlan2"; } } } SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit,pat.PatNum,AptCur.AptDateTime.ToShortDateString()+", "+AptCur.ProcDescript+logEntryMessage,AptCur.AptNum); sendHL7=true; } //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(sendHL7 && HL7Defs.IsExistingHL7Enabled()) { //S14 - Appt Modification event, S12 - New Appt Booking event MessageHL7 messageHL7=null; if(isCreateAppt) { messageHL7=MessageConstructor.GenerateSIU(pat,fam.GetPatient(pat.Guarantor),EventTypeHL7.S12,AptCur); } else { messageHL7=MessageConstructor.GenerateSIU(pat,fam.GetPatient(pat.Guarantor),EventTypeHL7.S14,AptCur); } //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=AptCur.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } List<string> procCodes=new List<string>(); for(int i=0;i<DS.Tables["Procedure"].Rows.Count;i++) { if(DS.Tables["Procedure"].Rows[i]["attached"].ToString()=="0") {//not attached continue; } procCodes.Add(DS.Tables["Procedure"].Rows[i]["ProcCode"].ToString()); } //if(AptOld.AptStatus!=ApptStatus.Complete && AptCur.AptStatus==ApptStatus.Complete) {//user set appt complete //Recalls.SynchScheduledApptFull(AptCur.PatNum); //} //else { //This was causing bugs. For example, when clicking ok on a completed appointment // Recalls.SynchScheduledApptLazy(AptCur.PatNum,AptCur.AptDateTime,procCodes); //moved to closing event //} DialogResult=DialogResult.OK; }
///<summary>Runs in a separate thread</summary> private void OnDataReceived(IAsyncResult asyncResult) { int byteCountReceived=socketIncomingWorker.EndReceive(asyncResult);//blocks until data is recieved. char[] chars=new char[byteCountReceived]; Decoder decoder=Encoding.UTF8.GetDecoder(); decoder.GetChars(dataBufferIncoming,0,byteCountReceived,chars,0);//doesn't necessarily get all bytes from the buffer because buffer could be half full. strbFullMsg.Append(chars);//strbFullMsg might already have partial data //I think we are guaranteed to have received at least one char. bool isFullMsg=false; bool isMalformed=false; if(strbFullMsg.Length==1 && strbFullMsg[0]==MLLP_ENDMSG_CHAR){//the only char in the message is the end char strbFullMsg.Clear();//this must be the very end of a previously processed message. Discard. isFullMsg=false; } //else if(strbFullMsg[0]!=MLLP_START_CHAR) { else if(strbFullMsg.Length>0 && strbFullMsg[0]!=MLLP_START_CHAR) { //Malformed message. isFullMsg=true;//we're going to do this so that the error gets saved in the database further down. isMalformed=true; } else if(strbFullMsg.Length>=3//so that the next two lines won't crash && strbFullMsg[strbFullMsg.Length-1]==MLLP_ENDMSG_CHAR//last char is the endmsg char. && strbFullMsg[strbFullMsg.Length-2]==MLLP_END_CHAR)//the second-to-the-last char is the end char. { //we have a complete message strbFullMsg.Remove(0,1);//strip off the start char strbFullMsg.Remove(strbFullMsg.Length-2,2);//strip off the end chars isFullMsg=true; } else if(strbFullMsg.Length>=2//so that the next line won't crash && strbFullMsg[strbFullMsg.Length-1]==MLLP_END_CHAR)//the last char is the end char. { //we will treat this as a complete message, because the endmsg char is optional. //if the endmsg char gets sent in a subsequent block, the code above will discard it. strbFullMsg.Remove(0,1);//strip off the start char strbFullMsg.Remove(strbFullMsg.Length-1,1);//strip off the end char isFullMsg=true; } else { isFullMsg=false;//this is an incomplete message. Continue to receive more blocks. } //end of big if statement------------------------------------------------- if(!isFullMsg) { dataBufferIncoming=new byte[8];//clear the buffer socketIncomingWorker.BeginReceive(dataBufferIncoming,0,dataBufferIncoming.Length,SocketFlags.None,new AsyncCallback(OnDataReceived),null); return;//get another block } //Prepare to save message to database if malformed and not processed HL7Msg hl7Msg=new HL7Msg(); hl7Msg.MsgText=strbFullMsg.ToString(); strbFullMsg.Clear();//ready for the next message bool isProcessed=true; string messageControlId=""; string ackEvent=""; if(isMalformed){ hl7Msg.HL7Status=HL7MessageStatus.InFailed; hl7Msg.Note="This message is malformed so it was not processed."; HL7Msgs.Insert(hl7Msg); isProcessed=false; } else{ MessageHL7 messageHl7Object=new MessageHL7(hl7Msg.MsgText);//this creates an entire heirarchy of objects. try { MessageParser.Process(messageHl7Object,IsVerboseLogging);//also saves the message to the db messageControlId=messageHl7Object.ControlId; ackEvent=messageHl7Object.AckEvent; } catch(Exception ex) { EventLog.WriteEntry("OpenDentHL7","Error in OnDataRecieved when processing message:\r\n"+ex.Message+"\r\n"+ex.StackTrace,EventLogEntryType.Error); isProcessed=false; } } MessageHL7 hl7Ack=MessageConstructor.GenerateACK(messageControlId,isProcessed,ackEvent); if(hl7Ack==null) { EventLog.WriteEntry("OpenDentHL7","No ACK defined for the enabled HL7 definition or no HL7 definition enabled.",EventLogEntryType.Information); return; } byte[] ackByteOutgoing=Encoding.ASCII.GetBytes(MLLP_START_CHAR+hl7Ack.ToString()+MLLP_END_CHAR+MLLP_ENDMSG_CHAR); if(IsVerboseLogging) { EventLog.WriteEntry("OpenDentHL7","Beginning to send ACK.\r\n"+MLLP_START_CHAR+hl7Ack.ToString()+MLLP_END_CHAR+MLLP_ENDMSG_CHAR,EventLogEntryType.Information); } socketIncomingWorker.Send(ackByteOutgoing);//this is a locking call //eCW uses the same worker socket to send the next message. Without this call to BeginReceive, they would attempt to send again //and the send would fail since we were no longer listening in this thread. eCW would timeout after 30 seconds of waiting for their //acknowledgement, then they would close their end and create a new socket for the next message. With this call, we can accept message //after message without waiting for a new connection. dataBufferIncoming=new byte[8];//clear the buffer socketIncomingWorker.BeginReceive(dataBufferIncoming,0,dataBufferIncoming.Length,SocketFlags.None,new AsyncCallback(OnDataReceived),null); }
private void menuItemSetComplete_Click(object sender,EventArgs e) { //moved down so we can have the date first //if(!Security.IsAuthorized(Permissions.ProcComplCreate)) { // return; //} if(gridProg.SelectedIndices.Length==0) { MsgBox.Show(this,"Please select an item first."); return; } if(checkAudit.Checked) { MsgBox.Show(this,"Not allowed in audit mode."); return; } DataRow row; Appointment apt; //One appointment------------------------------------------------------------------------------------------------------------- if(gridProg.SelectedIndices.Length==1 && ((DataRow)gridProg.Rows[gridProg.SelectedIndices[0]].Tag)["AptNum"].ToString()!="0") { if(!Security.IsAuthorized(Permissions.AppointmentEdit)){ return; } apt=Appointments.GetOneApt(PIn.Long(((DataRow)gridProg.Rows[gridProg.SelectedIndices[0]].Tag)["AptNum"].ToString())); if(apt.AptStatus == ApptStatus.Complete) { MsgBox.Show(this,"Already complete."); return; } if(apt.AptStatus == ApptStatus.PtNote || apt.AptStatus == ApptStatus.PtNoteCompleted || apt.AptStatus == ApptStatus.Planned || apt.AptStatus==ApptStatus.UnschedList) { MsgBox.Show(this,"Not allowed for that status."); return; } if(!Security.IsAuthorized(Permissions.ProcComplCreate,apt.AptDateTime)) { return; } if(apt.AptDateTime.Date>DateTime.Today) { if(!MsgBox.Show(this,MsgBoxButtons.OKCancel,"Appointment is in the future. Set complete anyway?")){ return; } } else if(!MsgBox.Show(this,true,"Set appointment complete?")){ return; } InsSub sub1=InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList,PatPlans.GetOrdinal(PriSecMed.Primary,PatPlanList,PlanList,SubList)),SubList); InsSub sub2=InsSubs.GetSub(PatPlans.GetInsSubNum(PatPlanList,PatPlans.GetOrdinal(PriSecMed.Secondary,PatPlanList,PlanList,SubList)),SubList); Appointments.SetAptStatusComplete(apt.AptNum,sub1.PlanNum,sub2.PlanNum); ProcedureL.SetCompleteInAppt(apt,PlanList,PatPlanList,PatCur.SiteNum,PatCur.Age,SubList);//loops through each proc, also makes completed security logs SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit, apt.PatNum, apt.ProcDescript+", "+apt.AptDateTime.ToString()+", Set Complete", apt.AptNum); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if(HL7Defs.IsExistingHL7Enabled()) { //S14 - Appt Modification event MessageHL7 messageHL7=MessageConstructor.GenerateSIU(PatCur,FamCur.GetPatient(PatCur.Guarantor),EventTypeHL7.S14,apt); //Will be null if there is no outbound SIU message defined, so do nothing if(messageHL7!=null) { HL7Msg hl7Msg=new HL7Msg(); hl7Msg.AptNum=apt.AptNum; hl7Msg.HL7Status=HL7MessageStatus.OutPending;//it will be marked outSent by the HL7 service. hl7Msg.MsgText=messageHL7.ToString(); hl7Msg.PatNum=PatCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this,messageHL7.ToString()); #endif } } Recalls.Synch(PatCur.PatNum); Recalls.SynchScheduledApptFull(PatCur.PatNum); ModuleSelected(PatCur.PatNum); return; } //One task if(gridProg.SelectedIndices.Length==1 && ((DataRow)gridProg.Rows[gridProg.SelectedIndices[0]].Tag)["TaskNum"].ToString()!="0") { if(MsgBox.Show(this,MsgBoxButtons.OKCancel,"The selected task will be marked Done and will affect all users.")) { long taskNum=PIn.Long(((DataRow)gridProg.Rows[gridProg.SelectedIndices[0]].Tag)["TaskNum"].ToString()); Task taskCur=Tasks.GetOne(taskNum); Task taskOld=taskCur.Copy(); taskCur.TaskStatus=TaskStatusEnum.Done;//global even if new status is tracked by user TaskUnreads.DeleteForTask(taskCur.TaskNum);//clear out taskunreads. We have too many tasks to read the done ones. Tasks.Update(taskCur,taskOld); ModuleSelected(PatCur.PatNum); return; } } //Multiple procedures------------------------------------------------------------------------------------------------------ if(!PrefC.GetBool(PrefName.AllowSettingProcsComplete)){ MsgBox.Show(this,"Only single appointments and tasks may be set complete. If you want to be able to set procedures complete, you must turn on that option in Setup | Chart | Chart Preferences."); return; } //check to make sure we don't have non-procedures for(int i=0;i<gridProg.SelectedIndices.Length;i++) { row=(DataRow)gridProg.Rows[gridProg.SelectedIndices[i]].Tag; if(row["ProcNum"].ToString()=="0" || row["ProcCode"].ToString()=="~GRP~") { MsgBox.Show(this,"Only procedures, single appointments, or tasks may be set complete."); return; } } Procedure procCur; Procedure procOld; ProcedureCode procCode; List<ClaimProc> ClaimProcList=ClaimProcs.Refresh(PatCur.PatNum); //this loop is just for security: for(int i=0;i<gridProg.SelectedIndices.Length;i++) { row=(DataRow)gridProg.Rows[gridProg.SelectedIndices[i]].Tag; procCur=Procedures.GetOneProc(PIn.Long(row["ProcNum"].ToString()),true); if(procCur.ProcStatus==ProcStat.C){ continue;//because it will be skipped below anyway } if(procCur.AptNum!=0) {//if attached to an appointment apt=Appointments.GetOneApt(procCur.AptNum); if(apt.AptDateTime.Date > MiscData.GetNowDateTime().Date) { MessageBox.Show(Lan.g(this,"Not allowed because a procedure is attached to a future appointment with a date of ")+apt.AptDateTime.ToShortDateString()); return; } if(!Security.IsAuthorized(Permissions.ProcComplCreate,apt.AptDateTime)) { return; } } else{ if(!Security.IsAuthorized(Permissions.ProcComplCreate,PIn.Date(textDate.Text))) { return; } } } List<string> procCodeList=new List<string>();//for automation for(int i=0;i<gridProg.SelectedIndices.Length;i++) { row=(DataRow)gridProg.Rows[gridProg.SelectedIndices[i]].Tag; apt=null; procCur=Procedures.GetOneProc(PIn.Long(row["ProcNum"].ToString()),true); if(procCur.ProcStatus==ProcStat.C) { continue;//don't allow setting a procedure complete again. Important for security reasons. } procOld=procCur.Copy(); procCode=ProcedureCodes.GetProcCode(procCur.CodeNum); procCodeList.Add(ProcedureCodes.GetStringProcCode(procCur.CodeNum)); if(procOld.ProcStatus!=ProcStat.C) { //if procedure was already complete, then don't add more notes. procCur.Note+=ProcCodeNotes.GetNote(procCur.ProvNum,procCur.CodeNum);//note wasn't complete, so add notes } procCur.DateEntryC=DateTime.Now; if(procCur.AptNum!=0) {//if attached to an appointment apt=Appointments.GetOneApt(procCur.AptNum); procCur.ProcDate=apt.AptDateTime; procCur.ClinicNum=apt.ClinicNum; procCur.PlaceService=Clinics.GetPlaceService(apt.ClinicNum); } else { procCur.ProcDate=PIn.Date(textDate.Text); procCur.PlaceService=(PlaceOfService)PrefC.GetLong(PrefName.DefaultProcedurePlaceService); } procCur.SiteNum=PatCur.SiteNum; Procedures.SetDateFirstVisit(procCur.ProcDate,2,PatCur); if(procCode.PaintType==ToothPaintingType.Extraction) {//if an extraction, then mark previous procs hidden //Procedures.SetHideGraphical(procCur);//might not matter anymore ToothInitials.SetValue(PatCur.PatNum,procCur.ToothNum,ToothInitialType.Missing); } procCur.ProcStatus=ProcStat.C; if(procCur.DiagnosticCode=="") { procCur.DiagnosticCode=PrefC.GetString(PrefName.ICD9DefaultForNewProcs); } if(CultureInfo.CurrentCulture.Name.EndsWith("CA")) {//Canada Procedures.SetCanadianLabFeesCompleteForProc(procCur); } Plugins.HookAddCode(this,"ContrChart.menuItemSetComplete_Click_procLoop",procCur,procOld); Procedures.Update(procCur,procOld); ProcedureL.LogProcComplCreate(PatCur.PatNum,procCur,procCur.ToothNum); //Tried to move it to the business layer, but too complex for now. //Procedures.SetComplete( // ((Procedure)gridProg.Rows[gridProg.SelectedIndices[i]].Tag).ProcNum,PIn.PDate(textDate.Text)); Procedures.ComputeEstimates(procCur,procCur.PatNum,ClaimProcList,false,PlanList,PatPlanList,BenefitList,PatCur.Age,SubList); //Auto insert encounter. Have to run this every time because entries might not all be on the same date or provider. if(procOld.ProcStatus!=ProcStat.C && procCur.ProcStatus==ProcStat.C) { Encounters.InsertDefaultEncounter(procCur.PatNum,procCur.ProvNum,procCur.ProcDate); } } AutomationL.Trigger(AutomationTrigger.CompleteProcedure,procCodeList,PatCur.PatNum); Recalls.Synch(PatCur.PatNum); //if(skipped>0){ // MessageBox.Show(Lan.g(this,".")+"\r\n" // +skipped.ToString()+" "+Lan.g(this,"procedures(s) skipped.")); //} ModuleSelected(PatCur.PatNum); }