source: Scheduling/trunk/cs/bsdx0200GUISourceCode/CGSchedLib.cs@ 850

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

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

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