///<summary>Gets all providers for the appointment view passed in. Pass 0 to get all provs associated with the 'none' view.</summary> public static List <long> GetProvsForView(long apptViewNum) { //No need to check RemotingRole; no call to db. if (apptViewNum == 0) { //Simply return all visible ops. These are the ops that the 'none' appointment view currently displays. List <Operatory> listVisibleOps = Operatories.GetWhere(x => !PrefC.HasClinicsEnabled || Clinics.ClinicNum == 0 || x.ClinicNum == Clinics.ClinicNum , true); List <long> listProvNums = listVisibleOps.Select(x => x.ProvDentist).ToList(); listProvNums.AddRange(listVisibleOps.Select(x => x.ProvHygienist)); return(listProvNums.Distinct().ToList()); } return(GetWhere(x => x.ApptViewNum == apptViewNum && x.ProvNum != 0) .Select(x => x.ProvNum).ToList()); }
///<summary>Gets all operatories for the appointment view passed in. Pass 0 to get all ops associated with the 'none' view. ///Only returns operatories that are associated to the currently selected clinic.</summary> public static List <long> GetOpsForView(long apptViewNum) { //No need to check RemotingRole; no call to db. List <long> retVal = new List <long>(); if (apptViewNum == 0) { bool hasClinicsEnabled = PrefC.HasClinicsEnabled; //Simply return all visible ops. These are the ops that the 'none' appointment view currently displays. //Do not consider operatories that are not associated with the currently selected clinic. return(Operatories.GetWhere(x => !hasClinicsEnabled || Clinics.ClinicNum == 0 || x.ClinicNum == Clinics.ClinicNum, true) .Select(x => x.OperatoryNum).ToList()); } return(ApptViewItems.GetWhere(x => x.ApptViewNum == apptViewNum && x.OpNum != 0).Select(x => x.OpNum).ToList()); }
///<summary>Get all provider operatory availabilities for passed in data.</summary> private static List <ApptSearchOperatorySchedule> GetAllForDate(DateTime scheduleDate, List <Schedule> listSchedules , List <Appointment> listAppointments, List <ScheduleOp> listSchedOps, List <long> listOpNums, List <long> listProvNums, long blockoutType) { //No need to check RemotingRole; no call to db. List <ApptSearchOperatorySchedule> listOpScheds = new List <ApptSearchOperatorySchedule>(); List <Operatory> listOps = Operatories.GetWhere(x => x.OperatoryNum.In(listOpNums)); //Remove any ScheduleOps that are not related to the operatories passed in. listSchedOps.RemoveAll(x => !listOpNums.Contains(x.OperatoryNum)); //Create dictionaries that are comprised of every operatory in question and will keep track of all ProviderNums for specific scenarios. Dictionary <long, List <long> > dictProvNumsInOpsBySched = listOps.ToDictionary(x => x.OperatoryNum, x => new List <long>()); Dictionary <long, List <long> > dictProvNumsInOpsByOp = listOps.ToDictionary(x => x.OperatoryNum, x => new List <long>() { x.ProvDentist, x.ProvHygienist }); //Could be a list of two 0's if no providers are associated to this op. scheduleDate = scheduleDate.Date; //remove time component foreach (long opNum in listOpNums) { ApptSearchOperatorySchedule apptSearchOpSched = new ApptSearchOperatorySchedule(); apptSearchOpSched.SchedDate = scheduleDate; apptSearchOpSched.ProviderNums = new List <long>(); apptSearchOpSched.OperatoryNum = opNum; apptSearchOpSched.IsOpAvailable = new bool[288]; for (int j = 0; j < 288; j++) { apptSearchOpSched.IsOpAvailable[j] = true; //Set entire operatory schedule to true. True=available. } listOpScheds.Add(apptSearchOpSched); } #region Fill OpScheds with Providers allowed to work in each operatory //Make explicit entries into dictProvNumsInOpsBySched if there are any SchedOps for each schedule OR add an entry to every operatory if none found. foreach (Schedule schedule in listSchedules.FindAll(x => x.SchedDate == scheduleDate)) //use this loop to fill listProvsInOpBySched { List <ScheduleOp> listSchedOpsForSchedule = listSchedOps.FindAll(x => x.ScheduleNum == schedule.ScheduleNum); if (listSchedOpsForSchedule.Count > 0) { AddProvNumToOps(dictProvNumsInOpsBySched, listSchedOpsForSchedule.Select(x => x.OperatoryNum).Distinct().ToList(), schedule.ProvNum); } else //Provider scheduled to work, but not limited to specific operatory to add providerNum to all ops in opsProvPerSchedules { AddProvNumToOps(dictProvNumsInOpsBySched, dictProvNumsInOpsBySched.Keys.ToList(), schedule.ProvNum); } } //Set each listOpScheds.ProviderNums to the corresponding providers via operatory OR schedules. foreach (Operatory op in listOps) { //If blockoutType is not 0 and 0 is only provNum in listProvNums, we are just looking for blockout schedules in ops. //Add zero to ProviderNums list for op if op has any blockout for the date we are searching. Unwanted blockouts are filtered out below. if (blockoutType > 0 && listProvNums.Max() == 0 && dictProvNumsInOpsBySched[op.OperatoryNum].Contains(0)) { listOpScheds.First(x => x.OperatoryNum == op.OperatoryNum).ProviderNums.Add(0); } //If the operatory does not have a primary and secondary provider use all providers from the schedules. else if (dictProvNumsInOpsByOp[op.OperatoryNum][0] == 0 && dictProvNumsInOpsByOp[op.OperatoryNum][1] == 0) { listOpScheds.First(x => x.OperatoryNum == op.OperatoryNum).ProviderNums = dictProvNumsInOpsBySched[op.OperatoryNum]; } else //Otherwise; only add providers that intersect between schedules and being explicitly assigned to an operatory. { List <long> listIntersectingProvNums = dictProvNumsInOpsBySched[op.OperatoryNum].Intersect(dictProvNumsInOpsByOp[op.OperatoryNum]).ToList(); if (listIntersectingProvNums.Count() > 0) { listOpScheds.First(x => x.OperatoryNum == op.OperatoryNum).ProviderNums.AddRange(listIntersectingProvNums); } } } #endregion #region Remove provider availability for current appointments List <Appointment> listAppointmentsForDate = listAppointments.FindAll(x => x.Op != 0 && x.AptDateTime.Date == scheduleDate); foreach (Appointment appt in listAppointmentsForDate) //Remove unavailable slots from schedule { ApptSearchOperatorySchedule apptSearchOperatorySchedule = listOpScheds.FirstOrDefault(x => x.OperatoryNum == appt.Op); if (apptSearchOperatorySchedule == null) { continue; } int apptStartIndex = (int)appt.AptDateTime.TimeOfDay.TotalMinutes / 5; for (int j = 0; j < appt.Pattern.Length; j++) //make unavailable all blocks of time during this appointment { apptSearchOperatorySchedule.IsOpAvailable[apptStartIndex + j] = false; //set time block to false, meaning something is scheduled here } } #endregion #region Remove provider availiabilty for blockouts set to Do Not Schedule List <long> listBlockoutsDoNotSchedule = new List <long>(); List <Def> listBlockoutsAll = Defs.GetDefsForCategory(DefCat.BlockoutTypes, true); foreach (Def blockout in listBlockoutsAll) { if (blockout.ItemValue.Contains(BlockoutType.NoSchedule.GetDescription())) { listBlockoutsDoNotSchedule.Add(blockout.DefNum); //do not return results for blockouts set to 'Do Not Schedule' continue; } if (blockoutType != 0 && blockoutType != blockout.DefNum) { listBlockoutsDoNotSchedule.Add(blockout.DefNum); //do not return results for blockouts that are not of our requested type } } if (listBlockoutsDoNotSchedule.Count > 0) { List <Schedule> listBlockouts = listSchedules.FindAll(x => x.ProvNum == 0 && x.SchedType == ScheduleType.Blockout && x.SchedDate == scheduleDate && x.BlockoutType.In(listBlockoutsDoNotSchedule)); foreach (Schedule blockout in listBlockouts) { //get length of blockout (how many 5 minute increments does it span) TimeSpan duration = blockout.StopTime.Subtract(blockout.StartTime); double fiveMinuteIncrements = Math.Ceiling(duration.TotalMinutes / 5); int blockoutStartIndex = (int)blockout.StartTime.TotalMinutes / 5; //Set each operatory as unavailable that has this blockout. List <ScheduleOp> listSchedOpsForBlockout = listSchedOps.FindAll(x => x.ScheduleNum == blockout.ScheduleNum); foreach (ScheduleOp schedOp in listSchedOpsForBlockout) { ApptSearchOperatorySchedule apptSearchOperatorySchedule = listOpScheds.FirstOrDefault(x => x.OperatoryNum == schedOp.OperatoryNum); if (apptSearchOperatorySchedule == null) { continue; } for (int i = 0; i < fiveMinuteIncrements; i++) { apptSearchOperatorySchedule.IsOpAvailable[blockoutStartIndex + i] = false; } } } } #endregion //Return all ApptSearchOperatorySchedules for the providers passed in. return(listOpScheds.FindAll(x => x.ProviderNums.Any(y => y.In(listProvNums)))); }