Ignore:
Timestamp:
Mar 3, 2011, 4:44:18 AM (13 years ago)
Author:
Sam Habiel
Message:

DPatientLookup.cs: Usings Cleanup
DApptSearch: Extensive refactoring. Now uses new algorithm to find appointments. Now outputs CGAvailability
CGView: Appointments checked in now set the Checkin time on the appointment structure; changes to support DApptSearch modified output.
CGSchedLib: Extensive refactoring; only 2 methods remain: CreateAppointmentSchedule and CreateAvailabilitySchedule
CGDocument: SlotsAvailable uses a new algorithm
CGAVView: Uses CalendarGrid.TimesOverlap instead of the removed one in CGSchedLib
CGAVDocument: Uses CalendarGrid.TimesOverlap instead of the removed one in CGSchedLib; CreateAssignedSlotSchedule reassigned to CreateAvailabilitySchedule

File:
1 edited

Legend:

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

    r1095 r1097  
    77using System.Windows.Forms;
    88using IndianHealthService.BMXNet;
     9using System.Linq;
    910
    1011namespace IndianHealthService.ClinicalScheduling
     
    627628        }
    628629
     630        /// <summary>
     631        /// Gets number of slots left in a certain selection on the grid. Used in Multiple Places.
     632        /// </summary>
     633        /// <param name="dSelStart">Selection Start Date</param>
     634        /// <param name="dSelEnd">Selection End Date</param>
     635        /// <param name="sResource">Resource Name</param>
     636        /// <param name="sAccessType">Out: Name of Access Type</param>
     637        /// <param name="sAvailabilityMessage">Out: Access Note</param>
     638        /// <returns>Number of slots</returns>
    629639        public int SlotsAvailable(DateTime dSelStart, DateTime dSelEnd, string sResource, out string sAccessType, out string sAvailabilityMessage)
    630640        {
     641
     642
     643            sAccessType = "";               //default out value
     644            sAvailabilityMessage = "";      //default out value
     645
     646            double slotsAvailable = 0;      //defalut return value
     647
     648            //NOTE: What's this lock? This lock makes sure that nobody is editing the availability array
     649            //when we are looking at it. Since the availability array could potentially be updated on
     650            //a different thread, we are can be potentially left stuck with an empty array.
     651            //
     652            //The other place that uses this lock is the RefershAvailabilitySchedule method
     653            //
     654            //This is a temporary fix until I figure out how to divorce the availbilities here from those drawn
     655            //on the calendar. Appointments are cloned b/c they are in an object that supports that; and b/c I
     656            //don't need to suddenly query them at runtime like I do with Availabilities.
     657
     658            //Let's Try Linq
     659            lock (this.m_pAvArray)
     660            {
     661                //This foreach loop looks for an availability that overlaps where the user clicked.
     662                //There can only be one, as availabilites cannot overlap each other (enforced at the DB level)
     663                //If selection hits multiple blocks, get the block with the most slots (reflected by the sorting here)
     664                CGAvailability[] pAVs = (from pAV in this.m_pAvArray.Cast<CGAvailability>()
     665                                         where (sResource == pAV.ResourceList && CalendarGrid.TimesOverlap(dSelStart, dSelEnd, pAV.StartTime, pAV.EndTime))
     666                                         orderby pAV.Slots descending
     667                                         select pAV)
     668                                         .ToArray<CGAvailability>();
     669
     670                if ((pAVs.Length) == 0) return 0;
     671
     672                slotsAvailable = pAVs[0].Slots;
     673                sAccessType = pAVs[0].AccessTypeName;
     674                sAvailabilityMessage = pAVs[0].Note;
     675
     676                //Subtract total slots current appointments take up.
     677                slotsAvailable -= (from appt in this.Appointments.AppointmentTable.Values.Cast<CGAppointment>()
     678                                   //If the resource is the same and the user selection overlaps, then...
     679                                   where (sResource == appt.Resource && CalendarGrid.TimesOverlap(pAVs[0].StartTime, pAVs[0].EndTime, appt.StartTime, appt.EndTime))
     680                                   // if appt starttime is before avail start time, only count against the avail starting from the availability start time
     681                                   let startTimeToCountAgainstBlock = appt.StartTime < pAVs[0].StartTime ? pAVs[0].StartTime : appt.StartTime
     682                                   // if appt endtime is after the avail ends, only count against the avail up to where the avail ends
     683                                   let endTimeToCountAgainstBlock = appt.EndTime > pAVs[0].EndTime ? pAVs[0].EndTime : appt.EndTime
     684                                   // theoretical minutes per slot for the availability
     685                                   let minPerSlot = (pAVs[0].EndTime - pAVs[0].StartTime).TotalMinutes / pAVs[0].Slots
     686                                   // how many minutes does this appointment take away from the slot
     687                                   let minPerAppt = (endTimeToCountAgainstBlock - startTimeToCountAgainstBlock).TotalMinutes
     688                                   // how many slots the appointment takes up using this availability's scale
     689                                   let slotsConsumed = minPerAppt / minPerSlot
     690                                   select slotsConsumed)
     691                                   // add up SlotsConsumed to substract from slotsAvailable
     692                                   .Sum();
     693            }
     694
     695            return (int)slotsAvailable;
     696
     697            /* OLD ALGOTHRIM 2
     698
     699            lock (this.m_pAvArray)
     700            {
     701                //This foreach loop looks for an availability that overlaps where the user clicked.
     702                //There can only be one, as availabilites cannot overlap each other (enforced at the DB level)
     703                //Therefore, we loop, and once we find it, we break.
     704                foreach (CGAvailability pAV in this.m_pAvArray)
     705                {
     706                    //If the resource is the same and the user selection overlaps, then...
     707                    if (sResource == pAV.ResourceList && CalendarGrid.TimesOverlap(dSelStart, dSelEnd, pAV.StartTime, pAV.EndTime))
     708                    {
     709                        slotsAvailable = pAV.Slots;         //variable now holds the total number of slots
     710                        sAccessType = pAV.AccessTypeName;   //Access Name
     711                        sAvailabilityMessage = pAV.Note;    //Access Block Note
     712                       
     713                        //Here we substract each appointment weight in slots from slotsAvailable
     714                        foreach (DictionaryEntry apptDict in this.m_appointments.AppointmentTable)
     715                        {
     716                            CGAppointment appt = (CGAppointment)apptDict.Value;
     717                            //If the appointment is in the same resource and overlaps with this availablity
     718                            if (sResource == appt.Resource && CalendarGrid.TimesOverlap(pAV.StartTime, pAV.EndTime, appt.StartTime, appt.EndTime))
     719                            {
     720                                // if appt starttime is before avail start time, only count against the avail starting from the availability start time
     721                                DateTime startTimeToCountAgainstBlock = appt.StartTime < pAV.StartTime ? pAV.StartTime : appt.StartTime;
     722                                // if appt endtime is after the avail ends, only count against the avail up to where the avail ends
     723                                DateTime endTimeToCountAgainstBlock = appt.EndTime > pAV.EndTime ? pAV.EndTime : appt.EndTime;
     724                                // theoretical minutes per slot for the availability
     725                                double minPerSlot = (pAV.EndTime - pAV.StartTime).TotalMinutes/pAV.Slots;
     726                                // how many minutes does this appointment take away from the slot
     727                                double minPerAppt = (endTimeToCountAgainstBlock - startTimeToCountAgainstBlock).TotalMinutes;
     728                                // how many slots the appointment takes up using this availability's scale
     729                                double slotsConsumed = minPerAppt / minPerSlot;
     730                                // subscract that from the total slots for the availability
     731                                slotsAvailable -= slotsConsumed;
     732                            } //end if
     733                            //now go to the next appointment in foreach
     734                        }
     735                        // As I said above, we can match only one availability. Once we found it and substracted from it; we are done.
     736                        break;
     737                    }
     738                }
     739                // We return the integer portion of the variable for display to the user or for calculations.
     740                // That means, if 2.11 slots are left, the user sees 2. If 2.66, still 2.
     741                return (int)slotsAvailable;
     742            }
     743            */
     744
     745            /* ORIGINAL ALGORITHM
    631746            sAccessType = "";
    632747            sAvailabilityMessage = "";
     
    695810            }
    696811            return nAvailableSlots;
     812            */
    697813        }
    698814
Note: See TracChangeset for help on using the changeset viewer.