source: Scheduling/trunk/cs/bsdx0200GUISourceCode/CGAVDocument.cs@ 894

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

Fixes for i18n.

File size: 14.5 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 // i18n support
225 sStart = FMDateTime.Create(rApptInfo.StartTime).FMDateString;
226 sEnd = FMDateTime.Create(rApptInfo.EndTime).FMDateString;
227 sNote = rApptInfo.Note;
228 sResource = rApptInfo.Resource;
229 sTypeID = rApptInfo.AccessTypeID.ToString();
230 sSlots = rApptInfo.Slots.ToString();
231
232 CGAppointment aCopy = new CGAppointment();
233 aCopy.CreateAppointment(rApptInfo.StartTime, rApptInfo.EndTime, sNote, 0, sResource);
234 aCopy.AccessTypeID = rApptInfo.AccessTypeID;
235 aCopy.Slots = rApptInfo.Slots;
236 aCopy.IsAccessBlock = true;
237
238 string sSql = "BSDX ADD NEW AVAILABILITY^" + sStart + "^" + sEnd + "^" + sTypeID + "^" + sResource + "^" + sSlots + "^" + sNote;
239 DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "NewAvailability");
240
241 int nApptID;
242 int nErrorID;
243
244 Debug.Assert(dtAppt.Rows.Count == 1);
245 DataRow r = dtAppt.Rows[0];
246 nApptID =Convert.ToInt32(r["AVAILABILITYID"]);
247 nErrorID = Convert.ToInt32(r["ERRORID"]);
248 if (nErrorID != -1)
249 {
250 throw new Exception("VistA Error");
251 }
252 Debug.Write("CreateAvailabilityAuto -- new AV block created\n");
253
254 UpdateAllViews();
255
256 aCopy.AppointmentKey = nApptID;
257 return nApptID;
258 }
259 catch (Exception ex)
260 {
261 Debug.Write("CGAVDocument.CreateAppointmentAuto Failed: " + ex.Message);
262 return -1;
263 }
264 }
265
266
267 public int CreateAppointment(CGAppointment rApptInfo)
268 {
269 try
270 {
271 string sStart;
272 string sEnd;
273 string sResource;
274 string sNote;
275 string sTypeID;
276 string sSlots;
277
278 //sStart = rApptInfo.StartTime.ToString("M-d-yyyy@HH:mm");
279 //sEnd = rApptInfo.EndTime.ToString("M-d-yyyy@HH:mm");
280 // i18n support
281 sStart = FMDateTime.Create(rApptInfo.StartTime).FMDateString;
282 sEnd = FMDateTime.Create(rApptInfo.EndTime).FMDateString;
283 sNote = rApptInfo.Note;
284 sResource = rApptInfo.Resource;
285 sTypeID = rApptInfo.AccessTypeID.ToString();
286 sSlots = rApptInfo.Slots.ToString();
287
288 CGAppointment aCopy = new CGAppointment();
289 aCopy.CreateAppointment(rApptInfo.StartTime, rApptInfo.EndTime, sNote, 0, sResource);
290 aCopy.AccessTypeID = rApptInfo.AccessTypeID;
291 aCopy.Slots = rApptInfo.Slots;
292 aCopy.IsAccessBlock = true;
293
294 aCopy.AccessTypeName = this.AccessNameFromID(aCopy.AccessTypeID);
295
296 foreach (CGAppointment a in this.m_AVBlocks.AppointmentTable.Values)
297 {
298 DateTime sStart2 = a.StartTime;
299 DateTime sEnd2 = a.EndTime;
300 if (CGSchedLib.TimesOverlap(aCopy.StartTime, aCopy.EndTime, a.StartTime, a.EndTime))
301 {
302 // throw new Exception("Access blocks may not overlap.");
303 MessageBox.Show("Access blocks may not overlap.","Clinical Scheduling", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
304 return -1;
305 }
306
307 }
308
309 string sSql = "BSDX ADD NEW AVAILABILITY^" + sStart + "^" + sEnd + "^" + sTypeID + "^" + sResource + "^" + sSlots + "^" + sNote;
310 DataTable dtAppt =m_DocManager.RPMSDataTable(sSql, "NewAvailability");
311
312 int nApptID;
313 int nErrorID;
314
315 Debug.Assert(dtAppt.Rows.Count == 1);
316 DataRow r = dtAppt.Rows[0];
317 nApptID =Convert.ToInt32(r["AVAILABILITYID"]);
318 nErrorID = Convert.ToInt32(r["ERRORID"]);
319 if (nErrorID != -1)
320 {
321 throw new Exception("VistA Error");
322 }
323 Debug.Write("CreateAvailability -- new AV block created\n");
324
325 aCopy.AppointmentKey = nApptID;
326
327 this.m_AVBlocks.AddAppointment(aCopy);
328
329 UpdateAllViews();
330
331 return nApptID;
332 }
333 catch (Exception ex)
334 {
335 Debug.Write("CGAVDocument.CreateAppointment Failed: " + ex.Message);
336 return -1;
337 }
338 }
339
340 private int GetTotalMinutes(DateTime dDate)
341 {
342 return ((dDate.Hour * 60) + dDate.Minute);
343 }
344
345 private string AccessNameFromID(int nAccessTypeID)
346 {
347 DataView dvTypes = new DataView(this.DocManager.GlobalDataSet.Tables["AccessTypes"]);
348 dvTypes.Sort = "BMXIEN ASC";
349 int nRow = dvTypes.Find(nAccessTypeID);
350 DataRowView drv = dvTypes[nRow];
351 string sAccessTypeName = drv["ACCESS_TYPE_NAME"].ToString();
352 return sAccessTypeName;
353 }
354
355
356 /// <summary>
357 /// Update availability block schedule based on info in RPMS
358 /// </summary>
359 public bool RefreshDaysSchedule()
360 {
361 DateTime dStart;
362 DateTime dEnd;
363 int nKeyID;
364 string sNote;
365 string sResource;
366 string sAccessType;
367 string sSlots;
368 CGAppointment pAppointment;
369 CGDocumentManager pApp = CGDocumentManager.Current;
370 DataTable rAppointmentSchedule;
371
372 this.m_AVBlocks.ClearAllAppointments();
373
374 ArrayList apptTypeIDs = new ArrayList();
375
376 rAppointmentSchedule = CGSchedLib.CreateAssignedSlotSchedule(m_DocManager, (string) m_sResourcesArray[0], this.m_dStartDate, this.m_dEndDate, apptTypeIDs,/* */ this.m_ScheduleType, "0");
377 CGSchedLib.OutputArray(rAppointmentSchedule, "rAppointmentSchedule");
378 foreach (DataRow r in rAppointmentSchedule.Rows)
379 {
380 nKeyID = Convert.ToInt32(r["AVAILABILITYID"].ToString());
381 if (nKeyID > 0)
382 {
383 dStart = (DateTime) r["START_TIME"];
384 dEnd = (DateTime) r["END_TIME"];
385 sNote = r["NOTE"].ToString();
386 sResource = r["RESOURCE"].ToString();
387 sAccessType = r["ACCESS_TYPE"].ToString();
388 sSlots = r["SLOTS"].ToString();
389
390 pAppointment = new CGAppointment();
391 pAppointment.CreateAppointment(dStart, dEnd, sNote, nKeyID, sResource);
392 pAppointment.AccessTypeID = Convert.ToInt16(sAccessType);
393 pAppointment.Slots = Convert.ToInt16(sSlots);
394 pAppointment.IsAccessBlock = true;
395 pAppointment.AccessTypeName = this.AccessNameFromID(pAppointment.AccessTypeID);
396
397 this.m_AVBlocks.AddAppointment(pAppointment);
398 }
399 }
400 return true;
401 }
402
403 /// <summary>
404 /// Given a selected date,
405 /// Calculates StartDay and End Day and returns them in output params.
406 /// nWeeks == number of Weeks to display
407 /// nColumnCount is number of days displayed per week. If 5 columns, begin on
408 /// Monday, if 7 Columns, begin on Sunday
409 ///
410 /// Returns TRUE if the document's data needs refreshing based on
411 /// this newly selected date.
412 /// </summary>
413 public bool WeekNeedsRefresh(int nWeeks, DateTime SelectedDate,
414 out DateTime WeekStartDay, out DateTime WeekEndDay)
415 {
416 DateTime OldStartDay = m_dStartDate;
417 DateTime OldEndDay = m_dEndDate;
418 int nWeekDay = (int) SelectedDate.DayOfWeek; //0 == Sunday
419
420 int nOff = 1;
421 TimeSpan ts = new TimeSpan(nWeekDay - nOff,0,0,0); //d,h,m,s
422
423 if (m_nColumnCount == 1)
424 {
425 ts = new TimeSpan(0,23,59,59);
426 WeekStartDay = SelectedDate;
427 }
428 else
429 {
430 WeekStartDay = SelectedDate - ts;
431 if (m_nColumnCount == 7)
432 {
433 ts = new TimeSpan(1,0,0,0);
434 WeekStartDay -= ts;
435 }
436 int nEnd = (m_nColumnCount == 7) ? 1 : 3;
437 ts = new TimeSpan((7* nWeeks) - nEnd, 23, 59,59);
438 }
439 WeekEndDay = WeekStartDay + ts;
440 bool bRet = (( WeekStartDay.Date != OldStartDay.Date) || (WeekEndDay.Date != OldEndDay.Date));
441 return bRet;
442 }
443
444 public void OnOpenDocument()
445 {
446 //Create new Document
447 // DateTime dStart;
448 // DateTime dEnd;
449
450 Debug.Assert(m_sResourcesArray.Count > 0);
451
452 m_sSecondary = "";
453
454 m_ScheduleType = (m_sResourcesArray.Count == 1) ? ScheduleType.Resource: ScheduleType.Clinic;
455
456 bool bRet = false;
457 //Set initial From and To dates based on current day
458 // DateTime dDate = new DateTime(2001,12,05); //test line
459 DateTime dDate = DateTime.Today;
460 if (m_ScheduleType == ScheduleType.Resource)
461 {
462 bRet = this.WeekNeedsRefresh(1,dDate, out this.m_dStartDate, out this.m_dEndDate);
463 }
464 else
465 {
466 this.m_dStartDate = dDate;
467 this.m_dEndDate = dDate;
468 this.m_dEndDate = this.m_dEndDate.AddHours(23);
469 this.m_dEndDate = this.m_dEndDate.AddMinutes(59);
470 this.m_dEndDate = this.m_dEndDate.AddSeconds(59);
471 }
472
473 bRet = this.RefreshDaysSchedule();
474
475 CGAVView view = null;
476 //If this document already has a view, the use it
477 Hashtable h = CGDocumentManager.Current.AvailabilityViews;
478 CGAVDocument d;
479 bool bReuseView = false;
480 foreach (CGAVView v in h.Keys)
481 {
482 d = (CGAVDocument) h[v];
483 if (d == this)
484 {
485 view = v;
486 bReuseView = true;
487 break;
488 }
489 }
490
491 //Otherwise, create new View
492 if (bReuseView == false)
493 {
494 view = new CGAVView();
495
496 view.DocManager = this.DocManager;
497 view.StartDate = m_dStartDate;
498
499 //Assign the document to the view
500 view.Document = this;
501
502 //Link the calendargrid's appointments table to the document's table
503 view.AVBlocks = this.AVBlocks;
504
505 view.Text = "Edit Availability - " + this.DocName;
506 view.Show();
507 }
508
509 this.UpdateAllViews();
510
511 }
512
513 public void AddResource(string sResource)
514 {
515 //TODO: Test that resource is not currently in list, that it IS a resource, etc
516 this.m_sResourcesArray.Add(sResource);
517 this.UpdateAllViews();
518 }
519
520 /// <summary>
521 /// Calls each AVview associated with this AVdocument and tells it to update itself
522 /// </summary>
523 public void UpdateAllViews()
524 {
525 //iterate through all views and call update.
526 Hashtable h = CGDocumentManager.Current.AvailabilityViews;
527
528 CGAVDocument d;
529 foreach (CGAVView v in h.Keys)
530 {
531 d = (CGAVDocument) h[v];
532 if (d == this)
533 {
534 v.UpdateArrays();
535 }
536 }
537
538 }
539
540 #endregion
541
542 }//End class
543}
Note: See TracBrowser for help on using the repository browser.