source: Scheduling/branches/Radiology-Support/cs/bsdx0200GUISourceCode/CGSchedLib.cs@ 1166

Last change on this file since 1166 was 1166, checked in by Sam Habiel, 13 years ago

Various Radiology-related Modifications:
DAL: ScheduleRadiologyExam and CancelRadiologyExam methods to DB
CGSchedLib: Organize usings
CGView:

File size: 34.5 KB
Line 
1using System;
2using System.Data;
3using System.Collections;
4
5namespace IndianHealthService.ClinicalScheduling
6{
7 public enum ScheduleType
8 {
9 Resource,
10 Clinic
11 }
12
13 /// <summary>
14 /// CGSchedLib contains static functions that are called from throughout the
15 /// scheduling application.
16 /// </summary>
17 public static class CGSchedLib
18 {
19 /// <summary>
20 /// Gets appointments from VISTA to display in Grid
21 /// </summary>
22 /// <param name="docManager">God Class</param>
23 /// <param name="saryResNames">Resource Names Array</param>
24 /// <param name="StartTime">Self Explanatory</param>
25 /// <param name="EndTime">Self Explanatory</param>
26 /// <returns></returns>
27 public static DataTable CreateAppointmentSchedule(CGDocumentManager docManager, ArrayList saryResNames, DateTime StartTime, DateTime EndTime)
28 {
29 string sResName = string.Join("|", saryResNames.ToArray());
30 string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
31 string sEnd = FMDateTime.Create(EndTime).FMDateString;
32 string sSql = "BSDX CREATE APPT SCHEDULE^" + sResName + "^" + sStart + "^" + sEnd ;
33 DataTable dtRet = docManager.RPMSDataTable(sSql, "AppointmentSchedule");
34 return dtRet;
35 }
36
37
38 /// <summary>
39 /// Gets all Availabilities and Appointments, then substracts Appointments from availabilities.
40 /// </summary>
41 /// <param name="docManager">God Class</param>
42 /// <param name="saryResourceNames">Resource Array (ArrayList)</param>
43 /// <param name="StartTime">Self-Explanatory</param>
44 /// <param name="EndTime">Self-Explanatory</param>
45 /// <param name="saryApptTypes">Array of Access Type IDs</param>
46 /// <param name="stType">Not used</param>
47 /// <param name="sSearchInfo">Specific Search Parameters</param>
48 /// <returns></returns>
49 public static DataTable CreateAvailabilitySchedule(CGDocumentManager docManager,
50 ArrayList saryResourceNames, DateTime StartTime, DateTime EndTime,
51 ArrayList saryApptTypes,/**/ ScheduleType stType, string sSearchInfo)
52 {
53 DataTable rsOut = new DataTable("AvailabilitySchedule");
54 if (saryResourceNames.Count == 0) return rsOut;
55 string sResNames = string.Join("|", saryResourceNames.ToArray());
56 string sApptTypeIDs = string.Join("|", saryApptTypes.ToArray());
57 string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
58 string sEnd = FMDateTime.Create(EndTime).FMDateString;
59 string sSql = "BSDX CREATE ASGND SLOT SCHED^" + sResNames + "^" + sStart + "^" + sEnd + "^" + sApptTypeIDs + "^" + sSearchInfo; //+ "^" + sSTType ;
60 rsOut = docManager.RPMSDataTable(sSql, "AssignedSlotSchedule");
61
62 return rsOut;
63 }
64
65 /*NOT USED ANYMORE
66 //TODO: Optimize: no need to keep looping through resources.
67 // for each resource
68 for (int i = 0; i < nSize; i++)
69 {
70 sResName = saryResourceNames[i].ToString();
71 //Gets all the slots (or Availabities, or AV Blocks if you like)
72 rsSlotSchedule = CGSchedLib.CreateAssignedSlotSchedule(docManager, sResName, StartTime, EndTime, saryApptTypes, stType, sSearchInfo);
73 rsTemp1 = rsSlotSchedule;
74
75 //if we have slots
76 if (rsSlotSchedule.Rows.Count > 0 )
77 {
78 // Get appointment count to substract from the slots
79 rsApptSchedule = CGSchedLib.CreateAppointmentSlotSchedule(docManager, sResName, StartTime, EndTime, stType);
80
81 // Perform the substraction
82 rsTemp1 = CGSchedLib.SubtractSlotsRS2(rsSlotSchedule, rsApptSchedule, sResName);
83
84 }
85 //otherwise, just return the slot schedule we have.
86 else
87 {
88 rsTemp1 = rsSlotSchedule;
89
90 }
91
92
93 // if only one resource was passed in, its availablility is what we want
94 if (i == 0)
95 {
96 rsOut = rsTemp1;
97
98 }
99 // if more than one resource, merge them together
100 else
101 {
102 rsOut = CGSchedLib.UnionBlocks(rsTemp1, rsOut);
103 }
104 }
105 return rsOut;
106 }
107 */
108
109 /* NOT USED ANYMORE!!!
110 public static DataTable CreateAssignedTypeSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime, DateTime EndTime, ScheduleType stType)
111 {
112
113 string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
114 string sEnd = FMDateTime.Create(EndTime).DateOnly.FMDateString;
115 string sSql = "BSDX TYPE BLOCKS OVERLAP^" + sStart + "^" + sEnd + "^" + sResourceName;
116
117 DataTable rs = docManager.RPMSDataTable(sSql, "AssignedTypeSchedule");
118
119 if (rs.Rows.Count == 0)
120 return rs;
121
122 DataTable rsCopy = new DataTable("rsCopy");
123 DataColumn dCol = new DataColumn();
124 dCol.DataType = Type.GetType("System.DateTime");
125 dCol.ColumnName = "StartTime";
126 dCol.ReadOnly = true;
127 dCol.AllowDBNull = false;
128 dCol.Unique = false;
129 rsCopy.Columns.Add(dCol);
130
131 dCol = new DataColumn();
132 dCol.DataType = Type.GetType("System.DateTime");
133 dCol.ColumnName = "EndTime";
134 dCol.ReadOnly = true;
135 dCol.AllowDBNull = false;
136 dCol.Unique = false;
137 rsCopy.Columns.Add(dCol);
138
139 dCol = new DataColumn();
140 dCol.DataType = Type.GetType("System.Int16");
141 dCol.ColumnName = "AppointmentTypeID";
142 dCol.ReadOnly = true;
143 dCol.AllowDBNull = false;
144 dCol.Unique = false;
145 rsCopy.Columns.Add(dCol);
146
147 dCol = new DataColumn();
148 dCol.DataType = Type.GetType("System.Int32");
149 dCol.ColumnName = "AvailabilityID";
150 dCol.ReadOnly = true;
151 dCol.AllowDBNull = false;
152 dCol.Unique = false;
153 rsCopy.Columns.Add(dCol);
154
155 dCol = new DataColumn();
156 dCol.DataType = Type.GetType("System.String");
157 dCol.ColumnName = "ResourceName";
158 dCol.ReadOnly = true;
159 dCol.AllowDBNull = false;
160 dCol.Unique = false;
161 rsCopy.Columns.Add(dCol);
162
163
164 DateTime dLastEnd;
165 DateTime dStart;
166 DateTime dEnd;
167 DataRow rNew; //Temporary Holding place for first or last row
168
169 // Get Last Date from final row
170 rNew = rs.Rows[rs.Rows.Count - 1];
171 dLastEnd = (DateTime) rNew["EndTime"];
172 // Get First Date from first row
173 rNew = rs.Rows[0];
174 dStart = (DateTime) rNew["StartTime"];
175
176 long UNSPECIFIED_TYPE = 10;
177 long UNSPECIFIED_ID = 0;
178
179 //if first block in vgetrows starts later than StartTime,
180 // then pad with a new block
181
182 // if First Row time is later than the StartTime param (should always be true)
183 // then make a new row whose time starts from StartTime and ends with dStart
184 if (dStart > StartTime)
185 {
186 dEnd = dStart;
187 rNew = rsCopy.NewRow();
188 rNew["StartTime"] = StartTime;
189 rNew["EndTime"] = dEnd;
190 rNew["AppointmentTypeID"] = UNSPECIFIED_TYPE;
191 rNew["AvailabilityID"] = UNSPECIFIED_ID;
192 rNew["ResourceName"] = sResourceName;
193 rsCopy.Rows.Add(rNew);
194 }
195
196 //if first block start time is < StartTime then trim (shouldn't happen)
197 if (dStart < StartTime)
198 {
199 rNew = rs.Rows[0];
200 rNew["StartTime"] = StartTime;
201 dStart = StartTime;
202 }
203
204 int nAppointmentTypeID;
205 int nAvailabilityID;
206
207 //dStart holds the first date for the availabilities returned from RPMS
208 dEnd = dStart;
209 foreach (DataRow rEach in rs.Rows)
210 {
211 dStart = (DateTime) rEach["StartTime"];
212 if (dStart > dEnd)
213 {
214 rNew = rsCopy.NewRow();
215 rNew["StartTime"] = dEnd;
216 rNew["EndTime"] = dStart;
217 rNew["AppointmentTypeID"] = 0;
218 rNew["AvailabilityID"] = UNSPECIFIED_ID;
219 rNew["ResourceName"] = sResourceName;
220 rsCopy.Rows.Add(rNew);
221 }
222
223 //dEnd now EndTime for AV Block
224 dEnd = (DateTime) rEach["EndTime"];
225
226 // if dEnd is greater than endime, set dEnd to be the same as EndTime.
227 if (dEnd > EndTime) { dEnd = EndTime; }
228
229
230 nAppointmentTypeID = (int) rEach["AppointmentTypeID"];
231 nAvailabilityID = (int) rEach["AvailabilityID"];
232
233 rNew = rsCopy.NewRow();
234 rNew["StartTime"] = dStart;
235 rNew["EndTime"] = dEnd;
236 rNew["AppointmentTypeID"] = nAppointmentTypeID;
237 rNew["AvailabilityID"] = nAvailabilityID;
238 rNew["ResourceName"] = sResourceName;
239 rsCopy.Rows.Add(rNew);
240 }
241
242 //Pad the end if necessary
243 if (dLastEnd < EndTime)
244 {
245 rNew = rsCopy.NewRow();
246 rNew["StartTime"] = dLastEnd;
247 rNew["EndTime"] = EndTime;
248 rNew["AppointmentTypeID"] = UNSPECIFIED_TYPE;
249 rNew["AvailabilityID"] = UNSPECIFIED_ID;
250 rNew["ResourceName"] = sResourceName;
251 rsCopy.Rows.Add(rNew);
252 }
253
254 return rsCopy;
255 }
256 */
257
258 /// <summary>
259 /// Gets the Availability Slots from the Server
260 /// </summary>
261 /// <param name="docManager">God Class</param>
262 /// <param name="sResourceName">Resource for which to get slots</param>
263 /// <param name="StartTime"></param>
264 /// <param name="EndTime"></param>
265 /// <param name="rsaryApptTypeIDs">Access Type IDs to retrieve</param>
266 /// <param name="stType">Not used</param>
267 /// <param name="sSearchInfo">If performing a slot search (i.e. for empty appointments), has search info here. Used by Find Appointments</param>
268 /// <returns>DataTable with the following Columns:
269 /// D00030START_TIME^D00030END_TIME^I00010SLOTS^T00030RESOURCE^T00010ACCESS_TYPE^T00250NOTE^I00030AVAILABILITYID
270 /// </returns>
271 /*
272 * public static DataTable CreateAssignedSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime,
273 DateTime EndTime, ArrayList rsaryApptTypeIDs, ScheduleType stType, string sSearchInfo)
274 {
275 //Appointment type ids is now always "" so that all appointment types are returned.
276 string sApptTypeIDs = string.Join("|", rsaryApptTypeIDs.ToArray());
277 string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
278 string sEnd = FMDateTime.Create(EndTime).FMDateString;
279 string sSql = "BSDX CREATE ASGND SLOT SCHED^" + sResourceName + "^" + sStart + "^" + sEnd + "^" + sApptTypeIDs + "^" + sSearchInfo; //+ "^" + sSTType ;
280 DataTable dtRet = docManager.RPMSDataTable(sSql, "AssignedSlotSchedule");
281
282 return dtRet;
283 }
284 */
285
286 /*
287 public static DataTable CreateCopyTable()
288 {
289 DataTable dtCopy = new DataTable("dtCopy");
290 DataColumn dCol = new DataColumn();
291 dCol.DataType = Type.GetType("System.DateTime");
292 dCol.ColumnName = "START_TIME";
293 dCol.ReadOnly = true;
294 dCol.AllowDBNull = false;
295 dCol.Unique = false;
296 dtCopy.Columns.Add(dCol);
297
298 dCol = new DataColumn();
299 dCol.DataType = Type.GetType("System.DateTime");
300 dCol.ColumnName = "END_TIME";
301 dCol.ReadOnly = true;
302 dCol.AllowDBNull = false;
303 dCol.Unique = false;
304 dtCopy.Columns.Add(dCol);
305
306 dCol = new DataColumn();
307 dCol.DataType = Type.GetType("System.Int16");
308 dCol.ColumnName = "SLOTS";
309 dCol.ReadOnly = true;
310 dCol.AllowDBNull = false;
311 dCol.Unique = false;
312 dtCopy.Columns.Add(dCol);
313
314 dCol = new DataColumn();
315 dCol.DataType = Type.GetType("System.String");
316 dCol.ColumnName = "RESOURCE";
317 dCol.ReadOnly = true;
318 dCol.AllowDBNull = true;
319 dCol.Unique = false;
320 dtCopy.Columns.Add(dCol);
321
322 dCol = new DataColumn();
323 dCol.DataType = Type.GetType("System.String");
324 dCol.ColumnName = "ACCESS_TYPE";
325 dCol.ReadOnly = true;
326 dCol.AllowDBNull = true;
327 dCol.Unique = false;
328 dtCopy.Columns.Add(dCol);
329
330 dCol = new DataColumn();
331 dCol.DataType = Type.GetType("System.String");
332 dCol.ColumnName = "NOTE";
333 dCol.ReadOnly = true;
334 dCol.AllowDBNull = true;
335 dCol.Unique = false;
336 dtCopy.Columns.Add(dCol);
337
338
339 return dtCopy;
340 }
341 */
342
343 /// <summary>
344 /// This gets a datatable which shows the appointments between start and end time, one row per appointment
345 /// </summary>
346 /// <param name="docManager"></param>
347 /// <param name="sResourceName"></param>
348 /// <param name="StartTime"></param>
349 /// <param name="EndTime"></param>
350 /// <param name="stType"></param>
351 /// <returns>DataTable with 4 columns: START_TIME, END_TIME, SLOTS, RESOURCE </returns>
352 /*
353 public static DataTable CreateAppointmentSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime, DateTime EndTime, ScheduleType stType)
354 {
355 //Change Dates to FM Format
356 string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
357 string sEnd = FMDateTime.Create(EndTime).DateOnly.FMDateString;
358
359 string sSTType = (stType == ScheduleType.Resource ? "ST_RESOURCE" : "ST_CLINIC");
360 string sSql = "BSDX APPT BLOCKS OVERLAP^" + sStart + "^" + sEnd + "^" + sResourceName ;//+ "^" + sSTType;
361
362 //This gets you a table with 2 columns containing start and end time for each appt
363 //Each appt gets its own row
364 DataTable dtRet = docManager.RPMSDataTable(sSql, "AppointmentSlotSchedule");
365
366 if (dtRet.Rows.Count < 1)
367 return dtRet;
368
369 //Create CDateTimeArray & load records from rsOut
370 int nRC = dtRet.Rows.Count; // nRC is row count from Appointments table just retrieved
371 ArrayList cdtArray = new ArrayList();
372 cdtArray.Capacity = (nRC * 2); //new ArrayList has capacity double that of appointment table
373 DateTime v;
374 int i = 0;
375
376 //for each row in the Appointment Table, ArrayList cdtArray gets 2 entries: Start and End times
377 foreach (DataRow r in dtRet.Rows)
378 {
379 v = (DateTime) r[dtRet.Columns["START_TIME"]];
380 cdtArray.Add(v);
381 v = (DateTime) r[dtRet.Columns["END_TIME"]];
382 cdtArray.Add(v);
383 }
384
385 //Sort start and end times (for use in ScheduleFromArray method)
386 cdtArray.Sort();
387
388 //Create a CTimeBlockArray and load it from rsOut
389
390 //Now, create a new ArrayList with the size of the appointment table to hold availabilities
391 ArrayList ctbAppointments = new ArrayList(nRC);
392 CGAvailability cTB;
393 i = 0;
394 //For each appointment, create an availability
395 foreach (DataRow r in dtRet.Rows)
396 {
397 cTB = new CGAvailability();
398 cTB.StartTime = (DateTime) r[dtRet.Columns["START_TIME"]];
399 cTB.EndTime = (DateTime) r[dtRet.Columns["END_TIME"]];
400 ctbAppointments.Add(cTB);
401 }
402
403 //Create a TimeBlock Array from the data in the DateTime array
404 ArrayList ctbApptSchedule = new ArrayList();
405
406 //Convert Appointments to Availabilities, where all appointments become squeezed together.
407 ScheduleFromArray(cdtArray, StartTime, EndTime, ref ctbApptSchedule);
408
409 So far, we have the following:
410 * dtRet -> List of Appointments Start and End times, one row per appointment
411 * cdtArray -> Linear 1 dimensional Array of dtRet Start and End times, sorted
412 * ctbAppointments -> Arraylist of dtRet as Availabilities
413 * ctbApptSchedule -> Arraylist of dtRet as Availabilities with no overlapping boundaries
414 * (overlaps in appointments get converted into availabilties themselves: so
415 * 2 appts as 10:10-10:30 and 10:20-10:40 get converted into 10:10-10:20,
416 * 10:20-10:30, 10:30-10:40).
417
418
419 //Find number of TimeBlocks in ctbApptSchedule that overlap the TimeBlocks in ctbAppointments
420 ArrayList ctbApptSchedule2 = new ArrayList();
421 CGAvailability cTB2;
422 int nSlots = 0;
423 for (i=0; i< ctbApptSchedule.Count; i++) //for each non-overlapping appts as availabilities
424 {
425 cTB = (CGAvailability) ctbApptSchedule[i];
426 //How many times does the non-overlapping part show up in an appointment slot?
427 nSlots = BlocksOverlap(cTB, ctbAppointments);
428 cTB2 = new CGAvailability();
429 cTB2.Create(cTB.StartTime, cTB.EndTime, nSlots);
430 ctbApptSchedule2.Add(cTB2);
431 }
432
433 ConsolidateBlocks(ctbApptSchedule2);
434
435 DataTable dtCopy = new DataTable("dtCopy");
436 DataColumn dCol = new DataColumn();
437 dCol.DataType = Type.GetType("System.DateTime");
438 dCol.ColumnName = "START_TIME";
439 dCol.ReadOnly = true;
440 dCol.AllowDBNull = false;
441 dCol.Unique = false;
442 dtCopy.Columns.Add(dCol);
443
444 dCol = new DataColumn();
445 dCol.DataType = Type.GetType("System.DateTime");
446 dCol.ColumnName = "END_TIME";
447 dCol.ReadOnly = true;
448 dCol.AllowDBNull = false;
449 dCol.Unique = false;
450 dtCopy.Columns.Add(dCol);
451
452 dCol = new DataColumn();
453 dCol.DataType = Type.GetType("System.Int16");
454 dCol.ColumnName = "SLOTS";
455 dCol.ReadOnly = true;
456 dCol.AllowDBNull = false;
457 dCol.Unique = false;
458 dtCopy.Columns.Add(dCol);
459
460 dCol = new DataColumn();
461 dCol.DataType = Type.GetType("System.String");
462 dCol.ColumnName = "RESOURCE";
463 dCol.ReadOnly = true;
464 dCol.AllowDBNull = false;
465 dCol.Unique = false;
466 dtCopy.Columns.Add(dCol);
467
468 for (int k=0; k < ctbApptSchedule2.Count; k++)
469 {
470 cTB = (CGAvailability) ctbApptSchedule2[k];
471 DataRow newRow;
472 newRow = dtCopy.NewRow();
473 newRow["START_TIME"] = cTB.StartTime;
474 newRow["END_TIME"] = cTB.EndTime;
475 newRow["SLOTS"] = cTB.Slots;
476 newRow["RESOURCE"] = sResourceName;
477 dtCopy.Rows.Add(newRow);
478 }
479
480 return dtCopy;
481
482 }
483 */
484
485 /*
486 public static int BlocksOverlap(CGAvailability rBlock, ArrayList rTBArray)
487 {
488 //this overload implements default false for bCountSlots
489 return CGSchedLib.BlocksOverlap(rBlock, rTBArray, false);
490 }
491 public static int BlocksOverlap(CGAvailability rBlock, ArrayList rTBArray, bool bCountSlots)
492 {
493 //If bCountSlots == true, then returns
494 //sum of Slots in overlapping blocks
495 //instead of the count of overlapping blocks
496
497 DateTime dStart1;
498 DateTime dStart2;
499 DateTime dEnd1;
500 DateTime dEnd2;
501 int nSlots;
502 int nCount = 0;
503 CGAvailability cBlock;
504
505 dStart1 = rBlock.StartTime;
506 dEnd1 = rBlock.EndTime;
507
508 for (int j=0; j< rTBArray.Count; j++)
509 {
510 cBlock = (CGAvailability) rTBArray[j];
511 dStart2 = cBlock.StartTime;
512 dEnd2 = cBlock.EndTime;
513 nSlots = cBlock.Slots;
514 if (TimesOverlap(dStart1, dEnd1, dStart2, dEnd2))
515 {
516 if (bCountSlots == true)
517 {
518 nCount += nSlots;
519 }
520 else
521 {
522 nCount++;
523 }
524 }
525 }
526
527 return nCount;
528 }
529 */
530
531 /// <summary>
532 /// Does an appointment overlap with another appointment in the same day?
533 /// </summary>
534 /// <param name="dStart1">Start Time of First Appt</param>
535 /// <param name="dEnd1">End Time of First Appt</param>
536 /// <param name="dStart2">Start Time of Second Appt</param>
537 /// <param name="dEnd2">End Time of Second Appt</param>
538 /// <returns>true or false</returns>
539 /// <remarks>Draws 2 rectangles and sees if they overlap using minutes from 1980 as the start point</remarks>
540 /*
541 public static bool TimesOverlap(DateTime dStart1, DateTime dEnd1, DateTime dStart2, DateTime dEnd2)
542 {
543 Rectangle rect1 = new Rectangle();
544 Rectangle rect2 = new Rectangle();
545 rect1.X = 0;
546 rect2.X = 0;
547 rect1.Width = 1;
548 rect2.Width = 1;
549
550 rect1.Y = CGSchedLib.MinSince80(dStart1);
551 rect1.Height = CGSchedLib.MinSince80(dEnd1) - rect1.Y;
552 rect2.Y = CGSchedLib.MinSince80(dStart2);
553 rect2.Height = CGSchedLib.MinSince80(dEnd2) - rect2.Y;
554 bool bRet = rect2.IntersectsWith(rect1);
555 return bRet;
556 }
557 */
558
559 /*
560 public static void ConsolidateBlocks(ArrayList rTBArray)
561 {
562 //TODO: Test this function
563
564 int j = 0;
565 bool bDirty = false;
566 CGAvailability cBlockA;
567 CGAvailability cBlockB;
568 CGAvailability cTemp1;
569 if (rTBArray.Count < 2)
570 return;
571 do
572 {
573 bDirty = false;
574 for (j = 0; j < (rTBArray.Count - 1); j++) //TODO: why minus 1?
575 {
576 cBlockA = (CGAvailability) rTBArray[j];
577 cBlockB = (CGAvailability) rTBArray[j+1];
578 if ((cBlockA.EndTime == cBlockB.StartTime)
579 && (cBlockA.Slots == cBlockB.Slots)
580 && (cBlockA.ResourceList == cBlockB.ResourceList)
581 && (cBlockA.AccessRuleList == cBlockB.AccessRuleList)
582 )
583 {
584 cTemp1 = new CGAvailability();
585 cTemp1.StartTime = cBlockA.StartTime;
586 cTemp1.EndTime = cBlockB.EndTime;
587 cTemp1.Slots = cBlockA.Slots;
588 cTemp1.AccessRuleList = cBlockA.AccessRuleList;
589 cTemp1.ResourceList = cBlockA.ResourceList;
590 rTBArray.Insert(j, cTemp1);
591 rTBArray.RemoveRange(j+1, 2);
592 bDirty = true;
593 break;
594 }
595 }
596 }
597 while (!((bDirty == false) || (rTBArray.Count == 1)));
598 } */
599
600 /// <summary>
601 /// My guess is that this calculates remaining slots
602 /// </summary>
603 /// <param name="rsBlocks1"></param>
604 /// <param name="rsBlocks2"></param>
605 /// <param name="sResource"></param>
606 /// <returns></returns>
607 /*
608 public static DataTable SubtractSlotsRS2(DataTable rsBlocks1, DataTable rsBlocks2, string sResource)
609 {
610 //Subtract slots in rsBlocks2 from rsBlocks1
611 //7-16-01 SUBCLINIC data field in rsBlocks1 persists thru routine.
612 //7-18-01 RESOURCE and ACCESS_TYPE fields presisted
613
614 if ((rsBlocks2.Rows.Count == 0) || (rsBlocks1.Rows.Count == 0))
615 return rsBlocks1;
616
617
618 //Create an array of the start and end times of blocks2
619 ArrayList cdtArray = new ArrayList(2*(rsBlocks1.Rows.Count + rsBlocks2.Rows.Count));
620
621 foreach (DataRow r in rsBlocks1.Rows)
622 {
623 cdtArray.Add(r[rsBlocks1.Columns["START_TIME"]]);
624 cdtArray.Add(r[rsBlocks1.Columns["END_TIME"]]);
625 }
626
627 foreach (DataRow r in rsBlocks2.Rows)
628 {
629 cdtArray.Add(r[rsBlocks2.Columns["START_TIME"]]);
630 cdtArray.Add(r[rsBlocks2.Columns["END_TIME"]]);
631 }
632
633 cdtArray.Sort();
634
635 ArrayList ctbReturn = new ArrayList();
636 DateTime cDate = new DateTime();
637 ScheduleFromArray(cdtArray, cDate, cDate, ref ctbReturn);
638
639 //Set up return table
640 DataTable rsCopy = CGSchedLib.CreateCopyTable(); //TODO: There's a datatable method that does this.
641 long nSlots = 0;
642 CGAvailability cTB;
643
644 for (int j=0; j < (ctbReturn.Count -1); j++) //TODO: why minus 1?
645 {
646 cTB = (CGAvailability) ctbReturn[j];
647 nSlots = SlotsInBlock(cTB, rsBlocks1) - SlotsInBlock(cTB, rsBlocks2);
648 string sResourceList = "";
649 string sAccessRuleList = "";
650 string sNote = "";
651
652 if (nSlots > 0)
653 {
654 bool bRet = ResourceRulesInBlock(cTB, rsBlocks1, ref sResourceList, ref sAccessRuleList, ref sNote);
655 }
656 DataRow newRow;
657 newRow = rsCopy.NewRow();
658 newRow["START_TIME"] = cTB.StartTime;
659 newRow["END_TIME"] = cTB.EndTime;
660 newRow["SLOTS"] = nSlots;
661 //Subclinic, Access Rule and Resource are null in subtractedSlot sets
662 newRow["RESOURCE"] = sResource;
663 newRow["ACCESS_TYPE"] = sAccessRuleList;
664
665 newRow["NOTE"] = sNote;
666
667 rsCopy.Rows.Add(newRow);
668 }
669 return rsCopy;
670
671 }
672 */
673
674 /*
675 public static DataTable UnionBlocks(DataTable rs1, DataTable rs2)
676 {
677 //Test input tables
678 Debug.Assert(rs1 != null);
679 Debug.Assert(rs2 != null);
680
681 DataTable rsCopy;
682 DataRow dr;
683 if (rs1.Columns.Count >= rs2.Columns.Count)
684 {
685 rsCopy = rs1.Copy();
686 foreach (DataRow dr2 in rs2.Rows)
687 {
688 dr = rsCopy.NewRow();
689 dr.ItemArray = dr2.ItemArray;
690 //dr["START_TIME"] = dr2["START_TIME"];
691 //dr["END_TIME"] = dr2["END_TIME"];
692 //dr["SLOTS"] = dr2["SLOTS"];
693 rsCopy.Rows.Add(dr);
694 }
695 }
696 else
697 {
698 rsCopy = rs2.Copy();
699 foreach (DataRow dr2 in rs1.Rows)
700 {
701 dr = rsCopy.NewRow();
702 dr.ItemArray = dr2.ItemArray;
703 rsCopy.Rows.Add(dr);
704 }
705 }
706 return rsCopy;
707 }
708 */
709
710 /*
711 public static DataTable IntersectBlocks(DataTable rs1, DataTable rs2)
712 {
713 DataTable rsCopy = CGSchedLib.CreateCopyTable();
714
715 //Test input tables
716
717 if ((rs1 == null) || (rs2 == null))
718 return rsCopy;
719
720 if ((rs1.Rows.Count == 0) || (rs2.Rows.Count == 0))
721 return rsCopy;
722
723 int nSlots1 = 0;
724 int nSlots2 = 0;
725 int nSlots3 = 0;
726 DateTime dStart1;
727 DateTime dStart2;
728 DateTime dStart3;
729 DateTime dEnd1;
730 DateTime dEnd2;
731 DateTime dEnd3;
732 string sClinic;
733 string sClinic2;
734// Rectangle rect1 = new Rectangle();
735// Rectangle rect2 = new Rectangle();
736// rect1.X = 0;
737// rect2.X = 0;
738// rect1.Width = 1;
739// rect2.Width = 1;
740
741 // DataColumn cSlots = rs1.Columns["SLOTS"];
742 foreach (System.Data.DataRow r1 in rs1.Rows)
743 {
744 nSlots1 = (int) r1[rs1.Columns["SLOTS"]];
745 if (nSlots1 > 0)
746 {
747 dStart1 = (DateTime) r1[rs1.Columns["START_TIME"]];
748 dEnd1 = (DateTime) r1[rs1.Columns["END_TIME"]];
749 sClinic = r1[rs1.Columns["SUBCLINIC"]].ToString();
750 if (sClinic == "NULL")
751 sClinic = "";
752// rect1.Y = CGSchedLib.MinSince80(dStart1);
753// rect1.Height = CGSchedLib.MinSince80(dEnd1) - rect1.Y;
754 foreach (System.Data.DataRow r2 in rs2.Rows)
755 {
756 nSlots2 = (int) r2[rs2.Columns["SLOTS"]];
757
758 if (nSlots2 > 0)
759 {
760 dStart2 = (DateTime) r2[rs2.Columns["START_TIME"]];
761 dEnd2 = (DateTime) r2[rs2.Columns["END_TIME"]];
762 sClinic2 = r2[rs2.Columns["SUBCLINIC"]].ToString();
763// rect2.Y = CGSchedLib.MinSince80(dStart2);
764// rect2.Height = CGSchedLib.MinSince80(dEnd2) - rect2.Y;
765 if (
766 /*(rect2.IntersectsWith(rect1) == true)
767 (CGSchedLib.TimesOverlap(dStart1, dEnd1, dStart2, dEnd2) == true)
768 &&
769 ((sClinic == sClinic2) || (sClinic == "NONE") || (sClinic2 == "NONE"))
770 )
771 {
772 dStart3 = (dStart1 >= dStart2) ? dStart1 : dStart2 ;
773 dEnd3 = (dEnd1 >= dEnd2) ? dEnd2 : dEnd1;
774 nSlots3 = (nSlots1 >= nSlots2) ? nSlots2 : nSlots1 ;
775
776 DataRow newRow;
777 newRow = rsCopy.NewRow();
778 newRow["START_TIME"] = dStart3;
779 newRow["END_TIME"] = dEnd3;
780 newRow["SLOTS"] = nSlots3;
781 newRow["SUBCLINIC"] = (sClinic == "NONE") ? sClinic2 : sClinic;
782 //Access Rule and Resource are null in interesected sets
783 newRow["ACCESS_TYPE"] = "";
784 newRow["RESOURCE"] = "";
785 rsCopy.Rows.Add(newRow);
786 }
787 }//nSlots2 > 0
788 }//foreach r2 in rs2.rows
789 }//nSlots1 > 0
790 }//foreach r1 in rs1.rows
791 return rsCopy;
792 }//end IntersectBlocks
793 */
794
795 /// <summary>
796 /// Number of minutes since Jan 1 1980
797 /// </summary>
798 /// <param name="d">Date to compare</param>
799 /// <returns>Minutes as integer</returns>
800 /*
801 public static int MinSince80(DateTime d)
802 {
803 //Returns the total minutes between d and 1 Jan 1980
804 DateTime y = new DateTime(1980,1,1,0,0,0);
805 Debug.Assert(d > y);
806 TimeSpan ts = d - y;
807 //Assure ts.TotalMinutes within int range so that cast on next line works
808 Debug.Assert(ts.TotalMinutes < 2147483646);
809 int nMinutes = (int) ts.TotalMinutes;
810 return nMinutes;
811 }
812 */
813
814 /*
815 /// <summary>
816 /// Converts an Array of Times like this:
817 /// 10:00 10:00 10:20 10:20 10:30 10:30 10:30 10:40
818 /// To an array of availabilities like this:
819 /// 12:00-10:00 10:00-10:20 10:20-10:30 10:30-10:40
820 /// Where the 12:00 comes from the start time
821 /// </summary>
822 /// <param name="cdtArray">ArrayList containing start and end times of Appointments combmined and sorted</param>
823 /// <param name="dStartTime">Start Time for Schedule</param>
824 /// <param name="dEndTime">End Time for Schedule</param>
825 /// <param name="rTBArray">Output of Availabilities: Pass Empty</param>
826 public static void ScheduleFromArray(ArrayList cdtArray, DateTime dStartTime, DateTime dEndTime,
827 ref ArrayList rTBArray)
828 {
829 int j = 0;
830 CGAvailability cTB;
831
832 if (cdtArray.Count == 0)
833 return;
834
835 Debug.Assert(cdtArray.Count > 0);
836 Debug.Assert(cdtArray[0].GetType() == typeof(DateTime));
837
838 //If StartTime passed in, then adjust for it
839 if (dStartTime.Ticks > 0)
840 {
841 // if first Array Entry greater than start time, then create an availability
842 // with the start time as dStartTime, and end time as the first array entry, and 0 slots
843 // then add this to the output array
844 if ((DateTime) cdtArray[0] > dStartTime)
845 {
846 cTB = new CGAvailability();
847 cTB.Create(dStartTime, (DateTime) cdtArray[0], 0);
848 rTBArray.Add(cTB);
849 }
850
851 // if first Array Entry less than start time (shouldn't happen),
852 // convert all input array's times less than the start time to all be the start time
853 if ((DateTime) cdtArray[0] < dStartTime)
854 {
855 for (j = 0; j < cdtArray.Count; j++)
856 {
857 if ((DateTime) cdtArray[j] < dStartTime)
858 cdtArray[j] = dStartTime;
859 }
860 }
861 }
862
863 //Trim the end if necessary
864 //If end time is passed, set all the times in the original array greater
865 //than the end time to be the end time (Shouldn't happen).
866 if (dEndTime.Ticks > 0)
867 {
868 for (j = 0; j < cdtArray.Count; j++)
869 {
870 if ((DateTime) cdtArray[j] > dEndTime)
871 cdtArray[j] = dEndTime;
872 }
873 }
874
875 //build the schedule in rTBArray
876 DateTime dTemp = new DateTime(); //hold previous appt time.
877 DateTime dStart;
878 DateTime dEnd;
879 int k = 0;
880 //for each time in appointment array
881 for (j = 0; j < (cdtArray.Count -1); j++) // -1 b/c k below starts with j+1.
882 {
883 if ((DateTime) cdtArray[j] != dTemp)
884 {
885 dStart =(DateTime) cdtArray[j];
886 dTemp = dStart;
887
888 //for each time in appointment array, starting with the next one
889 for (k = j+1; k < cdtArray.Count; k++)
890 {
891 dEnd = new DateTime();
892 if ((DateTime) cdtArray[k] != dStart) //if the next time isn't the same
893 {
894 dEnd = (DateTime) cdtArray[k]; // set the end to be the next time
895 }
896 if (dEnd.Ticks > 0) //make a new availability and add it to the output array.
897 {
898 cTB = new CGAvailability();
899 cTB.Create(dStart, dEnd, 0);
900 rTBArray.Add(cTB);
901 break;
902 }
903 // if the end time is still empty, loop
904 }
905 }
906 }
907
908 }//end ScheduleFromArray
909 */
910
911 /*
912 //long CResourceLink::SlotsInBlock(CTimeBlock &rTimeBlock, _RecordsetPtr rsBlock)
913 public static int SlotsInBlock(CGAvailability rTimeBlock, DataTable rsBlock)
914 {
915 DateTime dStart1;
916 DateTime dStart2;
917 DateTime dEnd1;
918 DateTime dEnd2;
919 int nSlots = 0;
920
921 if (rsBlock.Rows.Count == 0)
922 return nSlots;
923
924 Rectangle rect1 = new Rectangle();
925 Rectangle rect2 = new Rectangle();
926 rect1.X = 0;
927 rect2.X = 0;
928 rect1.Width = 1;
929 rect2.Width = 1;
930
931 dStart1 = rTimeBlock.StartTime;
932 dEnd1 = rTimeBlock.EndTime;
933 rect1.Y = CGSchedLib.MinSince80(dStart1);
934 rect1.Height = CGSchedLib.MinSince80(dEnd1) - rect1.Y;
935
936 //for each row in the availability schedule
937 foreach (DataRow r in rsBlock.Rows)
938 {
939 dStart2 = (DateTime) r[rsBlock.Columns["START_TIME"]];
940 dEnd2 = (DateTime) r[rsBlock.Columns["END_TIME"]];
941
942 rect2.Y = CGSchedLib.MinSince80(dStart2);
943 rect2.Height = CGSchedLib.MinSince80(dEnd2) - rect2.Y;
944 if (rect2.IntersectsWith(rect1) == true)
945 {
946 string sSlots = r[rsBlock.Columns["SLOTS"]].ToString();
947 nSlots = System.Convert.ToInt16(sSlots);
948// nSlots = (int) r[rsBlock.Columns["SLOTS"]];
949 break;
950 }
951 }
952 return nSlots;
953 }//end SlotsInBlock
954 */
955
956 /*
957 public static string ClinicInBlock(CGAvailability rTimeBlock, DataTable rsBlock)
958 {
959 DateTime dStart1;
960 DateTime dStart2;
961 DateTime dEnd1;
962 DateTime dEnd2;
963 string sClinic = "";
964
965 if (rsBlock.Rows.Count == 0)
966 return sClinic;
967
968 Rectangle rect1 = new Rectangle();
969 Rectangle rect2 = new Rectangle();
970 rect1.X = 0;
971 rect2.X = 0;
972 rect1.Width = 1;
973 rect2.Width = 1;
974
975 dStart1 = rTimeBlock.StartTime;
976 dEnd1 = rTimeBlock.EndTime;
977 rect1.Y = CGSchedLib.MinSince80(dStart1);
978 rect1.Height = CGSchedLib.MinSince80(dEnd1) - rect1.Y;
979
980 foreach (DataRow r in rsBlock.Rows)
981 {
982 dStart2 = (DateTime) r[rsBlock.Columns["START_TIME"]];
983 dEnd2 = (DateTime) r[rsBlock.Columns["END_TIME"]];
984
985 rect2.Y = CGSchedLib.MinSince80(dStart2);
986 rect2.Height = CGSchedLib.MinSince80(dEnd2) - rect2.Y;
987 if (rect2.IntersectsWith(rect1) == true)
988 {
989 sClinic = r[rsBlock.Columns["SUBCLINIC"]].ToString();
990 break;
991 }
992 }
993 return sClinic;
994 }//end ClinicInBlock
995 */
996
997 /*
998 public static bool ResourceRulesInBlock(CGAvailability rTimeBlock, DataTable rsBlock, ref string sResourceList, ref string sAccessRuleList, ref string sNote)
999 {
1000 DateTime dStart1;
1001 DateTime dStart2;
1002 DateTime dEnd1;
1003 DateTime dEnd2;
1004 string sResource;
1005 string sAccessRule;
1006
1007 if (rsBlock.Rows.Count == 0)
1008 return true;
1009
1010 Rectangle rect1 = new Rectangle();
1011 Rectangle rect2 = new Rectangle();
1012 rect1.X = 0;
1013 rect2.X = 0;
1014 rect1.Width = 1;
1015 rect2.Width = 1;
1016
1017 dStart1 = rTimeBlock.StartTime;
1018 dEnd1 = rTimeBlock.EndTime;
1019 rect1.Y = CGSchedLib.MinSince80(dStart1);
1020 rect1.Height = CGSchedLib.MinSince80(dEnd1) - rect1.Y;
1021
1022 foreach (DataRow r in rsBlock.Rows)
1023 {
1024 dStart2 = (DateTime) r[rsBlock.Columns["START_TIME"]];
1025 dEnd2 = (DateTime) r[rsBlock.Columns["END_TIME"]];
1026
1027 rect2.Y = CGSchedLib.MinSince80(dStart2);
1028 rect2.Height = CGSchedLib.MinSince80(dEnd2) - rect2.Y;
1029 if (rect2.IntersectsWith(rect1) == true)
1030 {
1031 sResource = r[rsBlock.Columns["RESOURCE"]].ToString();
1032 if (sResource == "NULL")
1033 sResource = "";
1034 if (sResource != "")
1035 {
1036 if (sResourceList == "")
1037 {
1038 sResourceList += sResource;
1039 }
1040 else
1041 {
1042 sResourceList += "^" + sResource;
1043 }
1044 }
1045 sAccessRule = r[rsBlock.Columns["ACCESS_TYPE"]].ToString();
1046 if (sAccessRule == "0")
1047 sAccessRule = "";
1048 if (sAccessRule != "")
1049 {
1050 if (sAccessRuleList == "")
1051 {
1052 sAccessRuleList += sAccessRule;
1053 }
1054 else
1055 {
1056 sAccessRuleList += "^" + sAccessRule;
1057 }
1058 }
1059 sNote = r[rsBlock.Columns["NOTE"]].ToString();
1060
1061 }
1062 }
1063 return true;
1064 }//End ResourceRulesInBlock
1065 */
1066
1067
1068 }
1069}
Note: See TracBrowser for help on using the repository browser.