source: Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocument.cs@ 853

Last change on this file since 853 was 850, checked in by Sam Habiel, 14 years ago

Updated Source Code for i18n.
Changes in DPatientLetter.cs
Changes in CGSchedLib.cs

File size: 29.1 KB
Line 
1using System;
2using System.Collections;
3using System.Data;
4using System.Data.OleDb;
5using System.Diagnostics;
6using System.Drawing;
7using System.Windows.Forms;
8using IndianHealthService.BMXNet;
9
10namespace IndianHealthService.ClinicalScheduling
11{
12 /// <summary>
13 /// Contains the array of appointments and availabily that make up the document class
14 /// </summary>
15 public class CGDocument : System.Object
16 {
17
18 public CGDocument()
19 {
20 m_appointments = new CGAppointments();
21 m_pAvArray = new ArrayList();
22 m_sResourcesArray = new ArrayList();
23 }
24
25 #region Member Variables
26 public int m_nColumnCount; //todo: this should point to the view's member for column count
27 public int m_nTimeUnits;
28 private string m_sDocName;
29 public ArrayList m_sResourcesArray; //keeps the resources
30 public ScheduleType m_ScheduleType;
31 private DateTime m_dSelectedDate; //Holds the user's selection from the dtpicker
32 private DateTime m_dStartDate; //Beginning date of document data
33 private DateTime m_dEndDate; //Ending date of document data
34 public CGAppointments m_appointments;
35 private ArrayList m_pAvArray;
36 private CGDocumentManager m_DocManager;
37 private DateTime m_dLastRefresh = DateTime.Now;
38
39 #endregion
40
41 #region Properties
42
43 /// <summary>
44 /// Returns the latest refresh time for this document
45 /// </summary>
46 public DateTime LastRefreshed
47 {
48 get
49 {
50 return m_dLastRefresh;
51 }
52 }
53
54 /// <summary>
55 /// The list of Resource names
56 /// </summary>
57 public ArrayList Resources
58 {
59 get
60 {
61 return this.m_sResourcesArray;
62 }
63 set
64 {
65 this.m_sResourcesArray = value;
66 }
67 }
68
69 /// <summary>
70 /// The array of CGAvailabilities that contains appt type and slots
71 /// </summary>
72 public ArrayList AvailabilityArray
73 {
74 get
75 {
76 return this.m_pAvArray;
77 }
78 }
79
80 public CGDocumentManager DocManager
81 {
82 get
83 {
84 return m_DocManager;
85 }
86 set
87 {
88 m_DocManager = value;
89 }
90 }
91
92 /// <summary>
93 /// Contains the hashtable of appointments
94 /// </summary>
95 public CGAppointments Appointments
96 {
97 get
98 {
99 return m_appointments;
100 }
101 }
102
103 /// <summary>
104 /// Holds the date selected by the user in CGView.dateTimePicker1
105 /// </summary>
106 public DateTime SelectedDate
107 {
108 get
109 {
110 return this.m_dSelectedDate;
111 }
112 set
113 {
114 this.m_dSelectedDate = value;
115 bool bRet = false;
116 if (m_sResourcesArray.Count == 1)
117 {
118 bRet = this.WeekNeedsRefresh(1, m_dSelectedDate, out this.m_dStartDate, out this.m_dEndDate);
119 }
120 else
121 {
122 this.m_dStartDate = m_dSelectedDate;
123 this.m_dEndDate = m_dSelectedDate;
124 this.m_dEndDate = this.m_dEndDate.AddHours(23);
125 this.m_dEndDate = this.m_dEndDate.AddMinutes(59);
126 this.m_dEndDate = this.m_dEndDate.AddSeconds(59);
127 }
128
129 bRet = RefreshSchedule();
130 }
131 }
132
133 /// <summary>
134 /// Contains the beginning date of the appointment document
135 /// </summary>
136 public DateTime StartDate
137 {
138 get
139 {
140 return this.m_dStartDate;
141 }
142 }
143
144 public string DocName
145 {
146 get
147 {
148 return this.m_sDocName;
149 }
150 set
151 {
152 this.m_sDocName = value;
153 }
154 }
155
156 #endregion
157
158 #region Methods
159
160 public void UpdateAllViews()
161 {
162 //iterate through all views and call update.
163 Hashtable h = CGDocumentManager.Current.Views;
164
165 CGDocument d;
166 foreach (CGView v in h.Keys)
167 {
168 d = (CGDocument) h[v];
169 if (d == this)
170 {
171 v.UpdateArrays();
172 }
173 }
174
175 }
176
177 /// <summary>
178 /// Update schedule based on info in RPMS
179 /// </summary>
180 private bool RefreshDaysSchedule()
181 {
182 try
183 {
184 string sPatientName;
185 string sPatientID;
186 DateTime dStart;
187 DateTime dEnd;
188 DateTime dCheckIn;
189 DateTime dAuxTime;
190 int nKeyID;
191 string sNote;
192 string sResource;
193 bool bNoShow = false;
194 string sNoShow = "0";
195 string sHRN = "";
196 int nAccessTypeID; //used in autorebook
197 string sWalkIn = "0";
198 bool bWalkIn;
199 CGAppointment pAppointment;
200 CGDocumentManager pApp = CGDocumentManager.Current;
201 DataTable rAppointmentSchedule;
202
203 //Nice to know that it gets set here!!!
204 m_dLastRefresh = DateTime.Now;
205
206 this.m_appointments.ClearAllAppointments();
207
208 // calls RPC to get appointments
209 rAppointmentSchedule = CGSchedLib.CreateAppointmentSchedule(m_DocManager, m_sResourcesArray, this.m_dStartDate, this.m_dEndDate);
210
211 // Datatable dumper into Debug Log (nice to know that this exists)
212 CGSchedLib.OutputArray(rAppointmentSchedule, "rAppointmentSchedule");
213
214
215 foreach (DataRow r in rAppointmentSchedule.Rows)
216 {
217
218 if (r["APPOINTMENTID"].ToString() == "0")
219 {
220 string sMsg = r["NOTE"].ToString();
221 throw new BMXNetException(sMsg);
222 }
223 nKeyID = Convert.ToInt32(r["APPOINTMENTID"].ToString());
224 sResource = r["RESOURCENAME"].ToString();
225 sPatientName =r["PATIENTNAME"].ToString();
226 sPatientID =r["PATIENTID"].ToString();
227 dStart = (DateTime) r["START_TIME"];
228 dEnd = (DateTime) r["END_TIME"];
229 dCheckIn = new DateTime();
230 dAuxTime = new DateTime();
231
232 if (r["CHECKIN"].GetType() != typeof(System.DBNull))
233 dCheckIn = (DateTime) r["CHECKIN"];
234 if (r["AUXTIME"].GetType() != typeof(System.DBNull))
235 dCheckIn = (DateTime) r["AUXTIME"];
236 sNote = r["NOTE"].ToString();
237 sNoShow = r["NOSHOW"].ToString();
238 bNoShow = (sNoShow == "1")?true: false;
239 sHRN = r["HRN"].ToString();
240 nAccessTypeID = (int) r["ACCESSTYPEID"];
241 sWalkIn = r["WALKIN"].ToString();
242 bWalkIn = (sWalkIn == "1")?true: false;
243
244 pAppointment = new CGAppointment();
245 pAppointment.CreateAppointment(dStart, dEnd, sNote, nKeyID, sResource);
246 pAppointment.PatientName = sPatientName;
247 pAppointment.PatientID = Convert.ToInt32(sPatientID);
248 if (dCheckIn.Ticks > 0)
249 pAppointment.CheckInTime = dCheckIn;
250 if (dAuxTime.Ticks > 0)
251 pAppointment.AuxTime = dAuxTime;
252 pAppointment.NoShow = bNoShow;
253 pAppointment.HealthRecordNumber = sHRN;
254 pAppointment.AccessTypeID = nAccessTypeID;
255 pAppointment.WalkIn = bWalkIn;
256 this.m_appointments.AddAppointment(pAppointment);
257
258 }
259
260 return true;
261 }
262 catch(Exception Ex)
263 {
264 Debug.Write("CGDocument.RefreshDaysSchedule error: " + Ex.Message + "\n");
265 return false;
266 }
267 }
268
269
270 public void OnNewDocument()
271 {
272 /*
273 * TEST EXCEPTION -- REMOVE AFTER TESTING
274 */
275 //throw new Exception("Simulated Uncaught Exception");
276 /*
277 * TEST EXCEPTION -- REMOVE AFTER TESTING
278 */
279
280 //Open an empty document
281 m_sResourcesArray.Clear();
282 m_ScheduleType = ScheduleType.Resource;
283
284 //Set initial From and To dates based on current day
285 // DateTime dDate = new DateTime(2001,12,05); //Testing line
286 DateTime dDate = DateTime.Today;
287
288 //smh: Question: Where does bRet get used? It's a useless varaible so far.
289 bool bRet = this.WeekNeedsRefresh(2,dDate, out this.m_dStartDate, out this.m_dEndDate);
290
291 //Create new View
292 CGView view = new CGView();
293 view.InitializeDocView(this,
294 this.DocManager,
295 m_dStartDate,
296 this.Appointments,
297 DocManager.WindowText);
298
299 view.Show();
300 view.SyncTree();
301 view.Activate();
302 this.UpdateAllViews();
303 }
304
305 private void SetDate(DateTime dDate)
306 {
307 bool bRet = false;
308 if (m_ScheduleType == ScheduleType.Resource)
309 {
310 bRet = this.WeekNeedsRefresh(2,dDate, out this.m_dStartDate, out this.m_dEndDate);
311 }
312 else
313 {
314 this.m_dStartDate = dDate;
315 this.m_dEndDate = dDate;
316 this.m_dEndDate = this.m_dEndDate.AddHours(23);
317 this.m_dEndDate = this.m_dEndDate.AddMinutes(59);
318 this.m_dEndDate = this.m_dEndDate.AddSeconds(59);
319 }
320
321 bRet = RefreshSchedule();
322 this.UpdateAllViews();
323 }
324
325 public void RefreshDocument()
326 {
327 bool bRet = RefreshSchedule();
328 this.UpdateAllViews();
329 }
330
331 public void OnOpenDocument()
332 {
333 try
334 {
335 //Create new Document
336 m_ScheduleType = (m_sResourcesArray.Count == 1) ? ScheduleType.Resource: ScheduleType.Clinic;
337 bool bRet = false;
338
339 //Set initial From and To dates based on current day
340 DateTime dDate = DateTime.Today;
341 if (m_ScheduleType == ScheduleType.Resource)
342 {
343 bRet = this.WeekNeedsRefresh(1,dDate, out this.m_dStartDate, out this.m_dEndDate);
344 }
345 else
346 {
347 this.m_dStartDate = dDate;
348 this.m_dEndDate = dDate;
349 this.m_dEndDate = this.m_dEndDate.AddHours(23);
350 this.m_dEndDate = this.m_dEndDate.AddMinutes(59);
351 this.m_dEndDate = this.m_dEndDate.AddSeconds(59);
352 }
353
354 bRet = RefreshSchedule();
355
356 CGView view = null;
357 //If this document already has a view, the use it
358 Hashtable h = CGDocumentManager.Current.Views;
359 CGDocument d;
360 bool bReuseView = false;
361 foreach (CGView v in h.Keys)
362 {
363 d = (CGDocument) h[v];
364 if (d == this)
365 {
366 view = v;
367 bReuseView = true;
368 v.InitializeDocView(this.DocName);
369 break;
370 }
371 }
372
373 //Otherwise, create new View
374 if (bReuseView == false)
375 {
376 view = new CGView();
377
378 view.InitializeDocView(this,
379 this.DocManager,
380 m_dStartDate,
381 this.Appointments,
382 this.DocName);
383
384 view.Show();
385 view.SyncTree();
386
387 }
388 this.UpdateAllViews();
389 }
390 catch (BMXNetException bmxEx)
391 {
392 throw bmxEx;
393 }
394 catch (Exception ex)
395 {
396 throw new BMXNet.BMXNetException("ClinicalScheduling.OnOpenDocument error: " + ex.Message);
397 }
398 }
399
400 private bool RefreshSchedule()
401 {
402 try
403 {
404 bool bRet = this.RefreshAvailabilitySchedule();
405 if (bRet == false)
406 {
407 return bRet;
408 }
409 bRet = this.RefreshDaysSchedule();
410 return bRet;
411 }
412 catch (ApplicationException aex)
413 {
414 Debug.Write("CGDocument.RefreshSchedule Application Error: " + aex.Message + "\n");
415 return false;
416 }
417 catch (Exception ex)
418 {
419 MessageBox.Show("CGDocument.RefreshSchedule error: " + ex.Message + "\n");
420 return false;
421 }
422 }
423
424 private bool RefreshAvailabilitySchedule()
425 {
426 try
427 {
428 if (this.m_DocManager.ConnectInfo.Connected == false)
429 {
430 m_DocManager.ConnectInfo.LoadConnectInfo();
431 }
432 System.IntPtr pHandle = m_DocManager.Handle;
433
434 m_pAvArray.Clear();
435
436 ArrayList saryApptTypes = new ArrayList();
437 int nApptTypeID = 0;
438
439 //Refresh Availability schedules
440 DataTable rAvailabilitySchedule;
441 rAvailabilitySchedule = CGSchedLib.CreateAvailabilitySchedule(m_DocManager, m_sResourcesArray, this.m_dStartDate, this.m_dEndDate, saryApptTypes,/**/ m_ScheduleType, "0");
442 CGSchedLib.OutputArray(rAvailabilitySchedule, "rAvailabilitySchedule");
443
444 //Refresh Type Schedule
445 string sResourceName = "";
446 DataTable rTypeSchedule = new DataTable();;
447 for (int j = 0; j < m_sResourcesArray.Count; j++)
448 {
449 sResourceName = m_sResourcesArray[j].ToString();
450 DataTable dtTemp = CGSchedLib.CreateAssignedTypeSchedule(m_DocManager, sResourceName, this.m_dStartDate, this.m_dEndDate, m_ScheduleType);
451 CGSchedLib.OutputArray(dtTemp, "dtTemp");
452 if (j == 0)
453 {
454 rTypeSchedule = dtTemp;
455 }
456 else
457 {
458 rTypeSchedule = CGSchedLib.UnionBlocks(rTypeSchedule, dtTemp);
459 }
460 }
461 CGSchedLib.OutputArray(rTypeSchedule, "rTypeSchedule");
462
463 DateTime dStart;
464 DateTime dEnd;
465 DateTime dTypeStart;
466 DateTime dTypeEnd;
467 int nSlots;
468 Rectangle crRectA = new Rectangle(0,0,1,0);
469 Rectangle crRectB= new Rectangle(0,0,1,0);
470 bool bIsect;
471 string sResourceList;
472 string sAccessRuleList;
473
474
475 foreach (DataRow rTemp in rAvailabilitySchedule.Rows)
476 {
477 //get StartTime, EndTime and Slots
478 dStart = (DateTime) rTemp["START_TIME"];
479 dEnd = (DateTime) rTemp["END_TIME"];
480
481 //TODO: Fix this slots datatype problem
482 string sSlots = rTemp["SLOTS"].ToString();
483 nSlots = Convert.ToInt16(sSlots);
484
485 sResourceList = rTemp["RESOURCE"].ToString();
486 sAccessRuleList = rTemp["ACCESS_TYPE"].ToString();
487
488 string sNote = rTemp["NOTE"].ToString();
489
490 if ((nSlots < -1000)||(sAccessRuleList == ""))
491 {
492 nApptTypeID = 0;
493 }
494 else
495 {
496 foreach (DataRow rType in rTypeSchedule.Rows)
497 {
498
499 dTypeStart = (DateTime) rType["StartTime"];
500 dTypeEnd = (DateTime) rType["EndTime"];
501 //if start & end times overlap, then
502 string sTypeResource = rType["ResourceName"].ToString();
503 if ((dTypeStart.DayOfYear == dStart.DayOfYear) && (sResourceList == sTypeResource))
504 {
505 crRectA.Y = GetTotalMinutes(dStart);
506 crRectA.Height = GetTotalMinutes(dEnd) - crRectA.Top;
507 crRectB.Y = GetTotalMinutes(dTypeStart);
508 crRectB.Height = GetTotalMinutes(dTypeEnd) - crRectB.Top;
509 bIsect = crRectA.IntersectsWith(crRectB);
510 if (bIsect == true)
511 {
512 //TODO: This code:
513 // nApptTypeID = (int) rType["AppointmentTypeID"];
514 //Causes this exception:
515 //Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
516 string sTemp = rType["AppointmentTypeID"].ToString();
517 nApptTypeID = Convert.ToInt16(sTemp);
518 break;
519 }
520 }
521 }//end foreach datarow rType
522 }
523
524 AddAvailability(dStart, dEnd, nApptTypeID, nSlots, false, sResourceList, sAccessRuleList, sNote);
525 }//end foreach datarow rTemp
526
527 return true;
528 }
529 catch (Exception ex)
530 {
531 Debug.Write("CGDocument.RefreshAvailabilitySchedule error: " + ex.Message + "\n");
532 return false;
533 }
534 }
535
536 private int GetTotalMinutes(DateTime dDate)
537 {
538 return ((dDate.Hour * 60) + dDate.Minute);
539 }
540
541 public int AddAvailability(DateTime StartTime, DateTime EndTime, int nType, int nSlots, bool UpdateView, string sResourceList, string sAccessRuleList, string sNote)
542 {
543 //adds it to the object array
544 //Returns the index in the array
545
546 CGAvailability pNewAv = new CGAvailability();
547 pNewAv.Create(StartTime, EndTime, nType, nSlots, sResourceList, sAccessRuleList);
548
549 pNewAv.Note = sNote;
550
551 //Look up the color and type name using the AppointmentTypes datatable
552 DataTable dtType = this.m_DocManager.GlobalDataSet.Tables["AccessTypes"];
553 DataRow dRow = dtType.Rows.Find(nType.ToString());
554 if (dRow != null)
555 {
556 string sColor = dRow["DISPLAY_COLOR"].ToString();
557 pNewAv.DisplayColor = sColor;
558 string sTemp = dRow["RED"].ToString();
559 sTemp = (sTemp == "")?"0":sTemp;
560 int nRed = Convert.ToInt16(sTemp);
561 pNewAv.Red = nRed;
562 sTemp = dRow["GREEN"].ToString();
563 sTemp = (sTemp == "")?"0":sTemp;
564 int nGreen = Convert.ToInt16(sTemp);
565 pNewAv.Green = nGreen;
566 sTemp = dRow["BLUE"].ToString();
567 sTemp = (sTemp == "")?"0":sTemp;
568 int nBlue = Convert.ToInt16(sTemp);
569 pNewAv.Blue = nBlue;
570
571 string sName = dRow["ACCESS_TYPE_NAME"].ToString();
572 pNewAv.AccessTypeName = sName;
573 }
574
575 int nIndex = 0;
576 nIndex = m_pAvArray.Add(pNewAv);
577 if (UpdateView == true)
578 {
579 this.UpdateAllViews();
580 }
581 return nIndex;
582 }
583
584
585 public void AddResource(string sResource)
586 {
587 //TODO: Test that resource is not currently in list, that it IS a resource, etc
588 this.m_sResourcesArray.Add(sResource);
589 this.UpdateAllViews();
590 }
591
592 public void ClearResources()
593 {
594 this.m_sResourcesArray.Clear();
595 }
596
597 public int SlotsAvailable(DateTime dSelStart, DateTime dSelEnd, string sResource, out string sAccessType, out string sAvailabilityMessage)
598 {
599 sAccessType = "";
600 sAvailabilityMessage = "";
601 DateTime dStart;
602 DateTime dEnd;
603 int nAvailableSlots = 999;
604 int nSlots = 0;
605 int i = 0;
606 CGAvailability pAv;
607 Rectangle crRectA = new Rectangle(0,0,1,0);
608 Rectangle crRectB = new Rectangle(0,0,1,0);
609 bool bIsect;
610 crRectB.Y = GetTotalMinutes(dSelStart);
611 crRectB.Height = GetTotalMinutes(dSelEnd)- crRectB.Y;
612
613 // //loop thru m_pAvArray
614 // //Compare the start time and end time of eachblock
615 while (i < m_pAvArray.Count)
616 {
617 pAv = (CGAvailability) m_pAvArray[i];
618 dStart = pAv.StartTime;
619 dEnd = pAv.EndTime;
620 if ((sResource == pAv.ResourceList) &&
621 ((dSelStart.Date == dStart.Date) || (dSelStart.Date == dEnd.Date)))
622 {
623 crRectA.Y = (dStart.Date < dSelStart.Date) ? 0 : GetTotalMinutes(dStart);
624 crRectA.Height = (dEnd.Date > dSelEnd.Date) ? 1440 : GetTotalMinutes(dEnd);
625 crRectA.Height = crRectA.Height - crRectA.Y;
626 bIsect = crRectA.IntersectsWith(crRectB);
627 if (bIsect != false)
628 {
629 nSlots = pAv.Slots;
630 if (nSlots < 1)
631 {
632 nAvailableSlots = 0;
633 break;
634 }
635 if (nSlots < nAvailableSlots)
636 {
637 nAvailableSlots = nSlots;
638 sAccessType = pAv.AccessTypeName;
639 sAvailabilityMessage = pAv.Note;
640
641 }
642 }
643 }
644 i++;
645 }
646 if (nAvailableSlots == 999)
647 {
648 nAvailableSlots = 0;
649 }
650 return nAvailableSlots;
651 }
652
653 /// <summary>
654 /// Given a selected date,
655 /// Calculates StartDay and End Day and returns them in output params.
656 /// nWeeks == number of Weeks to display
657 /// nColumnCount is number of days displayed per week. If 5 columns, begin on
658 /// Monday, if 7 Columns, begin on Sunday
659 ///
660 /// Returns TRUE if the document's data needs refreshing based on
661 /// this newly selected date.
662 /// </summary>
663 public bool WeekNeedsRefresh(int nWeeks, DateTime SelectedDate,
664 out DateTime WeekStartDay, out DateTime WeekEndDay)
665 {
666 DateTime OldStartDay = m_dStartDate;
667 DateTime OldEndDay = m_dEndDate;
668 int nWeekDay = (int) SelectedDate.DayOfWeek; //0 == Sunday
669
670 int nOff = 1;
671 TimeSpan ts = new TimeSpan(nWeekDay - nOff,0,0,0); //d,h,m,s
672
673 if (m_nColumnCount == 1)
674 {
675 ts = new TimeSpan(0,23,59,59);
676 WeekStartDay = SelectedDate;
677 }
678 else
679 {
680 WeekStartDay = SelectedDate - ts;
681 if (m_nColumnCount == 7)
682 {
683 ts = new TimeSpan(1,0,0,0);
684 WeekStartDay -= ts;
685 }
686 int nEnd = (m_nColumnCount == 7) ? 1 : 3;
687 ts = new TimeSpan((7* nWeeks) - nEnd, 23, 59,59);
688 }
689 WeekEndDay = WeekStartDay + ts;
690 bool bRet = (( WeekStartDay.Date != OldStartDay.Date) || (WeekEndDay.Date != OldEndDay.Date));
691 return bRet;
692 }
693
694 /// <summary>
695 /// Calls RPMS to create appointment then
696 /// adds appointment to the m_appointments collection
697 /// Returns the IEN of the appointment in the RPMS BSDX APPOINTMENT file.
698 /// </summary>
699 /// <param name="rApptInfo"></param>
700 /// <returns></returns>
701 public int CreateAppointment(CGAppointment rApptInfo)
702 {
703 return CreateAppointment(rApptInfo, false);
704 }
705
706 /// <summary>
707 /// Use this overload to create a walkin appointment
708 /// </summary>
709 /// <param name="rApptInfo"></param>
710 /// <param name="bWalkin"></param>
711 /// <returns></returns>
712 public int CreateAppointment(CGAppointment rApptInfo, bool bWalkin)
713 {
714 string sStart;
715 string sEnd;
716 string sPatID;
717 string sResource;
718 string sNote;
719 string sLen;
720 string sApptID;
721
722 sStart = rApptInfo.StartTime.ToString("M-d-yyyy@HH:mm");
723 sEnd = rApptInfo.EndTime.ToString("M-d-yyyy@HH:mm");
724 TimeSpan sp = rApptInfo.EndTime - rApptInfo.StartTime;
725 sLen = sp.TotalMinutes.ToString();
726 sPatID = rApptInfo.PatientID.ToString();
727 sNote = rApptInfo.Note;
728 sResource = rApptInfo.Resource;
729 if (bWalkin == true)
730 {
731 sApptID = "WALKIN";
732 }
733 else
734 {
735 sApptID = rApptInfo.AccessTypeID.ToString();
736 }
737
738 CGAppointment aCopy = new CGAppointment();
739 aCopy.CreateAppointment(rApptInfo.StartTime, rApptInfo.EndTime, sNote, 0, sResource);
740 aCopy.PatientID = rApptInfo.PatientID;
741 aCopy.PatientName = rApptInfo.PatientName;
742 aCopy.HealthRecordNumber = rApptInfo.HealthRecordNumber;
743 aCopy.AccessTypeID = rApptInfo.AccessTypeID;
744
745 string sSql = "BSDX ADD NEW APPOINTMENT^" + sStart + "^" + sEnd + "^" + sPatID + "^" + sResource + "^" + sLen + "^" + sNote + "^" + sApptID ;
746 System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "NewAppointment");
747 int nApptID;
748
749 Debug.Assert(dtAppt.Rows.Count == 1);
750 DataRow r = dtAppt.Rows[0];
751 nApptID =Convert.ToInt32(r["APPOINTMENTID"]);
752 string sErrorID;
753 sErrorID = r["ERRORID"].ToString();
754 if ((sErrorID != "")||(nApptID < 1))
755 throw new Exception(sErrorID);
756 aCopy.AppointmentKey = nApptID;
757 this.m_appointments.AddAppointment(aCopy);
758
759 bool bRet = RefreshAvailabilitySchedule();
760
761 UpdateAllViews();
762
763 return nApptID;
764 }
765
766 public void EditAppointment(CGAppointment pAppt, string sNote)
767 {
768 try
769 {
770 int nApptID = pAppt.AppointmentKey;
771 string sSql = "BSDX EDIT APPOINTMENT^" + nApptID.ToString() + "^" + sNote;
772
773 System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "EditAppointment");
774
775 Debug.Assert(dtAppt.Rows.Count == 1);
776 DataRow r = dtAppt.Rows[0];
777 string sErrorID = r["ERRORID"].ToString();
778 if (sErrorID == "-1")
779 pAppt.Note = sNote;
780
781 if (this.m_appointments.AppointmentTable.ContainsKey(nApptID))
782 {
783 bool bRet = RefreshAvailabilitySchedule();
784 UpdateAllViews();
785 }
786 }
787 catch (Exception ex)
788 {
789 Debug.Write("CGDocument.EditAppointment Failed: " + ex.Message);
790 }
791 }
792
793 public void CheckInAppointment(int nApptID, DateTime dCheckIn,
794 string ClinicStopIEN,
795 string ProviderIEN,
796 string PrintRouteSlip,
797 string PCCClinicIEN,
798 string PCCFormIEN,
799 string PCCOutGuide
800 )
801 {
802 string sCheckIn = dCheckIn.ToString("M-d-yyyy@HH:mm");
803
804 string sSql = "BSDX CHECKIN APPOINTMENT^" + nApptID.ToString() + "^" + sCheckIn + "^";
805 sSql += ClinicStopIEN + "^" + ProviderIEN + "^" + PrintRouteSlip + "^";
806 sSql += PCCClinicIEN + "^" + PCCFormIEN + "^" + PCCOutGuide;
807
808 System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "CheckInAppointment");
809
810 Debug.Assert(dtAppt.Rows.Count == 1);
811 DataRow r = dtAppt.Rows[0];
812 string sErrorID = r["ERRORID"].ToString();
813
814 if (this.m_appointments.AppointmentTable.ContainsKey(nApptID))
815 {
816 bool bRet = RefreshSchedule();
817 UpdateAllViews();
818 }
819 }
820
821 public string DeleteAppointment(int nApptID)
822 {
823 return DeleteAppointment(nApptID, true, 0, "");
824 }
825
826 public string DeleteAppointment(int nApptID, bool bClinicCancelled, int nReason, string sRemarks)
827 {
828 //Returns "" if deletion successful
829 //Otherwise, returns reason for failure
830
831 string sClinicCancelled = (bClinicCancelled == true)?"C":"PC";
832 string sReasonID = nReason.ToString();
833 string sSql = "BSDX CANCEL APPOINTMENT^" + nApptID.ToString();
834 sSql += "^" + sClinicCancelled;
835 sSql += "^" + sReasonID;
836 sSql += "^" + sRemarks;
837 DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "DeleteAppointment");
838
839 Debug.Assert(dtAppt.Rows.Count == 1);
840 DataRow r = dtAppt.Rows[0];
841 string sErrorID = r["ERRORID"].ToString();
842 if (sErrorID != "")
843 return sErrorID;
844
845 if (this.m_appointments.AppointmentTable.ContainsKey(nApptID))
846 {
847 this.m_appointments.RemoveAppointment(nApptID);
848 bool bRet = RefreshAvailabilitySchedule();
849 UpdateAllViews();
850 }
851 return "";
852 }
853
854 public string AutoRebook(CGAppointment a, int nSearchType, int nMinimumDays, int nMaximumDays, out CGAppointment aRebook)
855 {
856 //If successful Returns "1" and new start date and time returned in aRebook
857 //Otherwise, returns error message
858
859 CGAppointment aCopy = new CGAppointment();
860 aCopy.CreateAppointment(a.StartTime, a.EndTime, a.Note, 0, a.Resource);
861 aCopy.PatientID = a.PatientID;
862 aCopy.PatientName = a.PatientName;
863 aCopy.HealthRecordNumber = a.HealthRecordNumber;
864 aCopy.AccessTypeID = a.AccessTypeID;
865 aRebook = aCopy;
866
867 //Determine Rebook access type
868 //nSearchType = -1: use current, -2: use any non-zero type, >0 use this access type id
869 int nAVType = 0;
870
871 switch (nSearchType)
872 {
873 case -1:
874 nAVType = a.AccessTypeID;
875 break;
876 case -2:
877 nAVType = 0;
878 break;
879 default:
880 nAVType = nSearchType;
881 break;
882 }
883
884 int nSlots = 0;
885 string sSlots = "";
886 int nAccessTypeID; //To compare with nAVType
887
888 DateTime dResult = new DateTime(); //StartTime of access block to autorebook into
889
890 //Next two are empty, but needed to pass to CreateAvailabilitySchedule
891 ArrayList alAccessTypes = new ArrayList();
892 string sSearchInfo = "";
893
894 //Find the StartTime of first availability block of this type for this clinic
895 //between nMinimumDays and nMaximumDays
896
897 string sAVStart = a.StartTime.AddDays(nMinimumDays).ToString("M/d/yyyy@H:mm");
898
899 //dtAVEnd is the last day to search
900 DateTime dtAVEnd = a.StartTime.AddDays(nMinimumDays + nMaximumDays);
901 string sAVEnd = dtAVEnd.ToString("M/d/yyyy@H:mm");
902
903 //Increment start day to search a week (or so) at a time
904 //30 is a test increment. Need to test different values for performance
905 int nIncrement = (nMaximumDays < 30)?nMaximumDays:30;
906
907 //nCount and nCountEnd are the 'moving' counters
908 //that I add to start and end to get the bracket
909 //At the beginning of the DO loop, nCount and nCountEnd are already set
910 bool bFinished = false;
911 bool bFound = false;
912
913 DateTime dStart = a.StartTime.AddDays(nMinimumDays);
914 DateTime dEnd = dStart.AddDays(nIncrement);
915 do
916 {
917 string sSql = "BSDX REBOOK NEXT BLOCK^" + dStart.ToString("M/d/yyyy@H:mm")+ "^" + a.Resource + "^" + nAVType.ToString();
918 DataTable dtNextBlock = this.DocManager.RPMSDataTable(sSql, "NextBlock");
919 Debug.Assert(dtNextBlock.Rows.Count == 1);
920 DataRow drNextBlockRow = dtNextBlock.Rows[0];
921
922 object oNextBlock;
923 oNextBlock = drNextBlockRow["NEXTBLOCK"];
924 if (oNextBlock.GetType() == typeof(System.DBNull))
925 break;
926 DateTime dNextBlock = (DateTime) drNextBlockRow["NEXTBLOCK"];
927 if (dNextBlock > dtAVEnd)
928 {
929 break;
930 }
931
932 dStart = dNextBlock;
933 dEnd = dStart.AddDays(nIncrement);
934 if (dEnd > dtAVEnd)
935 dEnd = dtAVEnd;
936
937 DataTable dtResult = CGSchedLib.CreateAvailabilitySchedule(m_DocManager, this.Resources, dStart, dEnd, alAccessTypes, ScheduleType.Resource, sSearchInfo);
938 //Loop thru dtResult looking for a slot having the required availability type.
939 //If found, set bFinished = true;
940 foreach (DataRow dr in dtResult.Rows)
941 {
942
943 sSlots = dr["SLOTS"].ToString();
944 if (sSlots == "")
945 sSlots = "0";
946 nSlots = Convert.ToInt16(sSlots);
947 if (nSlots > 0)
948 {
949 nAccessTypeID = 0; //holds the access type id of the availability block
950 if (dr["ACCESS_TYPE"].ToString() != "")
951 nAccessTypeID =Convert.ToInt16(dr["ACCESS_TYPE"].ToString());
952 if ((nSearchType == -2) && (nAccessTypeID > 0)) //Match on any non-zero type
953 {
954 bFinished = true;
955 bFound = true;
956 dResult = (DateTime) dr["START_TIME"];
957 break;
958 }
959 if (nAccessTypeID == nAVType)
960 {
961 bFinished = true;
962 bFound = true;
963 dResult = (DateTime) dr["START_TIME"];
964 break;
965 }
966 }
967 }
968 dStart = dEnd.AddDays(1);
969 dEnd = dStart.AddDays(nIncrement);
970 if (dEnd > dtAVEnd)
971 dEnd = dtAVEnd;
972 } while (bFinished == false);
973
974 if (bFound == true)
975 {
976 aCopy.StartTime = dResult;
977 aCopy.EndTime = dResult.AddMinutes(a.Duration);
978 //Create the appointment
979 //Set the AUTOREBOOKED flag
980 //and store the "AutoRebooked To DateTime"
981 //in each autorebooked appointment
982 this.CreateAppointment(aCopy);
983 SetAutoRebook(a, dResult);
984 return "1";
985 }
986 else
987 {
988 return "0";
989 }
990 }
991
992 private void SetAutoRebook(CGAppointment a, DateTime dtRebookedTo)
993 {
994 string sApptKey = a.AppointmentKey.ToString();
995 string sRebookedTo = dtRebookedTo.ToString("M/d/yyyy@HH:mm");
996 string sSql = "BSDX REBOOK SET^" + sApptKey + "^" + sRebookedTo;
997 System.Data.DataTable dtRebook = m_DocManager.RPMSDataTable(sSql, "AutoRebook");
998
999 }
1000
1001 public string AppointmentNoShow(int nApptID, bool bNoShow)
1002 {
1003 /*
1004 * BSDX NOSHOW RPC Returns 1 in ERRORID if successfully sets NOSHOW flag in BSDX APPOINTMENT and, if applicable, File 2
1005 *Otherwise, returns 0 for failure and errormessage in ERRORTXT
1006 *THIS routine returns "" if success or the message in ERRORTEXT if failed
1007 *Exceptions should be caught by caller
1008 *
1009 */
1010
1011 string sTest = bNoShow.ToString();
1012 string sNoShow = (bNoShow == true)?"1":"0";
1013 string sSql = "BSDX NOSHOW^" + nApptID.ToString();
1014 sSql += "^";
1015 sSql += sNoShow;
1016
1017 DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "AppointmentNoShow");
1018
1019 Debug.Assert(dtAppt.Rows.Count == 1);
1020 DataRow r = dtAppt.Rows[0];
1021 string sErrorID = r["ERRORID"].ToString();
1022 if (sErrorID != "1")
1023 {
1024 return r["ERRORTEXT"].ToString();
1025 }
1026
1027 bool bRet = RefreshSchedule();
1028
1029 return sErrorID;
1030 }
1031
1032 #endregion Methods
1033
1034 }//End class
1035}//End namespace
Note: See TracBrowser for help on using the repository browser.