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
This commit is contained in:
sam 2011-03-03 09:44:18 +00:00
parent 7524c52392
commit d347c2d7d8
12 changed files with 617 additions and 349 deletions

View File

@ -168,7 +168,7 @@ namespace IndianHealthService.ClinicalScheduling
{
DateTime sStart2 = a.StartTime;
DateTime sEnd2 = a.EndTime;
if ((a.AppointmentKey != pAppt.AppointmentKey) && (CGSchedLib.TimesOverlap(dNewStart, dNewEnd, a.StartTime, a.EndTime)))
if ((a.AppointmentKey != pAppt.AppointmentKey) && (CalendarGrid.TimesOverlap(dNewStart, dNewEnd, a.StartTime, a.EndTime)))
{
MessageBox.Show("Access blocks may not overlap.","Clinical Scheduling", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
@ -297,7 +297,7 @@ namespace IndianHealthService.ClinicalScheduling
{
DateTime sStart2 = a.StartTime;
DateTime sEnd2 = a.EndTime;
if (CGSchedLib.TimesOverlap(aCopy.StartTime, aCopy.EndTime, a.StartTime, a.EndTime))
if (CalendarGrid.TimesOverlap(aCopy.StartTime, aCopy.EndTime, a.StartTime, a.EndTime))
{
// throw new Exception("Access blocks may not overlap.");
MessageBox.Show("Access blocks may not overlap.","Clinical Scheduling", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
@ -373,7 +373,7 @@ namespace IndianHealthService.ClinicalScheduling
ArrayList apptTypeIDs = new ArrayList();
rAppointmentSchedule = CGSchedLib.CreateAssignedSlotSchedule(m_DocManager, (string) m_sResourcesArray[0], this.m_dStartDate, this.m_dEndDate, apptTypeIDs,/* */ this.m_ScheduleType, "0");
rAppointmentSchedule = CGSchedLib.CreateAvailabilitySchedule(m_DocManager, m_sResourcesArray, this.m_dStartDate, this.m_dEndDate, apptTypeIDs,/* */ this.m_ScheduleType, "0");
foreach (DataRow r in rAppointmentSchedule.Rows)
{

View File

@ -105,7 +105,7 @@ namespace IndianHealthService.ClinicalScheduling
this.panelRight.Dock = System.Windows.Forms.DockStyle.Right;
this.panelRight.Location = new System.Drawing.Point(728, 0);
this.panelRight.Name = "panelRight";
this.panelRight.Size = new System.Drawing.Size(120, 364);
this.panelRight.Size = new System.Drawing.Size(120, 343);
this.panelRight.TabIndex = 1;
//
// panelClip
@ -166,7 +166,7 @@ namespace IndianHealthService.ClinicalScheduling
//
this.panelBottom.Controls.Add(this.statusBar1);
this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panelBottom.Location = new System.Drawing.Point(8, 340);
this.panelBottom.Location = new System.Drawing.Point(8, 319);
this.panelBottom.Name = "panelBottom";
this.panelBottom.Size = new System.Drawing.Size(720, 24);
this.panelBottom.TabIndex = 2;
@ -194,10 +194,9 @@ namespace IndianHealthService.ClinicalScheduling
//
this.dateTimePicker1.Dock = System.Windows.Forms.DockStyle.Right;
this.dateTimePicker1.DropDownAlign = System.Windows.Forms.LeftRightAlignment.Right;
this.dateTimePicker1.Format = System.Windows.Forms.DateTimePickerFormat.Short;
this.dateTimePicker1.Location = new System.Drawing.Point(592, 0);
this.dateTimePicker1.Location = new System.Drawing.Point(517, 0);
this.dateTimePicker1.Name = "dateTimePicker1";
this.dateTimePicker1.Size = new System.Drawing.Size(128, 20);
this.dateTimePicker1.Size = new System.Drawing.Size(203, 20);
this.dateTimePicker1.TabIndex = 4;
this.dateTimePicker1.ValueChanged += new System.EventHandler(this.dateTimePicker1_ValueChanged);
//
@ -218,7 +217,7 @@ namespace IndianHealthService.ClinicalScheduling
this.panelCenter.Dock = System.Windows.Forms.DockStyle.Fill;
this.panelCenter.Location = new System.Drawing.Point(8, 24);
this.panelCenter.Name = "panelCenter";
this.panelCenter.Size = new System.Drawing.Size(712, 316);
this.panelCenter.Size = new System.Drawing.Size(712, 295);
this.panelCenter.TabIndex = 4;
//
// ctxCalendarGrid
@ -254,7 +253,7 @@ namespace IndianHealthService.ClinicalScheduling
this.tvSchedules.HotTracking = true;
this.tvSchedules.Location = new System.Drawing.Point(0, 0);
this.tvSchedules.Name = "tvSchedules";
this.tvSchedules.Size = new System.Drawing.Size(8, 364);
this.tvSchedules.Size = new System.Drawing.Size(8, 343);
this.tvSchedules.Sorted = true;
this.tvSchedules.TabIndex = 5;
//
@ -455,7 +454,7 @@ namespace IndianHealthService.ClinicalScheduling
this.splitter1.Dock = System.Windows.Forms.DockStyle.Right;
this.splitter1.Location = new System.Drawing.Point(720, 24);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(8, 316);
this.splitter1.Size = new System.Drawing.Size(8, 295);
this.splitter1.TabIndex = 6;
this.splitter1.TabStop = false;
//
@ -485,19 +484,19 @@ namespace IndianHealthService.ClinicalScheduling
this.calendarGrid1.Name = "calendarGrid1";
this.calendarGrid1.Resources = ((System.Collections.ArrayList)(resources.GetObject("calendarGrid1.Resources")));
this.calendarGrid1.SelectedAppointment = 0;
this.calendarGrid1.Size = new System.Drawing.Size(712, 316);
this.calendarGrid1.Size = new System.Drawing.Size(712, 295);
this.calendarGrid1.StartDate = new System.DateTime(2003, 1, 27, 0, 0, 0, 0);
this.calendarGrid1.TabIndex = 2;
this.calendarGrid1.TimeScale = 20;
this.calendarGrid1.CGAppointmentAdded += new CalendarGrid.CGAppointmentChangedHandler(this.calendarGrid1_CGAppointmentAdded);
this.calendarGrid1.CGAppointmentChanged += new CalendarGrid.CGAppointmentChangedHandler(this.calendarGrid1_CGAppointmentChanged);
this.calendarGrid1.CGSelectionChanged += new CalendarGrid.CGSelectionChangedHandler(this.calendarGrid1_CGSelectionChanged);
this.calendarGrid1.CGAppointmentChanged += new IndianHealthService.ClinicalScheduling.CalendarGrid.CGAppointmentChangedHandler(this.calendarGrid1_CGAppointmentChanged);
this.calendarGrid1.CGAppointmentAdded += new IndianHealthService.ClinicalScheduling.CalendarGrid.CGAppointmentChangedHandler(this.calendarGrid1_CGAppointmentAdded);
this.calendarGrid1.CGSelectionChanged += new IndianHealthService.ClinicalScheduling.CalendarGrid.CGSelectionChangedHandler(this.calendarGrid1_CGSelectionChanged);
this.calendarGrid1.DoubleClick += new System.EventHandler(this.calendarGrid1_DoubleClick);
//
// CGAVView
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(848, 364);
this.ClientSize = new System.Drawing.Size(848, 343);
this.Controls.Add(this.panelCenter);
this.Controls.Add(this.splitter1);
this.Controls.Add(this.panelTop);
@ -726,7 +725,7 @@ namespace IndianHealthService.ClinicalScheduling
{
DateTime sStart2 = a.StartTime;
DateTime sEnd2 = a.EndTime;
if (CGSchedLib.TimesOverlap(dStart, dEnd, a.StartTime, a.EndTime))
if (CalendarGrid.TimesOverlap(dStart, dEnd, a.StartTime, a.EndTime))
{
MessageBox.Show("Access blocks may not overlap.","Clinical Scheduling", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;

View File

@ -112,15 +112,15 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="ctxApptClipMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="ctxApptClipMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="ctxCalendarGrid.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="ctxCalendarGrid.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>151, 17</value>
</metadata>
<data name="calendarGrid1.Resources" mimetype="application/x-microsoft.net.object.binary.base64">
@ -129,13 +129,13 @@
bXMFX3NpemUIX3ZlcnNpb24FAAAICAkCAAAAAAAAAAAAAAAQAgAAAAAAAAAL
</value>
</data>
<metadata name="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>281, 17</value>
</metadata>
<metadata name="saveAccessBlocksWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="saveAccessBlocksWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>398, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAIAC

View File

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using IndianHealthService.BMXNet;
using System.Linq;
namespace IndianHealthService.ClinicalScheduling
{
@ -626,8 +627,122 @@ namespace IndianHealthService.ClinicalScheduling
this.m_sResourcesArray.Add(sResource);
}
/// <summary>
/// Gets number of slots left in a certain selection on the grid. Used in Multiple Places.
/// </summary>
/// <param name="dSelStart">Selection Start Date</param>
/// <param name="dSelEnd">Selection End Date</param>
/// <param name="sResource">Resource Name</param>
/// <param name="sAccessType">Out: Name of Access Type</param>
/// <param name="sAvailabilityMessage">Out: Access Note</param>
/// <returns>Number of slots</returns>
public int SlotsAvailable(DateTime dSelStart, DateTime dSelEnd, string sResource, out string sAccessType, out string sAvailabilityMessage)
{
sAccessType = ""; //default out value
sAvailabilityMessage = ""; //default out value
double slotsAvailable = 0; //defalut return value
//NOTE: What's this lock? This lock makes sure that nobody is editing the availability array
//when we are looking at it. Since the availability array could potentially be updated on
//a different thread, we are can be potentially left stuck with an empty array.
//
//The other place that uses this lock is the RefershAvailabilitySchedule method
//
//This is a temporary fix until I figure out how to divorce the availbilities here from those drawn
//on the calendar. Appointments are cloned b/c they are in an object that supports that; and b/c I
//don't need to suddenly query them at runtime like I do with Availabilities.
//Let's Try Linq
lock (this.m_pAvArray)
{
//This foreach loop looks for an availability that overlaps where the user clicked.
//There can only be one, as availabilites cannot overlap each other (enforced at the DB level)
//If selection hits multiple blocks, get the block with the most slots (reflected by the sorting here)
CGAvailability[] pAVs = (from pAV in this.m_pAvArray.Cast<CGAvailability>()
where (sResource == pAV.ResourceList && CalendarGrid.TimesOverlap(dSelStart, dSelEnd, pAV.StartTime, pAV.EndTime))
orderby pAV.Slots descending
select pAV)
.ToArray<CGAvailability>();
if ((pAVs.Length) == 0) return 0;
slotsAvailable = pAVs[0].Slots;
sAccessType = pAVs[0].AccessTypeName;
sAvailabilityMessage = pAVs[0].Note;
//Subtract total slots current appointments take up.
slotsAvailable -= (from appt in this.Appointments.AppointmentTable.Values.Cast<CGAppointment>()
//If the resource is the same and the user selection overlaps, then...
where (sResource == appt.Resource && CalendarGrid.TimesOverlap(pAVs[0].StartTime, pAVs[0].EndTime, appt.StartTime, appt.EndTime))
// if appt starttime is before avail start time, only count against the avail starting from the availability start time
let startTimeToCountAgainstBlock = appt.StartTime < pAVs[0].StartTime ? pAVs[0].StartTime : appt.StartTime
// if appt endtime is after the avail ends, only count against the avail up to where the avail ends
let endTimeToCountAgainstBlock = appt.EndTime > pAVs[0].EndTime ? pAVs[0].EndTime : appt.EndTime
// theoretical minutes per slot for the availability
let minPerSlot = (pAVs[0].EndTime - pAVs[0].StartTime).TotalMinutes / pAVs[0].Slots
// how many minutes does this appointment take away from the slot
let minPerAppt = (endTimeToCountAgainstBlock - startTimeToCountAgainstBlock).TotalMinutes
// how many slots the appointment takes up using this availability's scale
let slotsConsumed = minPerAppt / minPerSlot
select slotsConsumed)
// add up SlotsConsumed to substract from slotsAvailable
.Sum();
}
return (int)slotsAvailable;
/* OLD ALGOTHRIM 2
lock (this.m_pAvArray)
{
//This foreach loop looks for an availability that overlaps where the user clicked.
//There can only be one, as availabilites cannot overlap each other (enforced at the DB level)
//Therefore, we loop, and once we find it, we break.
foreach (CGAvailability pAV in this.m_pAvArray)
{
//If the resource is the same and the user selection overlaps, then...
if (sResource == pAV.ResourceList && CalendarGrid.TimesOverlap(dSelStart, dSelEnd, pAV.StartTime, pAV.EndTime))
{
slotsAvailable = pAV.Slots; //variable now holds the total number of slots
sAccessType = pAV.AccessTypeName; //Access Name
sAvailabilityMessage = pAV.Note; //Access Block Note
//Here we substract each appointment weight in slots from slotsAvailable
foreach (DictionaryEntry apptDict in this.m_appointments.AppointmentTable)
{
CGAppointment appt = (CGAppointment)apptDict.Value;
//If the appointment is in the same resource and overlaps with this availablity
if (sResource == appt.Resource && CalendarGrid.TimesOverlap(pAV.StartTime, pAV.EndTime, appt.StartTime, appt.EndTime))
{
// if appt starttime is before avail start time, only count against the avail starting from the availability start time
DateTime startTimeToCountAgainstBlock = appt.StartTime < pAV.StartTime ? pAV.StartTime : appt.StartTime;
// if appt endtime is after the avail ends, only count against the avail up to where the avail ends
DateTime endTimeToCountAgainstBlock = appt.EndTime > pAV.EndTime ? pAV.EndTime : appt.EndTime;
// theoretical minutes per slot for the availability
double minPerSlot = (pAV.EndTime - pAV.StartTime).TotalMinutes/pAV.Slots;
// how many minutes does this appointment take away from the slot
double minPerAppt = (endTimeToCountAgainstBlock - startTimeToCountAgainstBlock).TotalMinutes;
// how many slots the appointment takes up using this availability's scale
double slotsConsumed = minPerAppt / minPerSlot;
// subscract that from the total slots for the availability
slotsAvailable -= slotsConsumed;
} //end if
//now go to the next appointment in foreach
}
// As I said above, we can match only one availability. Once we found it and substracted from it; we are done.
break;
}
}
// We return the integer portion of the variable for display to the user or for calculations.
// That means, if 2.11 slots are left, the user sees 2. If 2.66, still 2.
return (int)slotsAvailable;
}
*/
/* ORIGINAL ALGORITHM
sAccessType = "";
sAvailabilityMessage = "";
DateTime dStart;
@ -694,6 +809,7 @@ namespace IndianHealthService.ClinicalScheduling
nAvailableSlots = 0;
}
return nAvailableSlots;
*/
}
/// <summary>

View File

@ -1,10 +1,8 @@
using System;
using System.Data;
//using System.Data.OleDb;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using IndianHealthService.BMXNet;
namespace IndianHealthService.ClinicalScheduling
{
@ -23,28 +21,19 @@ namespace IndianHealthService.ClinicalScheduling
/// <summary>
/// Gets appointments from VISTA to display in Grid
/// </summary>
/// <param name="docManager"></param>
/// <param name="saryResNames"></param>
/// <param name="StartTime"></param>
/// <param name="EndTime"></param>
/// <param name="docManager">God Class</param>
/// <param name="saryResNames">Resource Names Array</param>
/// <param name="StartTime">Self Explanatory</param>
/// <param name="EndTime">Self Explanatory</param>
/// <returns></returns>
public static DataTable CreateAppointmentSchedule(CGDocumentManager docManager, ArrayList saryResNames, DateTime StartTime, DateTime EndTime)
{
string sResName = "";
for (int i = 0; i < saryResNames.Count; i++)
{
sResName += saryResNames[i];
if ((i+1) < saryResNames.Count)
sResName += "|";
}
string sResName = string.Join("|", saryResNames.ToArray());
string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
string sEnd = FMDateTime.Create(EndTime).FMDateString;
string sSql = "BSDX CREATE APPT SCHEDULE^" + sResName + "^" + sStart + "^" + sEnd ;
DataTable dtRet = docManager.RPMSDataTable(sSql, "AppointmentSchedule");
return dtRet;
}
@ -56,51 +45,52 @@ namespace IndianHealthService.ClinicalScheduling
/// <param name="StartTime">Self-Explanatory</param>
/// <param name="EndTime">Self-Explanatory</param>
/// <param name="saryApptTypes">Array of Access Type IDs</param>
/// <param name="stType"></param>
/// <param name="sSearchInfo"></param>
/// <param name="stType">Not used</param>
/// <param name="sSearchInfo">Specific Search Parameters</param>
/// <returns></returns>
public static DataTable CreateAvailabilitySchedule(CGDocumentManager docManager,
ArrayList saryResourceNames, DateTime StartTime, DateTime EndTime,
ArrayList saryApptTypes,/**/ ScheduleType stType, string sSearchInfo)
{
DataTable rsOut;
rsOut = new DataTable("AvailabilitySchedule");
public static DataTable CreateAvailabilitySchedule(CGDocumentManager docManager,
ArrayList saryResourceNames, DateTime StartTime, DateTime EndTime,
ArrayList saryApptTypes,/**/ ScheduleType stType, string sSearchInfo)
{
DataTable rsOut = new DataTable("AvailabilitySchedule");
if (saryResourceNames.Count == 0) return rsOut;
string sResNames = string.Join("|", saryResourceNames.ToArray());
string sApptTypeIDs = string.Join("|", saryApptTypes.ToArray());
string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
string sEnd = FMDateTime.Create(EndTime).FMDateString;
string sSql = "BSDX CREATE ASGND SLOT SCHED^" + sResNames + "^" + sStart + "^" + sEnd + "^" + sApptTypeIDs + "^" + sSearchInfo; //+ "^" + sSTType ;
rsOut = docManager.RPMSDataTable(sSql, "AssignedSlotSchedule");
DataTable rsSlotSchedule;
DataTable rsApptSchedule;
DataTable rsTemp1;
return rsOut;
}
int nSize = saryResourceNames.Count;
if (nSize == 0)
{
return rsOut;
}
string sResName;
/*NOT USED ANYMORE
//TODO: Optimize: no need to keep looping through resources.
// for each resource
for (int i = 0; i < nSize; i++)
{
sResName = saryResourceNames[i].ToString();
//Gets all the slots (or Availabities, or AV Blocks if you like)
rsSlotSchedule = CGSchedLib.CreateAssignedSlotSchedule(docManager, sResName, StartTime, EndTime, saryApptTypes,/**/ stType, sSearchInfo);
rsSlotSchedule = CGSchedLib.CreateAssignedSlotSchedule(docManager, sResName, StartTime, EndTime, saryApptTypes, stType, sSearchInfo);
rsTemp1 = rsSlotSchedule;
//if we have slots
if (rsSlotSchedule.Rows.Count > 0 )
{
if (rsSlotSchedule.Rows.Count > 0 )
{
// Get appointment count to substract from the slots
rsApptSchedule = CGSchedLib.CreateAppointmentSlotSchedule(docManager, sResName, StartTime, EndTime, stType);
rsApptSchedule = CGSchedLib.CreateAppointmentSlotSchedule(docManager, sResName, StartTime, EndTime, stType);
// Perform the substraction
rsTemp1 = CGSchedLib.SubtractSlotsRS2(rsSlotSchedule, rsApptSchedule, sResName);
rsTemp1 = CGSchedLib.SubtractSlotsRS2(rsSlotSchedule, rsApptSchedule, sResName);
}
}
//otherwise, just return the slot schedule we have.
else
{
rsTemp1 = rsSlotSchedule;
else
{
rsTemp1 = rsSlotSchedule;
}
}
// if only one resource was passed in, its availablility is what we want
if (i == 0)
@ -116,7 +106,7 @@ namespace IndianHealthService.ClinicalScheduling
}
return rsOut;
}
*/
/* NOT USED ANYMORE!!!
public static DataTable CreateAssignedTypeSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime, DateTime EndTime, ScheduleType stType)
@ -280,21 +270,12 @@ namespace IndianHealthService.ClinicalScheduling
/// <returns>DataTable with the following Columns:
/// D00030START_TIME^D00030END_TIME^I00010SLOTS^T00030RESOURCE^T00010ACCESS_TYPE^T00250NOTE^I00030AVAILABILITYID
/// </returns>
public static DataTable CreateAssignedSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime,
DateTime EndTime, ArrayList rsaryApptTypeIDs, /**/ ScheduleType stType, string sSearchInfo)
/*
* public static DataTable CreateAssignedSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime,
DateTime EndTime, ArrayList rsaryApptTypeIDs, ScheduleType stType, string sSearchInfo)
{
//Appointment type ids is now always "" so that all appointment types are returned.
string sApptTypeIDs = "";
//flatten types by '|'
int nSize = rsaryApptTypeIDs.Count; //nSize is used to decide where to put the '|' sent in the RPC as we flatten sApptTypeIDs
for (int i=0; i < nSize; i++)
{
sApptTypeIDs += rsaryApptTypeIDs[i];
if (i < (nSize-1))
sApptTypeIDs += "|";
}
string sApptTypeIDs = string.Join("|", rsaryApptTypeIDs.ToArray());
string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
string sEnd = FMDateTime.Create(EndTime).FMDateString;
string sSql = "BSDX CREATE ASGND SLOT SCHED^" + sResourceName + "^" + sStart + "^" + sEnd + "^" + sApptTypeIDs + "^" + sSearchInfo; //+ "^" + sSTType ;
@ -302,7 +283,9 @@ namespace IndianHealthService.ClinicalScheduling
return dtRet;
}
*/
/*
public static DataTable CreateCopyTable()
{
DataTable dtCopy = new DataTable("dtCopy");
@ -357,6 +340,7 @@ namespace IndianHealthService.ClinicalScheduling
return dtCopy;
}
*/
/// <summary>
/// This gets a datatable which shows the appointments between start and end time, one row per appointment
@ -367,7 +351,8 @@ namespace IndianHealthService.ClinicalScheduling
/// <param name="EndTime"></param>
/// <param name="stType"></param>
/// <returns>DataTable with 4 columns: START_TIME, END_TIME, SLOTS, RESOURCE </returns>
public static DataTable CreateAppointmentSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime, DateTime EndTime, ScheduleType stType)
/*
public static DataTable CreateAppointmentSlotSchedule(CGDocumentManager docManager, string sResourceName, DateTime StartTime, DateTime EndTime, ScheduleType stType)
{
//Change Dates to FM Format
string sStart = FMDateTime.Create(StartTime).DateOnly.FMDateString;
@ -423,7 +408,7 @@ namespace IndianHealthService.ClinicalScheduling
//Convert Appointments to Availabilities, where all appointments become squeezed together.
ScheduleFromArray(cdtArray, StartTime, EndTime, ref ctbApptSchedule);
/*So far, we have the following:
So far, we have the following:
* dtRet -> List of Appointments Start and End times, one row per appointment
* cdtArray -> Linear 1 dimensional Array of dtRet Start and End times, sorted
* ctbAppointments -> Arraylist of dtRet as Availabilities
@ -431,7 +416,7 @@ namespace IndianHealthService.ClinicalScheduling
* (overlaps in appointments get converted into availabilties themselves: so
* 2 appts as 10:10-10:30 and 10:20-10:40 get converted into 10:10-10:20,
* 10:20-10:30, 10:30-10:40).
*/
//Find number of TimeBlocks in ctbApptSchedule that overlap the TimeBlocks in ctbAppointments
ArrayList ctbApptSchedule2 = new ArrayList();
@ -497,7 +482,9 @@ namespace IndianHealthService.ClinicalScheduling
return dtCopy;
}
*/
/*
public static int BlocksOverlap(CGAvailability rBlock, ArrayList rTBArray)
{
//this overload implements default false for bCountSlots
@ -541,6 +528,7 @@ namespace IndianHealthService.ClinicalScheduling
return nCount;
}
*/
/// <summary>
/// Does an appointment overlap with another appointment in the same day?
@ -551,7 +539,8 @@ namespace IndianHealthService.ClinicalScheduling
/// <param name="dEnd2">End Time of Second Appt</param>
/// <returns>true or false</returns>
/// <remarks>Draws 2 rectangles and sees if they overlap using minutes from 1980 as the start point</remarks>
public static bool TimesOverlap(DateTime dStart1, DateTime dEnd1, DateTime dStart2, DateTime dEnd2)
/*
public static bool TimesOverlap(DateTime dStart1, DateTime dEnd1, DateTime dStart2, DateTime dEnd2)
{
Rectangle rect1 = new Rectangle();
Rectangle rect2 = new Rectangle();
@ -567,7 +556,9 @@ namespace IndianHealthService.ClinicalScheduling
bool bRet = rect2.IntersectsWith(rect1);
return bRet;
}
*/
/*
public static void ConsolidateBlocks(ArrayList rTBArray)
{
//TODO: Test this function
@ -606,7 +597,7 @@ namespace IndianHealthService.ClinicalScheduling
}
}
while (!((bDirty == false) || (rTBArray.Count == 1)));
}
} */
/// <summary>
/// My guess is that this calculates remaining slots
@ -615,7 +606,8 @@ namespace IndianHealthService.ClinicalScheduling
/// <param name="rsBlocks2"></param>
/// <param name="sResource"></param>
/// <returns></returns>
public static DataTable SubtractSlotsRS2(DataTable rsBlocks1, DataTable rsBlocks2, string sResource)
/*
public static DataTable SubtractSlotsRS2(DataTable rsBlocks1, DataTable rsBlocks2, string sResource)
{
//Subtract slots in rsBlocks2 from rsBlocks1
//7-16-01 SUBCLINIC data field in rsBlocks1 persists thru routine.
@ -679,7 +671,9 @@ namespace IndianHealthService.ClinicalScheduling
return rsCopy;
}
*/
/*
public static DataTable UnionBlocks(DataTable rs1, DataTable rs2)
{
//Test input tables
@ -713,7 +707,9 @@ namespace IndianHealthService.ClinicalScheduling
}
return rsCopy;
}
*/
/*
public static DataTable IntersectBlocks(DataTable rs1, DataTable rs2)
{
DataTable rsCopy = CGSchedLib.CreateCopyTable();
@ -769,7 +765,7 @@ namespace IndianHealthService.ClinicalScheduling
// rect2.Y = CGSchedLib.MinSince80(dStart2);
// rect2.Height = CGSchedLib.MinSince80(dEnd2) - rect2.Y;
if (
/*(rect2.IntersectsWith(rect1) == true)*/
/*(rect2.IntersectsWith(rect1) == true)
(CGSchedLib.TimesOverlap(dStart1, dEnd1, dStart2, dEnd2) == true)
&&
((sClinic == sClinic2) || (sClinic == "NONE") || (sClinic2 == "NONE"))
@ -796,13 +792,15 @@ namespace IndianHealthService.ClinicalScheduling
}//foreach r1 in rs1.rows
return rsCopy;
}//end IntersectBlocks
*/
/// <summary>
/// Number of minutes since Jan 1 1980
/// </summary>
/// <param name="d">Date to compare</param>
/// <returns>Minutes as integer</returns>
public static int MinSince80(DateTime d)
/*
public static int MinSince80(DateTime d)
{
//Returns the total minutes between d and 1 Jan 1980
DateTime y = new DateTime(1980,1,1,0,0,0);
@ -813,7 +811,9 @@ namespace IndianHealthService.ClinicalScheduling
int nMinutes = (int) ts.TotalMinutes;
return nMinutes;
}
*/
/*
/// <summary>
/// Converts an Array of Times like this:
/// 10:00 10:00 10:20 10:20 10:30 10:30 10:30 10:40
@ -908,8 +908,10 @@ namespace IndianHealthService.ClinicalScheduling
}
}//end ScheduleFromArray
//long CResourceLink::SlotsInBlock(CTimeBlock &rTimeBlock, _RecordsetPtr rsBlock)
*/
/*
//long CResourceLink::SlotsInBlock(CTimeBlock &rTimeBlock, _RecordsetPtr rsBlock)
public static int SlotsInBlock(CGAvailability rTimeBlock, DataTable rsBlock)
{
DateTime dStart1;
@ -951,7 +953,9 @@ namespace IndianHealthService.ClinicalScheduling
}
return nSlots;
}//end SlotsInBlock
*/
/*
public static string ClinicInBlock(CGAvailability rTimeBlock, DataTable rsBlock)
{
DateTime dStart1;
@ -990,7 +994,9 @@ namespace IndianHealthService.ClinicalScheduling
}
return sClinic;
}//end ClinicInBlock
*/
/*
public static bool ResourceRulesInBlock(CGAvailability rTimeBlock, DataTable rsBlock, ref string sResourceList, ref string sAccessRuleList, ref string sNote)
{
DateTime dStart1;
@ -1058,6 +1064,7 @@ namespace IndianHealthService.ClinicalScheduling
}
return true;
}//End ResourceRulesInBlock
*/
}

View File

@ -616,7 +616,7 @@ namespace IndianHealthService.ClinicalScheduling
this.tvSchedules.HotTracking = true;
this.tvSchedules.Location = new System.Drawing.Point(0, 0);
this.tvSchedules.Name = "tvSchedules";
this.tvSchedules.Size = new System.Drawing.Size(128, 400);
this.tvSchedules.Size = new System.Drawing.Size(128, 358);
this.tvSchedules.Sorted = true;
this.tvSchedules.TabIndex = 1;
this.tvSchedules.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvSchedules_AfterSelect);
@ -663,7 +663,7 @@ namespace IndianHealthService.ClinicalScheduling
this.panelRight.Dock = System.Windows.Forms.DockStyle.Right;
this.panelRight.Location = new System.Drawing.Point(941, 0);
this.panelRight.Name = "panelRight";
this.panelRight.Size = new System.Drawing.Size(128, 400);
this.panelRight.Size = new System.Drawing.Size(128, 358);
this.panelRight.TabIndex = 3;
this.panelRight.Visible = false;
//
@ -736,10 +736,9 @@ namespace IndianHealthService.ClinicalScheduling
//
this.dateTimePicker1.Dock = System.Windows.Forms.DockStyle.Right;
this.dateTimePicker1.DropDownAlign = System.Windows.Forms.LeftRightAlignment.Right;
this.dateTimePicker1.Format = System.Windows.Forms.DateTimePickerFormat.Short;
this.dateTimePicker1.Location = new System.Drawing.Point(685, 0);
this.dateTimePicker1.Location = new System.Drawing.Point(607, 0);
this.dateTimePicker1.Name = "dateTimePicker1";
this.dateTimePicker1.Size = new System.Drawing.Size(128, 20);
this.dateTimePicker1.Size = new System.Drawing.Size(206, 20);
this.dateTimePicker1.TabIndex = 1;
this.dateTimePicker1.CloseUp += new System.EventHandler(this.dateTimePicker1_CloseUp);
this.dateTimePicker1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.dateTimePicker1_KeyPress);
@ -760,7 +759,7 @@ namespace IndianHealthService.ClinicalScheduling
this.panelCenter.Dock = System.Windows.Forms.DockStyle.Fill;
this.panelCenter.Location = new System.Drawing.Point(136, 24);
this.panelCenter.Name = "panelCenter";
this.panelCenter.Size = new System.Drawing.Size(802, 352);
this.panelCenter.Size = new System.Drawing.Size(802, 310);
this.panelCenter.TabIndex = 7;
//
// ctxCalendarGrid
@ -846,7 +845,7 @@ namespace IndianHealthService.ClinicalScheduling
//
this.panelBottom.Controls.Add(this.statusBar1);
this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panelBottom.Location = new System.Drawing.Point(136, 376);
this.panelBottom.Location = new System.Drawing.Point(136, 334);
this.panelBottom.Name = "panelBottom";
this.panelBottom.Size = new System.Drawing.Size(802, 24);
this.panelBottom.TabIndex = 8;
@ -864,7 +863,7 @@ namespace IndianHealthService.ClinicalScheduling
//
this.splitter1.Location = new System.Drawing.Point(128, 24);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(8, 376);
this.splitter1.Size = new System.Drawing.Size(8, 334);
this.splitter1.TabIndex = 9;
this.splitter1.TabStop = false;
//
@ -873,7 +872,7 @@ namespace IndianHealthService.ClinicalScheduling
this.splitter2.Dock = System.Windows.Forms.DockStyle.Right;
this.splitter2.Location = new System.Drawing.Point(938, 24);
this.splitter2.Name = "splitter2";
this.splitter2.Size = new System.Drawing.Size(3, 376);
this.splitter2.Size = new System.Drawing.Size(3, 334);
this.splitter2.TabIndex = 10;
this.splitter2.TabStop = false;
//
@ -901,7 +900,7 @@ namespace IndianHealthService.ClinicalScheduling
this.calendarGrid1.Name = "calendarGrid1";
this.calendarGrid1.Resources = ((System.Collections.ArrayList)(resources.GetObject("calendarGrid1.Resources")));
this.calendarGrid1.SelectedAppointment = 0;
this.calendarGrid1.Size = new System.Drawing.Size(802, 352);
this.calendarGrid1.Size = new System.Drawing.Size(802, 310);
this.calendarGrid1.StartDate = new System.DateTime(2003, 1, 27, 0, 0, 0, 0);
this.calendarGrid1.TabIndex = 0;
this.calendarGrid1.TimeScale = 20;
@ -914,7 +913,7 @@ namespace IndianHealthService.ClinicalScheduling
// CGView
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(1069, 400);
this.ClientSize = new System.Drawing.Size(1069, 358);
this.Controls.Add(this.panelCenter);
this.Controls.Add(this.panelBottom);
this.Controls.Add(this.splitter2);
@ -1987,15 +1986,15 @@ namespace IndianHealthService.ClinicalScheduling
//Save to Database
this.Document.CheckInAppointment(nApptID, dtCheckIn);
//Tell appointment that it is checked in--smh cancel that!
//a.CheckInTime = DateTime.Now;
//Tell appointment that it is checked in
a.CheckInTime = DateTime.Now;
//smh new code
if (dlgCheckin.PrintRouteSlip)
this.printRoutingSlip.Print();
// end new code
//redraw grid (would this work???)
//redraw grid
this.calendarGrid1.Invalidate();
}
catch (Exception ex)
@ -2474,11 +2473,12 @@ namespace IndianHealthService.ClinicalScheduling
if (dSearch.ShowDialog(this) == DialogResult.Cancel)
return;
string sResource = dSearch.SelectedResource;
CGAvailability av = dSearch.SelectedAvailability;
ArrayList alResource = new ArrayList();
alResource.Add(sResource);
DateTime sDate = dSearch.SelectedDate;
m_sDocName = sResource;
alResource.Add(av.ResourceList);
DateTime sDate = av.StartTime;
m_sDocName = av.ResourceList;
OpenSelectedSchedule(alResource, sDate);
}

View File

@ -36,7 +36,7 @@
<RemoteDebugMachine>
</RemoteDebugMachine>
<StartAction>Project</StartAction>
<StartArguments>/s=192.168.56.101 /p=9260 /a=shabiel12 /v=catdog.77</StartArguments>
<StartArguments>/s=172.16.16.108 /p=9250 /a=s.habiel /v=catdog.66</StartArguments>
<StartPage>
</StartPage>
<StartProgram>C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\IEExec.exe</StartProgram>

View File

@ -1,22 +1,21 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data;
using System.Linq;
//using System.Data.OleDb;
using IndianHealthService.BMXNet;
namespace IndianHealthService.ClinicalScheduling
{
/// <summary>
/// Summary description for DApptSearch.
/// Modal Dialog for searching for Patient Slots
/// </summary>
public class DApptSearch : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button cmdCancel;
private System.Windows.Forms.Button cmdOK;
private System.Windows.Forms.Button btnAccept;
private System.Windows.Forms.Panel pnlDescription;
private System.Windows.Forms.GroupBox grpDescription;
private System.Windows.Forms.Label lblDescription;
@ -37,15 +36,24 @@ namespace IndianHealthService.ClinicalScheduling
private System.Windows.Forms.RadioButton rdoBoth;
private System.Windows.Forms.RadioButton rdoPM;
private System.Windows.Forms.RadioButton rdoAM;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.MonthCalendar calStartDate;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.DataGrid grdResult;
private System.Windows.Forms.Button cmdSearch;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button cmdSearch;
private ListView lstResults;
private ColumnHeader colStartTime;
private ColumnHeader colEndTime;
private ColumnHeader colResource;
private ColumnHeader colSlots;
private ColumnHeader colAccessType;
private ColumnHeader colDate;
private Label lblEnd;
private Label lblStart;
private DateTimePicker dtEnd;
private DateTimePicker dtStart;
private ColumnHeader colDOW;
private ColumnHeader colID;
private System.ComponentModel.IContainer components;
public DApptSearch()
{
@ -59,19 +67,14 @@ namespace IndianHealthService.ClinicalScheduling
private DataSet m_dsGlobal;
DataTable m_dtTypes;
DataView m_dvTypes;
List<CGAvailability> lstResultantAvailabilities;
private CGAvailability _selectedAvailability;
DateTime m_dStart;
DateTime m_dEnd;
ArrayList m_alResources;
ArrayList m_alAccessTypes;
string m_sWeekDays;
string m_sAmpm;
DataTable m_dtResult;
DataView m_dvResult;
string m_sSelectedResource;
DateTime m_sSelectedDate;
string m_sWeekDays; //only practical use now is for sending to server
string m_sAmpm; // same here.
#endregion Fields
@ -109,9 +112,11 @@ namespace IndianHealthService.ClinicalScheduling
public void InitializePage(ArrayList alResources, CGDocumentManager docManager)
{
this.m_DocManager = docManager;
this.Text = "Searching for Appointments in: " + string.Join(" | ", alResources.Cast<string>());
this.m_DocManager = docManager;
this.m_dsGlobal = m_DocManager.GlobalDataSet;
System.IntPtr pHandle = this.Handle;
LoadListBox("ALL");
m_dStart = DateTime.Today;
@ -135,13 +140,16 @@ namespace IndianHealthService.ClinicalScheduling
cboAccessTypeFilter.SelectedIndex = cboAccessTypeFilter.Items.Count - 1;
cboAccessTypeFilter.Refresh();
//Create DataGridTableStyle for Result grid
/* OLD CODE
//Create DataGridTableStyle for Result grid
DataGridTableStyle tsResult = new DataGridTableStyle();
tsResult.MappingName = "Result";
tsResult.ReadOnly = true;
// Add START_TIME column style.
DataGridTextBoxColumn colStartTime = new DataGridTextBoxColumn();
colStartTime.MappingName = "START_TIME";
colStartTime.MappingName = "StartTime";
colStartTime.HeaderText = "Start Time";
colStartTime.Width = 200;
colStartTime.Format = "f";
@ -149,7 +157,7 @@ namespace IndianHealthService.ClinicalScheduling
// Add END_TIME column style.
DataGridTextBoxColumn colEndTime = new DataGridTextBoxColumn();
colEndTime.MappingName = "END_TIME";
colEndTime.MappingName = "EndTime";
colEndTime.HeaderText = "End Time";
colEndTime.Width = 75;
colEndTime.Format = "h:mm tt";
@ -157,7 +165,7 @@ namespace IndianHealthService.ClinicalScheduling
// Add RESOURCE column style.
DataGridTextBoxColumn colResource = new DataGridTextBoxColumn();
colResource.MappingName = "RESOURCE";
colResource.MappingName = "ResourceList";
colResource.HeaderText = "Resource";
colResource.Width = 200;
tsResult.GridColumnStyles.Add(colResource);
@ -175,8 +183,9 @@ namespace IndianHealthService.ClinicalScheduling
colAccess.HeaderText = "Access Type";
colAccess.Width = 200;
tsResult.GridColumnStyles.Add(colAccess);
grdResult.TableStyles.Add(tsResult);
//grdResult.TableStyles.Add(tsResult);
*/
this.UpdateDialogData(true);
}
@ -231,13 +240,10 @@ namespace IndianHealthService.ClinicalScheduling
m_sWeekDays += "Sunday";
//Start
this.m_dStart = this.calStartDate.SelectionStart;
this.m_dStart = this.dtStart.Value;
//End
m_dEnd = calStartDate.SelectionEnd;
m_dEnd = m_dEnd.AddHours(23);
m_dEnd = m_dEnd.AddMinutes(59);
this.m_dEnd = this.dtEnd.Value;
}
}
@ -269,11 +275,15 @@ namespace IndianHealthService.ClinicalScheduling
this.panel1 = new System.Windows.Forms.Panel();
this.cmdSearch = new System.Windows.Forms.Button();
this.cmdCancel = new System.Windows.Forms.Button();
this.cmdOK = new System.Windows.Forms.Button();
this.btnAccept = new System.Windows.Forms.Button();
this.pnlDescription = new System.Windows.Forms.Panel();
this.grpDescription = new System.Windows.Forms.GroupBox();
this.lblDescription = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.lblEnd = new System.Windows.Forms.Label();
this.lblStart = new System.Windows.Forms.Label();
this.dtEnd = new System.Windows.Forms.DateTimePicker();
this.dtStart = new System.Windows.Forms.DateTimePicker();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.lstAccessTypes = new System.Windows.Forms.CheckedListBox();
@ -291,9 +301,16 @@ namespace IndianHealthService.ClinicalScheduling
this.rdoPM = new System.Windows.Forms.RadioButton();
this.rdoAM = new System.Windows.Forms.RadioButton();
this.label1 = new System.Windows.Forms.Label();
this.calStartDate = new System.Windows.Forms.MonthCalendar();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.grdResult = new System.Windows.Forms.DataGrid();
this.lstResults = new System.Windows.Forms.ListView();
this.colID = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colDate = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colDOW = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colStartTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colEndTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colResource = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colSlots = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colAccessType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.panel1.SuspendLayout();
this.pnlDescription.SuspendLayout();
this.grpDescription.SuspendLayout();
@ -301,14 +318,13 @@ namespace IndianHealthService.ClinicalScheduling
this.grpDayOfWeek.SuspendLayout();
this.grpTimeOfDay.SuspendLayout();
this.groupBox2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.grdResult)).BeginInit();
this.SuspendLayout();
//
// panel1
//
this.panel1.Controls.Add(this.cmdSearch);
this.panel1.Controls.Add(this.cmdCancel);
this.panel1.Controls.Add(this.cmdOK);
this.panel1.Controls.Add(this.btnAccept);
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(0, 461);
this.panel1.Name = "panel1";
@ -333,16 +349,15 @@ namespace IndianHealthService.ClinicalScheduling
this.cmdCancel.TabIndex = 1;
this.cmdCancel.Text = "Cancel";
//
// cmdOK
// btnAccept
//
this.cmdOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.cmdOK.Location = new System.Drawing.Point(128, 8);
this.cmdOK.Name = "cmdOK";
this.cmdOK.Size = new System.Drawing.Size(64, 24);
this.cmdOK.TabIndex = 0;
this.cmdOK.Text = "OK";
this.cmdOK.Visible = false;
this.cmdOK.Click += new System.EventHandler(this.cmdOK_Click);
this.btnAccept.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnAccept.Location = new System.Drawing.Point(128, 8);
this.btnAccept.Name = "btnAccept";
this.btnAccept.Size = new System.Drawing.Size(176, 24);
this.btnAccept.TabIndex = 0;
this.btnAccept.Text = "Select Slot for Appointment";
this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click);
//
// pnlDescription
//
@ -377,6 +392,10 @@ namespace IndianHealthService.ClinicalScheduling
//
// groupBox1
//
this.groupBox1.Controls.Add(this.lblEnd);
this.groupBox1.Controls.Add(this.lblStart);
this.groupBox1.Controls.Add(this.dtEnd);
this.groupBox1.Controls.Add(this.dtStart);
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.lstAccessTypes);
@ -384,7 +403,6 @@ namespace IndianHealthService.ClinicalScheduling
this.groupBox1.Controls.Add(this.grpDayOfWeek);
this.groupBox1.Controls.Add(this.grpTimeOfDay);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.calStartDate);
this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top;
this.groupBox1.Location = new System.Drawing.Point(0, 0);
this.groupBox1.Name = "groupBox1";
@ -393,6 +411,38 @@ namespace IndianHealthService.ClinicalScheduling
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Search Parameters";
//
// lblEnd
//
this.lblEnd.AutoSize = true;
this.lblEnd.Location = new System.Drawing.Point(12, 124);
this.lblEnd.Name = "lblEnd";
this.lblEnd.Size = new System.Drawing.Size(153, 13);
this.lblEnd.TabIndex = 67;
this.lblEnd.Text = "End Date to Search (Inclusive)";
//
// lblStart
//
this.lblStart.AutoSize = true;
this.lblStart.Location = new System.Drawing.Point(12, 35);
this.lblStart.Name = "lblStart";
this.lblStart.Size = new System.Drawing.Size(159, 13);
this.lblStart.TabIndex = 66;
this.lblStart.Text = "Start Date to Search (Inclusive)";
//
// dtEnd
//
this.dtEnd.Location = new System.Drawing.Point(12, 141);
this.dtEnd.Name = "dtEnd";
this.dtEnd.Size = new System.Drawing.Size(200, 20);
this.dtEnd.TabIndex = 65;
//
// dtStart
//
this.dtStart.Location = new System.Drawing.Point(12, 54);
this.dtStart.Name = "dtStart";
this.dtStart.Size = new System.Drawing.Size(200, 20);
this.dtStart.TabIndex = 64;
//
// label3
//
this.label3.Location = new System.Drawing.Point(684, 64);
@ -541,22 +591,15 @@ namespace IndianHealthService.ClinicalScheduling
// label1
//
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(16, 24);
this.label1.Location = new System.Drawing.Point(6, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(136, 16);
this.label1.TabIndex = 57;
this.label1.Text = "Date Range:";
//
// calStartDate
//
this.calStartDate.Location = new System.Drawing.Point(16, 40);
this.calStartDate.MaxSelectionCount = 62;
this.calStartDate.Name = "calStartDate";
this.calStartDate.TabIndex = 56;
//
// groupBox2
//
this.groupBox2.Controls.Add(this.grdResult);
this.groupBox2.Controls.Add(this.lstResults);
this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox2.Location = new System.Drawing.Point(0, 208);
this.groupBox2.Name = "groupBox2";
@ -565,19 +608,68 @@ namespace IndianHealthService.ClinicalScheduling
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Search Result";
//
// grdResult
// lstResults
//
this.grdResult.CaptionVisible = false;
this.grdResult.DataMember = "";
this.grdResult.Dock = System.Windows.Forms.DockStyle.Fill;
this.grdResult.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.grdResult.Location = new System.Drawing.Point(3, 16);
this.grdResult.Name = "grdResult";
this.grdResult.ReadOnly = true;
this.grdResult.Size = new System.Drawing.Size(917, 170);
this.grdResult.TabIndex = 0;
this.grdResult.DoubleClick += new System.EventHandler(this.grdResult_DoubleClick);
this.grdResult.CurrentCellChanged += new System.EventHandler(this.grdResult_CurrentCellChanged);
this.lstResults.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.colID,
this.colDate,
this.colDOW,
this.colStartTime,
this.colEndTime,
this.colResource,
this.colSlots,
this.colAccessType});
this.lstResults.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstResults.FullRowSelect = true;
this.lstResults.GridLines = true;
this.lstResults.Location = new System.Drawing.Point(3, 16);
this.lstResults.MultiSelect = false;
this.lstResults.Name = "lstResults";
this.lstResults.Size = new System.Drawing.Size(917, 170);
this.lstResults.TabIndex = 0;
this.lstResults.UseCompatibleStateImageBehavior = false;
this.lstResults.View = System.Windows.Forms.View.Details;
this.lstResults.DoubleClick += new System.EventHandler(this.lstResults_DoubleClick);
//
// colID
//
this.colID.Text = "ID";
this.colID.Width = 0;
//
// colDate
//
this.colDate.Text = "Date";
this.colDate.Width = 91;
//
// colDOW
//
this.colDOW.Text = "Day of Week";
this.colDOW.Width = 80;
//
// colStartTime
//
this.colStartTime.Text = "Start Time";
this.colStartTime.Width = 87;
//
// colEndTime
//
this.colEndTime.Text = "End Time";
this.colEndTime.Width = 116;
//
// colResource
//
this.colResource.Text = "Resource";
this.colResource.Width = 370;
//
// colSlots
//
this.colSlots.Text = "Slots";
this.colSlots.Width = 47;
//
// colAccessType
//
this.colAccessType.Text = "Access Type";
this.colAccessType.Width = 101;
//
// DApptSearch
//
@ -595,161 +687,205 @@ namespace IndianHealthService.ClinicalScheduling
this.pnlDescription.ResumeLayout(false);
this.grpDescription.ResumeLayout(false);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.grpDayOfWeek.ResumeLayout(false);
this.grpTimeOfDay.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.grdResult)).EndInit();
this.ResumeLayout(false);
}
#endregion
#region Event Handlers
private void cmdOK_Click(object sender, System.EventArgs e)
{
}
private void cmdSearch_Click(object sender, System.EventArgs e)
{
//Get the control data into local vars
//Tell user we are processing
this.Cursor = Cursors.WaitCursor;
//Get the control data into local vars
UpdateDialogData(false);
//Resource array, Begin date, Access type array, MTWTF , AM PM
//Assemble |-delimited resource string
string sResources = "";
for (int j=0; j < m_alResources.Count; j++)
{
sResources = sResources + m_alResources[j];
if (j < (m_alResources.Count - 1))
sResources = sResources + "|";
}
//Access Types Array
string sTypes = "";
if (m_alAccessTypes.Count > 0)
{
for (int j=0; j < m_alAccessTypes.Count; j++)
{
sTypes = sTypes + (string) m_alAccessTypes[j];
if (j < (m_alAccessTypes.Count-1))
sTypes = sTypes + "|";
}
}
//Get Availabilities and Appointments from the DB
//NB: m_sAmpm and m_sWeekDays don't have an effect on the M side side right now
string sSearchInfo = "1|" + m_sAmpm + "|" + m_sWeekDays;
m_dtResult = CGSchedLib.CreateAvailabilitySchedule(m_DocManager, m_alResources, m_dStart, m_dEnd, m_alAccessTypes, ScheduleType.Resource, sSearchInfo);
DataTable m_availTable = CGSchedLib.CreateAvailabilitySchedule(m_DocManager, m_alResources, m_dStart, m_dEnd, m_alAccessTypes, ScheduleType.Resource, sSearchInfo);
DataTable m_apptTable = CGSchedLib.CreateAppointmentSchedule(m_DocManager, m_alResources, m_dStart, m_dEnd);
if (m_dtResult.Rows.Count == 0)
{
MessageBox.Show("No availability found.");
return;
}
#if DEBUG
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
#endif
lstResultantAvailabilities = (from rowAV in m_availTable.AsEnumerable()
// Calculate the number of slots consumed in this availability by appointments
let slotsConsumed = (from appt in m_apptTable.AsEnumerable()
//If the resource is the same and the user selection overlaps, then...
where (rowAV.Field<string>("RESOURCE") == appt.Field<string>("RESOURCENAME")
&& CalendarGrid.TimesOverlap(rowAV.Field<DateTime>("START_TIME"), rowAV.Field<DateTime>("END_TIME"), appt.Field<DateTime>("START_TIME"), appt.Field<DateTime>("END_TIME")))
// if appt starttime is before avail start time, only count against the avail starting from the availability start time
let startTimeToCountAgainstBlock = appt.Field<DateTime>("START_TIME") < rowAV.Field<DateTime>("START_TIME") ? rowAV.Field<DateTime>("START_TIME") : appt.Field<DateTime>("START_TIME")
// if appt endtime is after the avail ends, only count against the avail up to where the avail ends
let endTimeToCountAgainstBlock = appt.Field<DateTime>("END_TIME") > rowAV.Field<DateTime>("END_TIME") ? rowAV.Field<DateTime>("END_TIME") : appt.Field<DateTime>("END_TIME")
// theoretical minutes per slot for the availability
let minPerSlot = (rowAV.Field<DateTime>("END_TIME") - rowAV.Field<DateTime>("START_TIME")).TotalMinutes / rowAV.Field<int>("SLOTS")
// how many minutes does this appointment take away from the slot
let minPerAppt = (endTimeToCountAgainstBlock - startTimeToCountAgainstBlock).TotalMinutes
// how many slots the appointment takes up using this availability's scale
let slotsConsumed = minPerAppt / minPerSlot
select slotsConsumed).Sum()
// Subtract the number consumed from the original ones
let slotsLeft = (float)rowAV.Field<int>("SLOTS") - slotsConsumed
// filter by that value if it is at least one slot
where slotsLeft >= 1
// Sort by Start Time, then by Resource Name
orderby rowAV.Field<DateTime>("START_TIME"), rowAV.Field<string>("RESOURCE")
//return as a CGAvailability
select new CGAvailability
{
ResourceList = rowAV.Field<string>("RESOURCE"),
StartTime = rowAV.Field<DateTime>("START_TIME"),
EndTime = rowAV.Field<DateTime>("END_TIME"),
Slots = (int)slotsLeft,
// AccessTypeName is grabbed from the Access Type Table using a psuedojoin syntax.
// "ACCESS_TYPE" is the IEN of the AcceesType.
// Single or default is b/c we are expecting one result.
AccessTypeName = (from at in m_dsGlobal.Tables["AccessTypes"].AsEnumerable()
where at.Field<int>("BMXIEN")==Int32.Parse(rowAV.Field<string>("ACCESS_TYPE"))
select at.Field<string>("ACCESS_TYPE_NAME")).SingleOrDefault<string>(),
AvailabilityType = rowAV.Field<int>("AVAILABILITYID")
})
// convert to Generic List
.ToList<CGAvailability>();
m_dtResult.TableName = "Result";
m_dtResult.Columns.Add("AMPM", System.Type.GetType("System.String") ,"Convert(START_TIME, 'System.String')" );
m_dtResult.Columns.Add("DAYOFWEEK", System.Type.GetType("System.String"));
m_dtResult.Columns.Add("ACCESSNAME", System.Type.GetType("System.String"));
// if specific access types are chosen, filter the results based on a join against them.
if (m_alAccessTypes.Count > 0)
lstResultantAvailabilities = (from av in lstResultantAvailabilities
join at in m_alAccessTypes.Cast<string>() on av.AccessTypeName equals at
select av).ToList<CGAvailability>();
DataRow drAT;
DateTime dt;
string sDOW;
int nAccessTypeID;
string sAccessType;
// if user chose AM radio button, get morning appointments
// TimeSpan.FromHours(12) gets the number of ticks since Midnight
if (rdoAM.Checked) // less than 12 pm
{
lstResultantAvailabilities = (from av in lstResultantAvailabilities
where av.StartTime.TimeOfDay < TimeSpan.FromHours(12)
select av).ToList<CGAvailability>();
}
// if user chose PM radio button, get morning appointments
if (rdoPM.Checked) // after or equal to 12 pm
{
lstResultantAvailabilities = (from av in lstResultantAvailabilities
where av.StartTime.TimeOfDay >= TimeSpan.FromHours(12)
select av).ToList<CGAvailability>();
}
foreach (DataRow dr in m_dtResult.Rows)
{
dt = (DateTime) dr["START_TIME"];
sDOW = dt.DayOfWeek.ToString();
dr["DAYOFWEEK"] = sDOW;
if (dr["ACCESS_TYPE"].ToString() != "")
{
nAccessTypeID =Convert.ToInt16(dr["ACCESS_TYPE"].ToString());
drAT = m_dsGlobal.Tables["AccessTypes"].Rows.Find(nAccessTypeID);
if (drAT != null)
{
sAccessType = drAT["ACCESS_TYPE_NAME"].ToString();
dr["ACCESSNAME"] = sAccessType;
}
}
}
// if any of the days of week are checked, create a new list based on them
// and clear the original list, and join the new lists together
if (chkMon.Checked || chkTue.Checked || chkWed.Checked || chkThu.Checked || chkFri.Checked || chkSat.Checked || chkSun.Checked)
{
var lstMonday = new List<CGAvailability>();
var lstTuesday = new List<CGAvailability>();
var lstWednesday = new List<CGAvailability>();
var lstThursday = new List<CGAvailability>();
var lstFriday = new List<CGAvailability>();
var lstSaturday = new List<CGAvailability>();
var lstSunday = new List<CGAvailability>();
if (chkMon.Checked == true)
{
lstMonday = (from av in lstResultantAvailabilities
where av.StartTime.DayOfWeek == DayOfWeek.Monday
select av).ToList<CGAvailability>();
}
if (chkTue.Checked == true)
{
lstTuesday = (from av in lstResultantAvailabilities
where av.StartTime.DayOfWeek == DayOfWeek.Tuesday
select av).ToList<CGAvailability>();
}
if (chkWed.Checked == true)
{
lstWednesday = (from av in lstResultantAvailabilities
where av.StartTime.DayOfWeek == DayOfWeek.Wednesday
select av).ToList<CGAvailability>();
}
if (chkThu.Checked == true)
{
lstThursday = (from av in lstResultantAvailabilities
where av.StartTime.DayOfWeek == DayOfWeek.Thursday
select av).ToList<CGAvailability>();
}
if (chkFri.Checked == true)
{
lstFriday = (from av in lstResultantAvailabilities
where av.StartTime.DayOfWeek == DayOfWeek.Friday
select av).ToList<CGAvailability>();
}
if (chkSat.Checked == true)
{
lstSaturday = (from av in lstResultantAvailabilities
where av.StartTime.DayOfWeek == DayOfWeek.Saturday
select av).ToList<CGAvailability>();
}
if (chkSun.Checked == true)
{
lstSunday = (from av in lstResultantAvailabilities
where av.StartTime.DayOfWeek == DayOfWeek.Sunday
select av).ToList<CGAvailability>();
}
m_dvResult = new DataView(m_dtResult);
lstResultantAvailabilities.Clear();
lstResultantAvailabilities.AddRange(lstMonday);
lstResultantAvailabilities.AddRange(lstTuesday);
lstResultantAvailabilities.AddRange(lstWednesday);
lstResultantAvailabilities.AddRange(lstThursday);
lstResultantAvailabilities.AddRange(lstFriday);
lstResultantAvailabilities.AddRange(lstSaturday);
lstResultantAvailabilities.AddRange(lstSunday);
string sFilter = "(SLOTS > 0)";
if (m_sAmpm != "")
{
if (m_sAmpm == "AM")
sFilter = sFilter + " AND (AMPM LIKE '*AM*')";
if (m_sAmpm == "PM")
sFilter = sFilter + " AND (AMPM LIKE '*PM*')";
}
lstResultantAvailabilities.OrderBy(av => av.StartTime).ThenBy(av => av.ResourceList);
}
bool sOr = false;
if (m_sWeekDays != "")
{
sFilter += " AND (";
if (chkMon.Checked == true)
{
sFilter = sFilter + "(DAYOFWEEK LIKE '*Monday*')";
sOr = true;
}
if (chkTue.Checked == true)
{
sFilter = (sOr == true)?sFilter + " OR ":sFilter;
sFilter = sFilter + "(DAYOFWEEK LIKE '*Tuesday*')";
sOr = true;
}
if (chkWed.Checked == true)
{
sFilter = (sOr == true)?sFilter + " OR ":sFilter;
sFilter = sFilter + "(DAYOFWEEK LIKE '*Wednesday*')";
sOr = true;
}
if (chkThu.Checked == true)
{
sFilter = (sOr == true)?sFilter + " OR ":sFilter;
sFilter = sFilter + "(DAYOFWEEK LIKE '*Thursday*')";
sOr = true;
}
if (chkFri.Checked == true)
{
sFilter = (sOr == true)?sFilter + " OR ":sFilter;
sFilter = sFilter + "(DAYOFWEEK LIKE '*Friday*')";
sOr = true;
}
if (chkSat.Checked == true)
{
sFilter = (sOr == true)?sFilter + " OR ":sFilter;
sFilter = sFilter + "(DAYOFWEEK LIKE '*Saturday*')";
sOr = true;
}
if (chkSun.Checked == true)
{
sFilter = (sOr == true)?sFilter + " OR ":sFilter;
sFilter = sFilter + "(DAYOFWEEK LIKE '*Sunday*')";
sOr = true;
}
sFilter += ")";
}
if (m_alAccessTypes.Count > 0)
{
sFilter += " AND (";
sOr = false;
foreach (string sType in m_alAccessTypes)
{
if (sOr == true)
sFilter += " OR ";
sOr = true;
sFilter += "(ACCESSNAME = '" + sType + "')";
}
sFilter += ")";
}
#if DEBUG
System.Diagnostics.Debug.Write("LINQ took this long: " + stopwatch.ElapsedMilliseconds + "\n");
stopwatch = null;
#endif
//Then, convert the availabilities to ListViewItems
var items = (from item in lstResultantAvailabilities
let s = new string[] {item.AvailabilityType.ToString(), item.StartTime.ToShortDateString(), item.StartTime.DayOfWeek.ToString(),item.StartTime.ToShortTimeString() ,item.EndTime.ToShortTimeString() ,item.ResourceList,item.Slots.ToString(),item.AccessTypeName}
let lvItem = new ListViewItem(s)
select lvItem).ToArray<ListViewItem>();
m_dvResult.RowFilter = sFilter;
this.grdResult.DataSource = m_dvResult;
//--Updating Listview
lstResults.BeginUpdate(); //tell listview to suspend drawing for now
lstResults.Items.Clear(); //empty it from old data
//if (items.Length == 0) lstResults.Items.Add(new ListViewItem(new string[] { "", "", "", "" , "", "No Slots found", "", "" })); // no results
if (items.Length > 0) lstResults.Items.AddRange(items); // add new data
lstResults.EndUpdate(); // ok done adding items, draw now.
//--End Update Listview
//We are done
this.Cursor = Cursors.Default;
}
private void cboAccessTypeFilter_SelectionChangeCommitted(object sender, System.EventArgs e)
@ -769,51 +905,65 @@ namespace IndianHealthService.ClinicalScheduling
private void grdResult_DoubleClick(object sender, System.EventArgs e)
{
if (grdResult.DataSource == null)
/*
if (lstResults.DataSource == null)
return;
DataGridCell dgCell;
DataGridViewCell dgCell;
dgCell = this.grdResult.CurrentCell;
dgCell.ColumnNumber = 2;
this.m_sSelectedResource = grdResult[dgCell.RowNumber, dgCell.ColumnNumber].ToString();
this.m_sSelectedDate = (DateTime) grdResult[dgCell.RowNumber,0];
this.m_sSelectedResource = grdResult.SelectedRows[0].Cells[2].ToString();
this.m_sSelectedDate = (DateTime)grdResult.SelectedRows[0].Cells[0].Value;
this.DialogResult = DialogResult.OK;
this.Close();
*/
}
private void grdResult_CurrentCellChanged(object sender, System.EventArgs e)
{
DataGridCell dgCell;
dgCell = this.grdResult.CurrentCell;
this.grdResult.Select(dgCell.RowNumber);
/*
DataGridViewCell dgCell;
dgCell = this.grdResult.CurrentCell;
*/
}
/// <summary>
/// BAAAAAAAAAAAAAAAAAD. Use a shared method instead.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lstResults_DoubleClick(object sender, EventArgs e)
{
btnAccept_Click(sender, e);
}
private void btnAccept_Click(object sender, EventArgs e)
{
if (lstResults.SelectedIndices.Count == 0)
{
this.DialogResult = DialogResult.None;
return;
}
long availabilityKey = long.Parse(lstResults.SelectedItems[0].SubItems[0].Text);
_selectedAvailability = (from av in lstResultantAvailabilities
where av.AvailabilityType == availabilityKey
select av).Single<CGAvailability>();
this.DialogResult = DialogResult.OK;
}
#endregion Event Handlers
#region Properties
/// <summary>
/// Gets the resource selected by the user
/// </summary>
public string SelectedResource
{
get
{
return this.m_sSelectedResource;
}
}
/// Gets the Availability Selected by the User in which to put an appointment
/// </summary>
public CGAvailability SelectedAvailability
{
get { return this._selectedAvailability; }
}
/// <summary>
/// Gets the date selected by the user
/// </summary>
public DateTime SelectedDate
{
get
{
return this.m_sSelectedDate;
}
}
#endregion Properties
}
}
}

View File

@ -112,9 +112,9 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,11 +1,7 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
//using System.Data.OleDb;
using IndianHealthService.BMXNet;
namespace IndianHealthService.ClinicalScheduling
{