Ignore:
Timestamp:
Feb 21, 2011, 9:21:24 AM (14 years ago)
Author:
Sam Habiel
Message:

Remove CGSchedLib.OutputArray everywhere. Used to be needed in VS 2003; not anymore as you can see tables now.
CalendarGrid:

  • Make MinSince80 and TimesOverlap static functions for use by other classes since they are done over and over again.

CGAppointments:

  • Documentation updates

CGAVDocument:

CGDocument:

CGDocumentManager:

CGSchedLib: Lots of Changes

CGView:

  • OnUpdateScheduleCallback now has try catch when it this.Invokes the original form so that it won't crash if the form has been closed before it gets called.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Scheduling/trunk/cs/bsdx0200GUISourceCode/CGSchedLib.cs

    r1011 r1095  
    1919        /// scheduling application.
    2020        /// </summary>
    21         public class CGSchedLib
     21        public static class CGSchedLib
    2222        {
    23                 public CGSchedLib()
    24                 {
    25 
    26                 }
    27 
    2823        /// <summary>
    2924        /// Gets appointments from VISTA to display in Grid
     
    5348                }
    5449
    55                 public static void OutputArray(DataTable dt, string sName)
    56                 {
    57 #if (DEBUG && OUTPUTARRAY)
    58                         Debug.Write("\n " + sName + " OutputArray:\n");
    59                         if (dt == null)
    60                                 return;
    61 
    62                         foreach (DataColumn c in dt.Columns)
    63                         {
    64                                 Debug.Write(c.ToString());
    65                         }
    66                         Debug.Write("\n");
    67                         foreach (DataRow r in dt.Rows)
    68                         {
    69                                 foreach (DataColumn c in dt.Columns)
    70                                 {
    71                                         Debug.Write(r[c].ToString());
    72                                 }
    73                                 Debug.Write("\n");
    74                         }                       
    75                         Debug.Write("\n");
    76 #endif
    77                 }
    78 
     50
     51        /// <summary>
     52        /// Gets all Availabilities and Appointments, then substracts Appointments from availabilities.
     53        /// </summary>
     54        /// <param name="docManager">God Class</param>
     55        /// <param name="saryResourceNames">Resource Array (ArrayList)</param>
     56        /// <param name="StartTime">Self-Explanatory</param>
     57        /// <param name="EndTime">Self-Explanatory</param>
     58        /// <param name="saryApptTypes">Array of Access Type IDs</param>
     59        /// <param name="stType"></param>
     60        /// <param name="sSearchInfo"></param>
     61        /// <returns></returns>
    7962                public static DataTable CreateAvailabilitySchedule(CGDocumentManager docManager,
    8063                        ArrayList saryResourceNames, DateTime StartTime, DateTime EndTime,
     
    9578                       
    9679                        string sResName;
     80            //TODO: Optimize: no need to keep looping through resources.
    9781            // for each resource
    9882                        for (int i = 0; i < nSize; i++)
    9983                        {
    10084                                sResName = saryResourceNames[i].ToString();
    101                 //Gets all the slots (or Availabities, if you like)
     85                //Gets all the slots (or Availabities, or AV Blocks if you like)
    10286                                rsSlotSchedule = CGSchedLib.CreateAssignedSlotSchedule(docManager, sResName, StartTime, EndTime, saryApptTypes,/**/ stType, sSearchInfo);
    103                                 OutputArray(rsSlotSchedule, "rsSlotSchedule");
     87                               
    10488                //if we have slots
    10589                                if (rsSlotSchedule.Rows.Count > 0 )
     
    10791                    // Get appointment count to substract from the slots
    10892                                        rsApptSchedule = CGSchedLib.CreateAppointmentSlotSchedule(docManager, sResName, StartTime, EndTime, stType);
    109                                         OutputArray(rsApptSchedule, "rsApptSchedule");
     93
    11094                    // Perform the substraction
    11195                                        rsTemp1 = CGSchedLib.SubtractSlotsRS2(rsSlotSchedule, rsApptSchedule, sResName);
    112                                         OutputArray(rsTemp1, "rsTemp1");
    113                                 }
     96
     97                                }
     98                //otherwise, just return the slot schedule we have.
    11499                                else
    115100                                {
    116101                                        rsTemp1 = rsSlotSchedule;
    117                                         OutputArray(rsTemp1, "rsTemp1");
    118                                 }
     102
     103                                }
     104
    119105                // if only one resource was passed in, its availablility is what we want
    120106                                if (i == 0)
    121107                                {
    122108                                        rsOut = rsTemp1;
    123                                         OutputArray(rsOut, "rsOut");
    124                                 }
     109
     110                                }
     111                // if more than one resource, merge them together
    125112                                else
    126113                                {
    127114                                        rsOut = CGSchedLib.UnionBlocks(rsTemp1, rsOut);
    128                                         OutputArray(rsOut, "United rsOut");
    129115                                }
    130116                        }
     
    133119
    134120
     121        /* NOT USED ANYMORE!!!
    135122                public static DataTable CreateAssignedTypeSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime, DateTime EndTime, ScheduleType stType)
    136123                {
    137124
    138                         string sStart;
    139                         string sEnd;
    140                         //sStart = StartTime.ToString("M-d-yyyy");
    141             sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
    142                         //sEnd = EndTime.ToString("M-d-yyyy");
    143             sEnd = FMDateTime.Create(EndTime).DateOnly.FMDateString;
    144 //                      string sSource = (stType == ScheduleType.Resource ? "ST_RESOURCE" : "ST_CLINIC");
    145                         string sSql = "BSDX TYPE BLOCKS OVERLAP^" + sStart + "^" + sEnd + "^" + sResourceName ;//+ "^" + sSource;
     125            string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
     126                        string sEnd = FMDateTime.Create(EndTime).DateOnly.FMDateString;
     127            string sSql = "BSDX TYPE BLOCKS OVERLAP^" + sStart + "^" + sEnd + "^" + sResourceName;
    146128
    147129                        DataTable rs = docManager.RPMSDataTable(sSql, "AssignedTypeSchedule");
     
    176158
    177159                        dCol = new DataColumn();
    178                         //dCol.DataType = Type.GetType("System.Int16");
    179             dCol.DataType = Type.GetType("System.Int32"); //MJL 11/17/2006
     160            dCol.DataType = Type.GetType("System.Int32");
    180161            dCol.ColumnName = "AvailabilityID";
    181162                        dCol.ReadOnly = true;
     
    196177                        DateTime dStart;
    197178                        DateTime dEnd;
    198 //                      DataRow r;
    199                         DataRow rNew;
    200 
     179                        DataRow rNew; //Temporary Holding place for first or last row
     180
     181            // Get Last Date from final row
    201182                        rNew = rs.Rows[rs.Rows.Count - 1];
    202183                        dLastEnd = (DateTime) rNew["EndTime"];
     184            // Get First Date from first row
    203185                        rNew = rs.Rows[0];
    204186                        dStart = (DateTime) rNew["StartTime"];
     
    210192                        // then pad with a new block
    211193
     194            // if First Row time is later than the StartTime param (should always be true)
     195            // then make a new row whose time starts from StartTime and ends with dStart
    212196                        if (dStart > StartTime)
    213197                        {
     
    222206                        }       
    223207                       
    224                         //if first block start time is < StartTime then trim
     208                        //if first block start time is < StartTime then trim (shouldn't happen)
    225209                        if (dStart < StartTime)
    226210                        {
     
    233217                        int nAvailabilityID;
    234218
     219            //dStart holds the first date for the availabilities returned from RPMS
    235220                        dEnd = dStart;
    236221                        foreach (DataRow rEach in rs.Rows)
     
    248233                                }
    249234
     235                //dEnd now EndTime for AV Block
    250236                                dEnd = (DateTime) rEach["EndTime"];
    251237
    252                                 if (dEnd > EndTime)
    253                                         dEnd = EndTime;
     238                // if dEnd is greater than endime, set dEnd to be the same as EndTime.
     239                if (dEnd > EndTime) { dEnd = EndTime; }
     240
     241
    254242                                nAppointmentTypeID = (int) rEach["AppointmentTypeID"];
    255243                                nAvailabilityID = (int) rEach["AvailabilityID"];
     
    275263                                rsCopy.Rows.Add(rNew);         
    276264                        }
    277                         OutputArray(rsCopy, "CreateAssignedTypeSchedule");
     265                       
    278266                        return rsCopy;
    279267                }
    280 
    281                 public static DataTable CreateAssignedSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime, DateTime EndTime, ArrayList rsaryApptTypeIDs, /**/ ScheduleType stType, string sSearchInfo)
    282                 {
    283 
    284                         //Appointment type ids is now always "" so that all appointment types are returned.
     268        */
     269
     270        /// <summary>
     271        /// Gets the Availability Slots from the Server
     272        /// </summary>
     273        /// <param name="docManager">God Class</param>
     274        /// <param name="sResourceName">Resource for which to get slots</param>
     275        /// <param name="StartTime"></param>
     276        /// <param name="EndTime"></param>
     277        /// <param name="rsaryApptTypeIDs">Access Type IDs to retrieve</param>
     278        /// <param name="stType">Not used</param>
     279        /// <param name="sSearchInfo">If performing a slot search (i.e. for empty appointments), has search info here. Used by Find Appointments</param>
     280        /// <returns>DataTable with the following Columns:
     281        /// D00030START_TIME^D00030END_TIME^I00010SLOTS^T00030RESOURCE^T00010ACCESS_TYPE^T00250NOTE^I00030AVAILABILITYID
     282        /// </returns>
     283                public static DataTable CreateAssignedSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime,
     284            DateTime EndTime, ArrayList rsaryApptTypeIDs, /**/ ScheduleType stType, string sSearchInfo)
     285                {
     286            //Appointment type ids is now always "" so that all appointment types are returned.
    285287                        string sApptTypeIDs = "";
    286288                       
    287                         //The following code block is not used now, but keep for possible later use:
    288                         //Unpack the Appointment Type IDs
    289                         /*
    290                         */
    291                         int nSize = rsaryApptTypeIDs.Count;
     289            //flatten types by '|'
     290                        int nSize = rsaryApptTypeIDs.Count;  //nSize is used to decide where to put the '|' sent in the RPC as we flatten sApptTypeIDs
    292291                        for (int i=0; i < nSize; i++)
    293292                        {
     
    297296                        }       
    298297       
    299                         string sStart;
    300                         string sEnd;
    301                         //sStart = StartTime.ToString("M-d-yyyy"); smh
    302             sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
    303                         //sEnd = EndTime.ToString("M-d-yyyy@H:mm"); smh
    304             sEnd = FMDateTime.Create(EndTime).FMDateString;
     298            string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
     299            string sEnd = FMDateTime.Create(EndTime).FMDateString;
    305300                        string sSql = "BSDX CREATE ASGND SLOT SCHED^" + sResourceName + "^" + sStart + "^" + sEnd + "^" + sApptTypeIDs + "^" + sSearchInfo; //+ "^" + sSTType ;
    306 
    307301                        DataTable dtRet = docManager.RPMSDataTable(sSql, "AssignedSlotSchedule");
    308302
    309                         if (sResourceName == "")
    310                         {
    311                                 return dtRet;
    312                         }
    313 
    314                         return dtRet;
     303            return dtRet;
    315304                }
    316305
     
    370359                }
    371360
     361        /// <summary>
     362        /// This gets a datatable which shows the appointments between start and end time, one row per appointment
     363        /// </summary>
     364        /// <param name="docManager"></param>
     365        /// <param name="sResourceName"></param>
     366        /// <param name="StartTime"></param>
     367        /// <param name="EndTime"></param>
     368        /// <param name="stType"></param>
     369        /// <returns>DataTable with 4 columns: START_TIME, END_TIME, SLOTS, RESOURCE </returns>
    372370                public static DataTable CreateAppointmentSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime, DateTime EndTime, ScheduleType stType)
    373371                {
    374 
    375 
    376                         string sStart;
    377                         string sEnd;
    378                         //sStart = StartTime.ToString("M-d-yyyy");
    379             sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
    380                         //sEnd = EndTime.ToString("M-d-yyyy");
    381             sEnd = FMDateTime.Create(EndTime).DateOnly.FMDateString;
    382 
    383                         string sSTType = (stType == ScheduleType.Resource ? "ST_RESOURCE" : "ST_CLINIC");
     372            //Change Dates to FM Format
     373            string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
     374                        string sEnd = FMDateTime.Create(EndTime).DateOnly.FMDateString;
     375                       
     376            string sSTType = (stType == ScheduleType.Resource ? "ST_RESOURCE" : "ST_CLINIC");
    384377                        string sSql = "BSDX APPT BLOCKS OVERLAP^" + sStart + "^" + sEnd + "^" + sResourceName ;//+ "^"  + sSTType;
    385378
     379            //This gets you a table with 2 columns containing start and end time for each appt
     380            //Each appt gets its own row
    386381                        DataTable dtRet = docManager.RPMSDataTable(sSql, "AppointmentSlotSchedule");
    387382                       
     
    390385                       
    391386                        //Create CDateTimeArray & load records from rsOut
    392                         int nRC;
    393                         nRC = dtRet.Rows.Count;
     387                        int nRC = dtRet.Rows.Count;     // nRC is row count from Appointments table just retrieved
    394388                        ArrayList cdtArray = new ArrayList();
    395                         cdtArray.Capacity = (nRC * 2);
     389                        cdtArray.Capacity = (nRC * 2); //new ArrayList has capacity double that of appointment table
    396390                        DateTime v;
    397391                        int i = 0;
    398392
    399                         foreach (DataRow r in dtRet.Rows)
     393                        //for each row in the Appointment Table, ArrayList cdtArray gets 2 entries: Start and End times
     394            foreach (DataRow r in dtRet.Rows)
    400395                        {
    401396                                v = (DateTime) r[dtRet.Columns["START_TIME"]];
     
    404399                                cdtArray.Add(v);
    405400                        }
     401
     402            //Sort start and end times (for use in ScheduleFromArray method)
    406403                        cdtArray.Sort();
    407404
    408405                        //Create a CTimeBlockArray and load it from rsOut
    409406               
     407            //Now, create a new ArrayList with the size of the appointment table to hold availabilities
    410408                        ArrayList ctbAppointments = new ArrayList(nRC);
    411409                        CGAvailability cTB;
    412410                        i = 0;
     411            //For each appointment, create an availability
    413412                        foreach (DataRow r in dtRet.Rows)
    414413                        {
     
    421420                        //Create a TimeBlock Array from the data in the DateTime array
    422421                        ArrayList ctbApptSchedule = new ArrayList();
     422
     423            //Convert Appointments to Availabilities, where all appointments become squeezed together.
    423424                        ScheduleFromArray(cdtArray, StartTime, EndTime, ref ctbApptSchedule);
    424                        
    425                         //Find number of TimeBlocks in ctbApptSchedule that
    426                         //overlap the TimeBlocks in ctbAppointments
     425
     426            /*So far, we have the following:
     427             * dtRet -> List of Appointments Start and End times, one row per appointment
     428             * cdtArray -> Linear 1 dimensional Array of dtRet Start and End times, sorted
     429             * ctbAppointments -> Arraylist of dtRet as Availabilities
     430             * ctbApptSchedule -> Arraylist of dtRet as Availabilities with no overlapping boundaries
     431             *      (overlaps in appointments get converted into availabilties themselves: so
     432             *      2 appts as 10:10-10:30 and 10:20-10:40 get converted into 10:10-10:20,
     433             *      10:20-10:30, 10:30-10:40).
     434            */
     435
     436            //Find number of TimeBlocks in ctbApptSchedule that overlap the TimeBlocks in ctbAppointments
    427437                        ArrayList ctbApptSchedule2 = new ArrayList();
    428438                        CGAvailability cTB2;
    429439                        int nSlots = 0;
    430                         for (i=0; i< ctbApptSchedule.Count; i++)
     440                        for (i=0; i< ctbApptSchedule.Count; i++)    //for each non-overlapping appts as availabilities
    431441                        {
    432442                                cTB = (CGAvailability) ctbApptSchedule[i];
    433                                 nSlots = BlocksOverlap(cTB, ctbAppointments);
     443                //How many times does the non-overlapping part show up in an appointment slot?
     444                                nSlots = BlocksOverlap(cTB, ctbAppointments);   
    434445                                cTB2 = new CGAvailability();
    435446                                cTB2.Create(cTB.StartTime, cTB.EndTime, nSlots);
     
    532543                }
    533544
    534                 //BOOL CResourceLink::TimesOverlap(COleDateTime dStart1, COleDateTime dEnd1, COleDateTime dStart2, COleDateTime dEnd2)
     545                /// <summary>
     546                /// Does an appointment overlap with another appointment in the same day?
     547                /// </summary>
     548                /// <param name="dStart1">Start Time of First Appt</param>
     549                /// <param name="dEnd1">End Time of First Appt</param>
     550        /// <param name="dStart2">Start Time of Second Appt</param>
     551                /// <param name="dEnd2">End Time of Second Appt</param>
     552                /// <returns>true or false</returns>
     553        /// <remarks>Draws 2 rectangles and sees if they overlap using minutes from 1980 as the start point</remarks>
    535554                public static bool TimesOverlap(DateTime dStart1, DateTime dEnd1, DateTime dStart2, DateTime dEnd2)
    536555                {
     
    667686                        Debug.Assert(rs1 != null);
    668687                        Debug.Assert(rs2 != null);
    669                         CGSchedLib.OutputArray(rs1, "UnionBlocks rs1");
    670                         CGSchedLib.OutputArray(rs2, "UnionBlocks rs2");
    671688                       
    672689                        DataTable rsCopy;
     
    798815                }
    799816
    800                 public static void ScheduleFromArray(ArrayList cdtArray, DateTime dStartTime, DateTime dEndTime, ref ArrayList rTBArray)
     817        /// <summary>
     818        /// Converts an Array of Times like this:
     819        /// 10:00 10:00 10:20 10:20 10:30 10:30 10:30 10:40
     820        /// To an array of availabilities like this:
     821        /// 12:00-10:00 10:00-10:20 10:20-10:30 10:30-10:40
     822        /// Where the 12:00 comes from the start time
     823        /// </summary>
     824        /// <param name="cdtArray">ArrayList containing start and end times of Appointments combmined and sorted</param>
     825        /// <param name="dStartTime">Start Time for Schedule</param>
     826        /// <param name="dEndTime">End Time for Schedule</param>
     827        /// <param name="rTBArray">Output of Availabilities: Pass Empty</param>
     828                public static void ScheduleFromArray(ArrayList cdtArray, DateTime dStartTime, DateTime dEndTime,
     829            ref ArrayList rTBArray)
    801830                {
    802831                        int j = 0;
     
    812841                        if (dStartTime.Ticks > 0)
    813842                        {
    814                                 if ((DateTime) cdtArray[0] > dStartTime)
     843                                // if first Array Entry greater than start time, then create an availability
     844                // with the start time as dStartTime, and end time as the first array entry, and 0 slots
     845                // then add this to the output array
     846                if ((DateTime) cdtArray[0] > dStartTime)
    815847                                {
    816848                                        cTB = new CGAvailability();
     
    818850                                        rTBArray.Add(cTB);
    819851                                }
     852
     853                // if first Array Entry less than start time (shouldn't happen),
     854                // convert all input array's times less than the start time to all be the start time
    820855                                if ((DateTime) cdtArray[0] < dStartTime)
    821856                                {
     
    829864
    830865                        //Trim the end if necessary
     866            //If end time is passed, set all the times in the original array greater
     867            //than the end time to be the end time (Shouldn't happen).
    831868                        if (dEndTime.Ticks > 0)
    832869                        {
     
    839876
    840877                        //build the schedule in rTBArray
    841                         DateTime dTemp = new DateTime();
     878                        DateTime dTemp = new DateTime(); //hold previous appt time.
    842879                        DateTime dStart;
    843880                        DateTime dEnd;
    844881                        int k = 0;
    845                         for (j = 0; j < (cdtArray.Count -1); j++) //TODO: why minus 1?
     882            //for each time in appointment array
     883                        for (j = 0; j < (cdtArray.Count -1); j++) // -1 b/c k below starts with j+1.
    846884                        {
    847885                                if ((DateTime) cdtArray[j] != dTemp)
     
    849887                                        dStart =(DateTime) cdtArray[j];
    850888                                        dTemp = dStart;
     889                   
     890                    //for each time in appointment array, starting with the next one
    851891                                        for (k = j+1; k < cdtArray.Count; k++)
    852892                                        {
    853893                                                dEnd = new DateTime();
    854                                                 if ((DateTime) cdtArray[k] != dStart)
     894                                                if ((DateTime) cdtArray[k] != dStart) //if the next time isn't the same
    855895                                                {
    856                                                         dEnd = (DateTime) cdtArray[k];
     896                                                        dEnd = (DateTime) cdtArray[k]; // set the end to be the next time
    857897                                                }
    858                                                 if (dEnd.Ticks > 0)
     898                                                if (dEnd.Ticks > 0) //make a new availability and add it to the output array.
    859899                                                {
    860900                                                        cTB = new CGAvailability();
     
    863903                                                        break;
    864904                                                }
     905                        // if the end time is still empty, loop
    865906                                        }
    866907                                }
Note: See TracChangeset for help on using the changeset viewer.