source: Scheduling/branches/GUI1.2/CGAVDocument.cs@ 1657

Last change on this file since 1657 was 627, checked in by Sam Habiel, 15 years ago

Removed user-interface references to RPMS.

File size: 14.1 KB
Line 
1using System;
2using System.Collections;
3using System.Data;
4//using 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 array of availability blocks for a scheduling resource
14 /// </summary>
15 public class CGAVDocument : System.Object
16 {
17 public CGAVDocument()
18 {
19 m_AVBlocks = new CGAppointments();
20 m_sResourcesArray = new ArrayList();
21 }
22
23 #region Member Variables
24
25 public int m_nColumnCount; //todo: this should point to the view's member for column count
26 public int m_nTimeUnits;
27 public string m_sSecondary;
28 private string m_sDocName;
29 public ArrayList m_sResourcesArray;
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_AVBlocks;
35 private CGDocumentManager m_DocManager;
36 private int m_nDocID; //Resource IEN in ^BSDXRES
37
38 #endregion
39
40 #region Properties
41
42 /// <summary>
43 /// Resource IEN in ^BSDXRES
44 /// </summary>
45 public int ResourceID
46 {
47 get
48 {
49 return m_nDocID;
50 }
51 set
52 {
53 m_nDocID = value;
54 }
55 }
56
57 /// <summary>
58 /// The list of Resource names
59 /// </summary>
60 public ArrayList Resources
61 {
62 get
63 {
64 return this.m_sResourcesArray;
65 }
66 set
67 {
68 this.m_sResourcesArray = value;
69 }
70 }
71
72 public CGDocumentManager DocManager
73 {
74 get
75 {
76 return m_DocManager;
77 }
78 set
79 {
80 m_DocManager = value;
81 }
82 }
83
84 /// <summary>
85 /// Contains the hashtable of Availability Blocks
86 /// </summary>
87 public CGAppointments AVBlocks
88 {
89 get
90 {
91 return m_AVBlocks;
92 }
93 set
94 {
95 m_AVBlocks = value;
96 }
97 }
98
99 /// <summary>
100 /// Holds the date selected by the user in CGView.dateTimePicker1
101 /// </summary>
102 public DateTime SelectedDate
103 {
104 get
105 {
106 return this.m_dSelectedDate;
107 }
108 set
109 {
110 this.m_dSelectedDate = value;
111 bool bRet = false;
112 if (m_ScheduleType == ScheduleType.Resource)
113 {
114 bRet = this.WeekNeedsRefresh(1, m_dSelectedDate, out this.m_dStartDate, out this.m_dEndDate);
115 }
116 else
117 {
118 this.m_dStartDate = m_dSelectedDate;
119 this.m_dEndDate = m_dSelectedDate;
120 this.m_dEndDate = this.m_dEndDate.AddHours(23);
121 this.m_dEndDate = this.m_dEndDate.AddMinutes(59);
122 this.m_dEndDate = this.m_dEndDate.AddSeconds(59);
123 }
124
125 bRet = this.RefreshDaysSchedule();
126 }
127 }
128
129 /// <summary>
130 /// Contains the beginning date of the appointment document
131 /// </summary>
132 public DateTime StartDate
133 {
134 get
135 {
136 return this.m_dStartDate;
137 }
138 }
139
140 public string DocName
141 {
142 get
143 {
144 return this.m_sDocName;
145 }
146 set
147 {
148 this.m_sDocName = value;
149 }
150 }
151
152 #endregion
153
154 #region Methods
155
156 public void ChangeAppointmentTime(CGAppointment pAppt, DateTime dNewStart, DateTime dNewEnd, string sResource)
157 {
158 try
159 {
160 DateTime dOldStart = pAppt.StartTime;
161 DateTime dOldEnd = pAppt.EndTime;
162 if ((dOldStart == dNewStart) && (dOldEnd == dNewEnd))
163 { //no change in time
164 return;
165 }
166
167 foreach (CGAppointment a in m_AVBlocks.AppointmentTable.Values)
168 {
169 DateTime sStart2 = a.StartTime;
170 DateTime sEnd2 = a.EndTime;
171 if ((a.AppointmentKey != pAppt.AppointmentKey) && (CGSchedLib.TimesOverlap(dNewStart, dNewEnd, a.StartTime, a.EndTime)))
172 {
173 MessageBox.Show("Access blocks may not overlap.","Clinical Scheduling", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
174 return;
175 }
176 }
177
178 this.DeleteAvailability(pAppt.AppointmentKey);
179 pAppt.StartTime = dNewStart;
180 pAppt.EndTime = dNewEnd;
181 pAppt.Resource = sResource;
182 this.CreateAppointment(pAppt);
183
184 }
185 catch(Exception e)
186 {
187 MessageBox.Show("CGDocument::ChangeAppointmentTime failed: " + e.Message);
188 return;
189 }
190 }
191
192 public void DeleteAvailability(int nApptID)
193 {
194 if (this.m_AVBlocks.AppointmentTable.ContainsKey(nApptID))
195 {
196 string sSql = "BSDX CANCEL AVAILABILITY^" + nApptID.ToString();
197 DataTable dtAppt =m_DocManager.RPMSDataTable(sSql, "DeleteAvailability");
198 int nErrorID;
199 Debug.Assert(dtAppt.Rows.Count == 1);
200 DataRow r = dtAppt.Rows[0];
201 nErrorID = Convert.ToInt32(r["ERRORID"]);
202 this.m_AVBlocks.RemoveAppointment(nApptID);
203 UpdateAllViews();
204 }
205 }
206
207 /// <summary>
208 /// Called by LoadTemplate to create Access Block
209 /// Returns the IEN of the availability block in the RPMS BSDX AVAILABILITY file.
210 /// </summary>
211 public int CreateAppointmentAuto(CGAppointment rApptInfo)
212 {
213 try
214 {
215 string sStart;
216 string sEnd;
217 string sResource;
218 string sNote;
219 string sTypeID;
220 string sSlots;
221
222 sStart = rApptInfo.StartTime.ToString("M-d-yyyy@HH:mm");
223 sEnd = rApptInfo.EndTime.ToString("M-d-yyyy@HH:mm");
224 sNote = rApptInfo.Note;
225 sResource = rApptInfo.Resource;
226 sTypeID = rApptInfo.AccessTypeID.ToString();
227 sSlots = rApptInfo.Slots.ToString();
228
229 CGAppointment aCopy = new CGAppointment();
230 aCopy.CreateAppointment(rApptInfo.StartTime, rApptInfo.EndTime, sNote, 0, sResource);
231 aCopy.AccessTypeID = rApptInfo.AccessTypeID;
232 aCopy.Slots = rApptInfo.Slots;
233 aCopy.IsAccessBlock = true;
234
235 string sSql = "BSDX ADD NEW AVAILABILITY^" + sStart + "^" + sEnd + "^" + sTypeID + "^" + sResource + "^" + sSlots + "^" + sNote;
236 DataTable dtAppt =m_DocManager.RPMSDataTable(sSql, "NewAvailability");
237
238 int nApptID;
239 int nErrorID;
240
241 Debug.Assert(dtAppt.Rows.Count == 1);
242 DataRow r = dtAppt.Rows[0];
243 nApptID =Convert.ToInt32(r["AVAILABILITYID"]);
244 nErrorID = Convert.ToInt32(r["ERRORID"]);
245 if (nErrorID != -1)
246 {
247 throw new Exception("VistA Error");
248 }
249 Debug.Write("CreateAvailabilityAuto -- new AV block created\n");
250
251 UpdateAllViews();
252
253 aCopy.AppointmentKey = nApptID;
254 return nApptID;
255 }
256 catch (Exception ex)
257 {
258 Debug.Write("CGAVDocument.CreateAppointmentAuto Failed: " + ex.Message);
259 return -1;
260 }
261 }
262
263
264 public int CreateAppointment(CGAppointment rApptInfo)
265 {
266 try
267 {
268 string sStart;
269 string sEnd;
270 string sResource;
271 string sNote;
272 string sTypeID;
273 string sSlots;
274
275 sStart = rApptInfo.StartTime.ToString("M-d-yyyy@HH:mm");
276 sEnd = rApptInfo.EndTime.ToString("M-d-yyyy@HH:mm");
277 sNote = rApptInfo.Note;
278 sResource = rApptInfo.Resource;
279 sTypeID = rApptInfo.AccessTypeID.ToString();
280 sSlots = rApptInfo.Slots.ToString();
281
282 CGAppointment aCopy = new CGAppointment();
283 aCopy.CreateAppointment(rApptInfo.StartTime, rApptInfo.EndTime, sNote, 0, sResource);
284 aCopy.AccessTypeID = rApptInfo.AccessTypeID;
285 aCopy.Slots = rApptInfo.Slots;
286 aCopy.IsAccessBlock = true;
287
288 aCopy.AccessTypeName = this.AccessNameFromID(aCopy.AccessTypeID);
289
290 foreach (CGAppointment a in this.m_AVBlocks.AppointmentTable.Values)
291 {
292 DateTime sStart2 = a.StartTime;
293 DateTime sEnd2 = a.EndTime;
294 if (CGSchedLib.TimesOverlap(aCopy.StartTime, aCopy.EndTime, a.StartTime, a.EndTime))
295 {
296 // throw new Exception("Access blocks may not overlap.");
297 MessageBox.Show("Access blocks may not overlap.","Clinical Scheduling", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
298 return -1;
299 }
300
301 }
302
303 string sSql = "BSDX ADD NEW AVAILABILITY^" + sStart + "^" + sEnd + "^" + sTypeID + "^" + sResource + "^" + sSlots + "^" + sNote;
304 DataTable dtAppt =m_DocManager.RPMSDataTable(sSql, "NewAvailability");
305
306 int nApptID;
307 int nErrorID;
308
309 Debug.Assert(dtAppt.Rows.Count == 1);
310 DataRow r = dtAppt.Rows[0];
311 nApptID =Convert.ToInt32(r["AVAILABILITYID"]);
312 nErrorID = Convert.ToInt32(r["ERRORID"]);
313 if (nErrorID != -1)
314 {
315 throw new Exception("VistA Error");
316 }
317 Debug.Write("CreateAvailability -- new AV block created\n");
318
319 aCopy.AppointmentKey = nApptID;
320
321 this.m_AVBlocks.AddAppointment(aCopy);
322
323 UpdateAllViews();
324
325 return nApptID;
326 }
327 catch (Exception ex)
328 {
329 Debug.Write("CGAVDocument.CreateAppointment Failed: " + ex.Message);
330 return -1;
331 }
332 }
333
334 private int GetTotalMinutes(DateTime dDate)
335 {
336 return ((dDate.Hour * 60) + dDate.Minute);
337 }
338
339 private string AccessNameFromID(int nAccessTypeID)
340 {
341 DataView dvTypes = new DataView(this.DocManager.GlobalDataSet.Tables["AccessTypes"]);
342 dvTypes.Sort = "BMXIEN ASC";
343 int nRow = dvTypes.Find(nAccessTypeID);
344 DataRowView drv = dvTypes[nRow];
345 string sAccessTypeName = drv["ACCESS_TYPE_NAME"].ToString();
346 return sAccessTypeName;
347 }
348
349
350 /// <summary>
351 /// Update availability block schedule based on info in RPMS
352 /// </summary>
353 public bool RefreshDaysSchedule()
354 {
355 DateTime dStart;
356 DateTime dEnd;
357 int nKeyID;
358 string sNote;
359 string sResource;
360 string sAccessType;
361 string sSlots;
362 CGAppointment pAppointment;
363 CGDocumentManager pApp = CGDocumentManager.Current;
364 DataTable rAppointmentSchedule;
365
366 this.m_AVBlocks.ClearAllAppointments();
367
368 ArrayList apptTypeIDs = new ArrayList();
369
370 rAppointmentSchedule = CGSchedLib.CreateAssignedSlotSchedule(m_DocManager, (string) m_sResourcesArray[0], this.m_dStartDate, this.m_dEndDate, apptTypeIDs,/* */ this.m_ScheduleType, "0");
371 CGSchedLib.OutputArray(rAppointmentSchedule, "rAppointmentSchedule");
372 foreach (DataRow r in rAppointmentSchedule.Rows)
373 {
374 nKeyID = Convert.ToInt32(r["AVAILABILITYID"].ToString());
375 if (nKeyID > 0)
376 {
377 dStart = (DateTime) r["START_TIME"];
378 dEnd = (DateTime) r["END_TIME"];
379 sNote = r["NOTE"].ToString();
380 sResource = r["RESOURCE"].ToString();
381 sAccessType = r["ACCESS_TYPE"].ToString();
382 sSlots = r["SLOTS"].ToString();
383
384 pAppointment = new CGAppointment();
385 pAppointment.CreateAppointment(dStart, dEnd, sNote, nKeyID, sResource);
386 pAppointment.AccessTypeID = Convert.ToInt16(sAccessType);
387 pAppointment.Slots = Convert.ToInt16(sSlots);
388 pAppointment.IsAccessBlock = true;
389 pAppointment.AccessTypeName = this.AccessNameFromID(pAppointment.AccessTypeID);
390
391 this.m_AVBlocks.AddAppointment(pAppointment);
392 }
393 }
394 return true;
395 }
396
397 /// <summary>
398 /// Given a selected date,
399 /// Calculates StartDay and End Day and returns them in output params.
400 /// nWeeks == number of Weeks to display
401 /// nColumnCount is number of days displayed per week. If 5 columns, begin on
402 /// Monday, if 7 Columns, begin on Sunday
403 ///
404 /// Returns TRUE if the document's data needs refreshing based on
405 /// this newly selected date.
406 /// </summary>
407 public bool WeekNeedsRefresh(int nWeeks, DateTime SelectedDate,
408 out DateTime WeekStartDay, out DateTime WeekEndDay)
409 {
410 DateTime OldStartDay = m_dStartDate;
411 DateTime OldEndDay = m_dEndDate;
412 int nWeekDay = (int) SelectedDate.DayOfWeek; //0 == Sunday
413
414 int nOff = 1;
415 TimeSpan ts = new TimeSpan(nWeekDay - nOff,0,0,0); //d,h,m,s
416
417 if (m_nColumnCount == 1)
418 {
419 ts = new TimeSpan(0,23,59,59);
420 WeekStartDay = SelectedDate;
421 }
422 else
423 {
424 WeekStartDay = SelectedDate - ts;
425 if (m_nColumnCount == 7)
426 {
427 ts = new TimeSpan(1,0,0,0);
428 WeekStartDay -= ts;
429 }
430 int nEnd = (m_nColumnCount == 7) ? 1 : 3;
431 ts = new TimeSpan((7* nWeeks) - nEnd, 23, 59,59);
432 }
433 WeekEndDay = WeekStartDay + ts;
434 bool bRet = (( WeekStartDay.Date != OldStartDay.Date) || (WeekEndDay.Date != OldEndDay.Date));
435 return bRet;
436 }
437
438 public void OnOpenDocument()
439 {
440 //Create new Document
441 // DateTime dStart;
442 // DateTime dEnd;
443
444 Debug.Assert(m_sResourcesArray.Count > 0);
445
446 m_sSecondary = "";
447
448 m_ScheduleType = (m_sResourcesArray.Count == 1) ? ScheduleType.Resource: ScheduleType.Clinic;
449
450 bool bRet = false;
451 //Set initial From and To dates based on current day
452 // DateTime dDate = new DateTime(2001,12,05); //test line
453 DateTime dDate = DateTime.Today;
454 if (m_ScheduleType == ScheduleType.Resource)
455 {
456 bRet = this.WeekNeedsRefresh(1,dDate, out this.m_dStartDate, out this.m_dEndDate);
457 }
458 else
459 {
460 this.m_dStartDate = dDate;
461 this.m_dEndDate = dDate;
462 this.m_dEndDate = this.m_dEndDate.AddHours(23);
463 this.m_dEndDate = this.m_dEndDate.AddMinutes(59);
464 this.m_dEndDate = this.m_dEndDate.AddSeconds(59);
465 }
466
467 bRet = this.RefreshDaysSchedule();
468
469 CGAVView view = null;
470 //If this document already has a view, the use it
471 Hashtable h = CGDocumentManager.Current.AvailabilityViews;
472 CGAVDocument d;
473 bool bReuseView = false;
474 foreach (CGAVView v in h.Keys)
475 {
476 d = (CGAVDocument) h[v];
477 if (d == this)
478 {
479 view = v;
480 bReuseView = true;
481 break;
482 }
483 }
484
485 //Otherwise, create new View
486 if (bReuseView == false)
487 {
488 view = new CGAVView();
489
490 view.DocManager = this.DocManager;
491 view.StartDate = m_dStartDate;
492
493 //Assign the document to the view
494 view.Document = this;
495
496 //Link the calendargrid's appointments table to the document's table
497 view.AVBlocks = this.AVBlocks;
498
499 view.Text = "Edit Availability - " + this.DocName;
500 view.Show();
501 }
502
503 this.UpdateAllViews();
504
505 }
506
507 public void AddResource(string sResource)
508 {
509 //TODO: Test that resource is not currently in list, that it IS a resource, etc
510 this.m_sResourcesArray.Add(sResource);
511 this.UpdateAllViews();
512 }
513
514 /// <summary>
515 /// Calls each AVview associated with this AVdocument and tells it to update itself
516 /// </summary>
517 public void UpdateAllViews()
518 {
519 //iterate through all views and call update.
520 Hashtable h = CGDocumentManager.Current.AvailabilityViews;
521
522 CGAVDocument d;
523 foreach (CGAVView v in h.Keys)
524 {
525 d = (CGAVDocument) h[v];
526 if (d == this)
527 {
528 v.UpdateArrays();
529 }
530 }
531
532 }
533
534 #endregion
535
536 }//End class
537}
Note: See TracBrowser for help on using the repository browser.