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

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

StartDate for CGAVView, 1st try.
CGDocument uses StartDate from Current thread locale rather than current culture.

File size: 29.9 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.
658 /// If 5 columns, begin on Second Day of Week
659 /// If 7 Columns, begin on First Day of Week
660 /// (this is a change from the hardcoded behavior for US-based calendars)
661 ///
662 /// Returns TRUE if the document's data needs refreshing based on
663 /// this newly selected date.
664 /// </summary>
665 public bool WeekNeedsRefresh(int nWeeks, DateTime SelectedDate,
666 out DateTime WeekStartDay, out DateTime WeekEndDay)
667 {
668 DateTime OldStartDay = m_dStartDate;
669 DateTime OldEndDay = m_dEndDate;
670 // Week start based on thread locale
671 int nStartWeekDay = (int)System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
672 int nWeekDay = (int) SelectedDate.DayOfWeek; //0 == Sunday
673
674 // this offset gets approrpriate day based on locale.
675 int nOff = (nStartWeekDay + 1) % 7;
676 TimeSpan ts = new TimeSpan(nWeekDay - nOff,0,0,0); //d,h,m,s
677
678 if (m_nColumnCount == 1)
679 {
680 ts = new TimeSpan(0,23,59,59);
681 WeekStartDay = SelectedDate;
682 }
683 else
684 {
685 WeekStartDay = SelectedDate - ts;
686 if (m_nColumnCount == 7)
687 {
688 ts = new TimeSpan(1,0,0,0);
689 WeekStartDay -= ts;
690 }
691 int nEnd = (m_nColumnCount == 7) ? 1 : 3;
692 ts = new TimeSpan((7* nWeeks) - nEnd, 23, 59,59);
693 }
694 WeekEndDay = WeekStartDay + ts;
695 bool bRet = (( WeekStartDay.Date != OldStartDay.Date) || (WeekEndDay.Date != OldEndDay.Date));
696 return bRet;
697 }
698
699 /// <summary>
700 /// Calls RPMS to create appointment then
701 /// adds appointment to the m_appointments collection
702 /// Returns the IEN of the appointment in the RPMS BSDX APPOINTMENT file.
703 /// </summary>
704 /// <param name="rApptInfo"></param>
705 /// <returns></returns>
706 public int CreateAppointment(CGAppointment rApptInfo)
707 {
708 return CreateAppointment(rApptInfo, false);
709 }
710
711 /// <summary>
712 /// Use this overload to create a walkin appointment
713 /// </summary>
714 /// <param name="rApptInfo"></param>
715 /// <param name="bWalkin"></param>
716 /// <returns></returns>
717 public int CreateAppointment(CGAppointment rApptInfo, bool bWalkin)
718 {
719 string sStart;
720 string sEnd;
721 string sPatID;
722 string sResource;
723 string sNote;
724 string sLen;
725 string sApptID;
726
727 //sStart = rApptInfo.StartTime.ToString("M-d-yyyy@HH:mm");
728 //sEnd = rApptInfo.EndTime.ToString("M-d-yyyy@HH:mm");
729
730 // i18n code -- Use culture neutral FMDates
731 sStart = FMDateTime.Create(rApptInfo.StartTime).FMDateString;
732 sEnd = FMDateTime.Create(rApptInfo.EndTime).FMDateString;
733
734 TimeSpan sp = rApptInfo.EndTime - rApptInfo.StartTime;
735 sLen = sp.TotalMinutes.ToString();
736 sPatID = rApptInfo.PatientID.ToString();
737 sNote = rApptInfo.Note;
738 sResource = rApptInfo.Resource;
739 if (bWalkin == true)
740 {
741 sApptID = "WALKIN";
742 }
743 else
744 {
745 sApptID = rApptInfo.AccessTypeID.ToString();
746 }
747
748 CGAppointment aCopy = new CGAppointment();
749 aCopy.CreateAppointment(rApptInfo.StartTime, rApptInfo.EndTime, sNote, 0, sResource);
750 aCopy.PatientID = rApptInfo.PatientID;
751 aCopy.PatientName = rApptInfo.PatientName;
752 aCopy.HealthRecordNumber = rApptInfo.HealthRecordNumber;
753 aCopy.AccessTypeID = rApptInfo.AccessTypeID;
754
755 string sSql = "BSDX ADD NEW APPOINTMENT^" + sStart + "^" + sEnd + "^" + sPatID + "^" + sResource + "^" + sLen + "^" + sNote + "^" + sApptID ;
756 System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "NewAppointment");
757 int nApptID;
758
759 Debug.Assert(dtAppt.Rows.Count == 1);
760 DataRow r = dtAppt.Rows[0];
761 nApptID =Convert.ToInt32(r["APPOINTMENTID"]);
762 string sErrorID;
763 sErrorID = r["ERRORID"].ToString();
764 if ((sErrorID != "")||(nApptID < 1))
765 throw new Exception(sErrorID);
766 aCopy.AppointmentKey = nApptID;
767 this.m_appointments.AddAppointment(aCopy);
768
769 bool bRet = RefreshAvailabilitySchedule();
770
771 UpdateAllViews();
772
773 return nApptID;
774 }
775
776 public void EditAppointment(CGAppointment pAppt, string sNote)
777 {
778 try
779 {
780 int nApptID = pAppt.AppointmentKey;
781 string sSql = "BSDX EDIT APPOINTMENT^" + nApptID.ToString() + "^" + sNote;
782
783 System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "EditAppointment");
784
785 Debug.Assert(dtAppt.Rows.Count == 1);
786 DataRow r = dtAppt.Rows[0];
787 string sErrorID = r["ERRORID"].ToString();
788 if (sErrorID == "-1")
789 pAppt.Note = sNote;
790
791 if (this.m_appointments.AppointmentTable.ContainsKey(nApptID))
792 {
793 bool bRet = RefreshAvailabilitySchedule();
794 UpdateAllViews();
795 }
796 }
797 catch (Exception ex)
798 {
799 Debug.Write("CGDocument.EditAppointment Failed: " + ex.Message);
800 }
801 }
802
803 public void CheckInAppointment(int nApptID, DateTime dCheckIn,
804 string ClinicStopIEN,
805 string ProviderIEN,
806 string PrintRouteSlip,
807 string PCCClinicIEN,
808 string PCCFormIEN,
809 string PCCOutGuide
810 )
811 {
812 string sCheckIn = dCheckIn.ToString("M-d-yyyy@HH:mm");
813
814 string sSql = "BSDX CHECKIN APPOINTMENT^" + nApptID.ToString() + "^" + sCheckIn + "^";
815 sSql += ClinicStopIEN + "^" + ProviderIEN + "^" + PrintRouteSlip + "^";
816 sSql += PCCClinicIEN + "^" + PCCFormIEN + "^" + PCCOutGuide;
817
818 System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "CheckInAppointment");
819
820 Debug.Assert(dtAppt.Rows.Count == 1);
821 DataRow r = dtAppt.Rows[0];
822 string sErrorID = r["ERRORID"].ToString();
823
824 if (this.m_appointments.AppointmentTable.ContainsKey(nApptID))
825 {
826 bool bRet = RefreshSchedule();
827 UpdateAllViews();
828 }
829 }
830
831 public string DeleteAppointment(int nApptID)
832 {
833 return DeleteAppointment(nApptID, true, 0, "");
834 }
835
836 public string DeleteAppointment(int nApptID, bool bClinicCancelled, int nReason, string sRemarks)
837 {
838 //Returns "" if deletion successful
839 //Otherwise, returns reason for failure
840
841 string sClinicCancelled = (bClinicCancelled == true)?"C":"PC";
842 string sReasonID = nReason.ToString();
843 string sSql = "BSDX CANCEL APPOINTMENT^" + nApptID.ToString();
844 sSql += "^" + sClinicCancelled;
845 sSql += "^" + sReasonID;
846 sSql += "^" + sRemarks;
847 DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "DeleteAppointment");
848
849 Debug.Assert(dtAppt.Rows.Count == 1);
850 DataRow r = dtAppt.Rows[0];
851 string sErrorID = r["ERRORID"].ToString();
852 if (sErrorID != "")
853 return sErrorID;
854
855 if (this.m_appointments.AppointmentTable.ContainsKey(nApptID))
856 {
857 this.m_appointments.RemoveAppointment(nApptID);
858 bool bRet = RefreshAvailabilitySchedule();
859 UpdateAllViews();
860 }
861 return "";
862 }
863
864 public string AutoRebook(CGAppointment a, int nSearchType, int nMinimumDays, int nMaximumDays, out CGAppointment aRebook)
865 {
866 //If successful Returns "1" and new start date and time returned in aRebook
867 //Otherwise, returns error message
868
869 CGAppointment aCopy = new CGAppointment();
870 aCopy.CreateAppointment(a.StartTime, a.EndTime, a.Note, 0, a.Resource);
871 aCopy.PatientID = a.PatientID;
872 aCopy.PatientName = a.PatientName;
873 aCopy.HealthRecordNumber = a.HealthRecordNumber;
874 aCopy.AccessTypeID = a.AccessTypeID;
875 aRebook = aCopy;
876
877 //Determine Rebook access type
878 //nSearchType = -1: use current, -2: use any non-zero type, >0 use this access type id
879 int nAVType = 0;
880
881 switch (nSearchType)
882 {
883 case -1:
884 nAVType = a.AccessTypeID;
885 break;
886 case -2:
887 nAVType = 0;
888 break;
889 default:
890 nAVType = nSearchType;
891 break;
892 }
893
894 int nSlots = 0;
895 string sSlots = "";
896 int nAccessTypeID; //To compare with nAVType
897
898 DateTime dResult = new DateTime(); //StartTime of access block to autorebook into
899
900 //Next two are empty, but needed to pass to CreateAvailabilitySchedule
901 ArrayList alAccessTypes = new ArrayList();
902 string sSearchInfo = "";
903
904 //Find the StartTime of first availability block of this type for this clinic
905 //between nMinimumDays and nMaximumDays
906
907 string sAVStart = a.StartTime.AddDays(nMinimumDays).ToString("M/d/yyyy@H:mm");
908
909 //dtAVEnd is the last day to search
910 DateTime dtAVEnd = a.StartTime.AddDays(nMinimumDays + nMaximumDays);
911 string sAVEnd = dtAVEnd.ToString("M/d/yyyy@H:mm");
912
913 //Increment start day to search a week (or so) at a time
914 //30 is a test increment. Need to test different values for performance
915 int nIncrement = (nMaximumDays < 30)?nMaximumDays:30;
916
917 //nCount and nCountEnd are the 'moving' counters
918 //that I add to start and end to get the bracket
919 //At the beginning of the DO loop, nCount and nCountEnd are already set
920 bool bFinished = false;
921 bool bFound = false;
922
923 DateTime dStart = a.StartTime.AddDays(nMinimumDays);
924 // v 1.3 i18n support - FM Date passed insated of American Date
925 string sStart = FMDateTime.Create(dStart).DateOnly.FMDateString;
926 DateTime dEnd = dStart.AddDays(nIncrement);
927 do
928 {
929 string sSql = "BSDX REBOOK NEXT BLOCK^" + sStart + "^" + a.Resource + "^" + nAVType.ToString();
930 DataTable dtNextBlock = this.DocManager.RPMSDataTable(sSql, "NextBlock");
931 Debug.Assert(dtNextBlock.Rows.Count == 1);
932 DataRow drNextBlockRow = dtNextBlock.Rows[0];
933
934 object oNextBlock;
935 oNextBlock = drNextBlockRow["NEXTBLOCK"];
936 if (oNextBlock.GetType() == typeof(System.DBNull))
937 break;
938 DateTime dNextBlock = (DateTime) drNextBlockRow["NEXTBLOCK"];
939 if (dNextBlock > dtAVEnd)
940 {
941 break;
942 }
943
944 dStart = dNextBlock;
945 dEnd = dStart.AddDays(nIncrement);
946 if (dEnd > dtAVEnd)
947 dEnd = dtAVEnd;
948
949 DataTable dtResult = CGSchedLib.CreateAvailabilitySchedule(m_DocManager, this.Resources, dStart, dEnd, alAccessTypes, ScheduleType.Resource, sSearchInfo);
950 //Loop thru dtResult looking for a slot having the required availability type.
951 //If found, set bFinished = true;
952 foreach (DataRow dr in dtResult.Rows)
953 {
954
955 sSlots = dr["SLOTS"].ToString();
956 if (sSlots == "")
957 sSlots = "0";
958 nSlots = Convert.ToInt16(sSlots);
959 if (nSlots > 0)
960 {
961 nAccessTypeID = 0; //holds the access type id of the availability block
962 if (dr["ACCESS_TYPE"].ToString() != "")
963 nAccessTypeID =Convert.ToInt16(dr["ACCESS_TYPE"].ToString());
964 if ((nSearchType == -2) && (nAccessTypeID > 0)) //Match on any non-zero type
965 {
966 bFinished = true;
967 bFound = true;
968 dResult = (DateTime) dr["START_TIME"];
969 break;
970 }
971 if (nAccessTypeID == nAVType)
972 {
973 bFinished = true;
974 bFound = true;
975 dResult = (DateTime) dr["START_TIME"];
976 break;
977 }
978 }
979 }
980 dStart = dEnd.AddDays(1);
981 dEnd = dStart.AddDays(nIncrement);
982 if (dEnd > dtAVEnd)
983 dEnd = dtAVEnd;
984 } while (bFinished == false);
985
986 if (bFound == true)
987 {
988 aCopy.StartTime = dResult;
989 aCopy.EndTime = dResult.AddMinutes(a.Duration);
990 //Create the appointment
991 //Set the AUTOREBOOKED flag
992 //and store the "AutoRebooked To DateTime"
993 //in each autorebooked appointment
994 this.CreateAppointment(aCopy);
995 SetAutoRebook(a, dResult);
996 return "1";
997 }
998 else
999 {
1000 return "0";
1001 }
1002 }
1003
1004 private void SetAutoRebook(CGAppointment a, DateTime dtRebookedTo)
1005 {
1006 string sApptKey = a.AppointmentKey.ToString();
1007 //string sRebookedTo = dtRebookedTo.ToString("M/d/yyyy@HH:mm");
1008 // i18n
1009 string sRebookedTo = FMDateTime.Create(dtRebookedTo).FMDateString;
1010 string sSql = "BSDX REBOOK SET^" + sApptKey + "^" + sRebookedTo;
1011 System.Data.DataTable dtRebook = m_DocManager.RPMSDataTable(sSql, "AutoRebook");
1012
1013 }
1014
1015 public string AppointmentNoShow(int nApptID, bool bNoShow)
1016 {
1017 /*
1018 * BSDX NOSHOW RPC Returns 1 in ERRORID if successfully sets NOSHOW flag in BSDX APPOINTMENT and, if applicable, File 2
1019 *Otherwise, returns 0 for failure and errormessage in ERRORTXT
1020 *THIS routine returns "" if success or the message in ERRORTEXT if failed
1021 *Exceptions should be caught by caller
1022 *
1023 */
1024
1025 string sTest = bNoShow.ToString();
1026 string sNoShow = (bNoShow == true)?"1":"0";
1027 string sSql = "BSDX NOSHOW^" + nApptID.ToString();
1028 sSql += "^";
1029 sSql += sNoShow;
1030
1031 DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "AppointmentNoShow");
1032
1033 Debug.Assert(dtAppt.Rows.Count == 1);
1034 DataRow r = dtAppt.Rows[0];
1035 string sErrorID = r["ERRORID"].ToString();
1036 if (sErrorID != "1")
1037 {
1038 return r["ERRORTEXT"].ToString();
1039 }
1040
1041 bool bRet = RefreshSchedule();
1042
1043 return sErrorID;
1044 }
1045
1046 #endregion Methods
1047
1048 }//End class
1049}//End namespace
Note: See TracBrowser for help on using the repository browser.