/// <summary> /// Takes all the users assigned to department and checks if they are assigned to teams, and runs other methods that assign all the unassigned workers. /// </summary> /// <param name="departmentId">Id of coordinator's department.</param> /// <param name="db">Instance of database context.</param> /// <returns><see cref="List{T}"/> of <see cref="Team"/>s.</returns> private List <Team> GetTeamsToAlgorithm(int departmentId, P_zpp_2DbContext db) { var workerlist = new List <ApplicationUser>(); workerlist = db.Users .Where(x => x.DeptId == departmentId) .ToList(); List <ApplicationUser>?AssignedWorkers = workerlist .Where(x => x.SpecialInfo != null) .ToList(); List <ApplicationUser>?AssignedWorkers2 = AssignedWorkers .Where(x => JsonConvert.DeserializeObject <SpecialInfo>(x.SpecialInfo).TeamNumber != null) .ToList(); if (!AssignedWorkers2.Any() || AssignedWorkers2 == null) //workers have never been assigned { return(AssignAllWorkersToTeams(workerlist, db)); } else if (AssignedWorkers2.Count != workerlist.Count) //new workers were added to database { return(AssignNewWorkersToAlreadyExistingTeams(workerlist, db)); } else { return(GetTeams(workerlist)); } }
/// <summary> /// Gets the last schedule that has ending date right before starting day of a schedule that is about to be generated. /// </summary> /// <param name="StartingDay">First day of a schedule to generate</param> /// <param name="db">An instance of DbContext</param> /// <returns>Returns a <see cref="CustomScheduleClass"/> object, that contains unserialized Schedule and HangingDays property.</returns> private CustomScheduleClass GetLastSchedule(DateTime StartingDay, P_zpp_2DbContext db) { var DayBeforeStartingDay = StartingDay.AddDays(-1); var lastschedule = db.schedules .Where(x => x.LastScheduleDay == DayBeforeStartingDay.Date) .FirstOrDefault(); if (lastschedule != null) { var ScheduleInDictionary = JsonConvert.DeserializeObject <Dictionary <ApplicationUser, List <SingleShift> > >(lastschedule.ScheduleInJSON); var HangingDays = JsonConvert.DeserializeObject <List <LastShiftInfo> >(lastschedule.HangingDaysInJSON); CustomScheduleClass scheduleToReturn = new CustomScheduleClass(ScheduleInDictionary, HangingDays); return(scheduleToReturn); } else { return(null); } }
/// <summary> /// Main method that start all the method necessary to generate the schedule in four brigade work system. /// </summary> /// <param name="coordinatorId">Coordinator ID.</param> /// <param name="si">Schedule instructions created and chosen by coordinator.</param> /// <param name="departmentId">Work department ID</param> /// <param name="db">Database context.</param> /// <param name="d1">First day of schedule to generate.</param> /// <param name="d2">Last day of schedule to generate.</param> /// <returns>Schedule of type <see cref="Dictionary{ApplicationUser, List{SingleShift}}"/> that is <see href="https://www.newtonsoft.com/json/help/html/SerializingJSON.htm">serialized in JSON.</see></returns> public string Generate(string coordinatorId, ScheduleInstructions si, int departmentId, P_zpp_2DbContext db, DateTime d1, DateTime d2) { //List<ShiftInfoForScheduleGenerating> sifsg = new(); //sifsg.Add(new ShiftInfoForScheduleGenerating(new DateTime(2020, 5, 1, 6, 0, 0), new DateTime(2020, 5, 31, 14, 0, 0), 4, false)); // 6-14 //sifsg.Add(new ShiftInfoForScheduleGenerating(new DateTime(2020, 5, 1, 14, 0, 0), new DateTime(2020, 5, 31, 22, 0, 0), 4, false)); //14-22 //sifsg.Add(new ShiftInfoForScheduleGenerating(new DateTime(2020, 5, 1, 22, 0, 0), new DateTime(2020, 5, 31, 6, 0, 0), 4, true));//22-6 d1 = new DateTime(2021, 6, 1); d2 = new DateTime(2021, 6, 30); var teams = GetTeamsToAlgorithm(departmentId, db); var shiftInfoFromUser = JsonConvert.DeserializeObject <List <ShiftInfoForScheduleGenerating> >(si.ListOfShistsInJSON); var lastSchedule = GetLastSchedule(shiftInfoFromUser.First().ShiftSetBeginTime.Date, db); var shifts = CreateShifts(shiftInfoFromUser, lastSchedule, d1, d2); var ScheduleInDictionary = PutTeamsIntoShifts(shifts, teams, lastSchedule, shiftInfoFromUser); var ScheduleWithoutLeaves = GenerateSchedule(ScheduleInDictionary, teams); _Schedule = AdjustScheduleForLeaves(ScheduleWithoutLeaves, si.CoordinatorId, db); string json = JsonConvert.SerializeObject(SerializedSchedule, Formatting.Indented); return(json); }
/// <summary> /// Method that creates <see cref="List{T}"/> of <see cref="Team"/>s with assigned workers to teams. /// </summary> /// <param name="workerlist"><see cref="List{T}"/> of <see cref="ApplicationUser"/>s</param> /// <param name="db">An instance of database context.</param> /// <returns></returns> private List <Team> AssignAllWorkersToTeams(List <ApplicationUser> workerlist, P_zpp_2DbContext db) { List <Team> Teams = new(); var WorkerAmount = workerlist.Count / 4; for (int i = 0; i < 4; i++) { var team = workerlist.Skip(i * WorkerAmount).Take(WorkerAmount).ToList(); foreach (var item in team) { item.SpecialInfo = JsonConvert.SerializeObject(new SpecialInfo { TeamNumber = i + 1 }); db.Update(item); } Teams.Add(new Team(i + 1, team)); } db.SaveChanges(); return(Teams); }
/// <summary> /// Assignes all the workers which weren't assigned to the team to the team with the least amount of workers. /// </summary> /// <param name="workerlist"><see cref="List{T}"/> of <see cref="ApplicationUser"/>s</param> /// <param name="db">An instance of database context.</param> /// <returns><see cref="List{T}"/> of <see cref="Team"/>s</returns> private List <Team> AssignNewWorkersToAlreadyExistingTeams(List <ApplicationUser> workerlist, P_zpp_2DbContext db) { List <Team> Teams = new(); for (int i = 0; i < 4; i++) { var team = workerlist .Where(x => JsonConvert.DeserializeObject <SpecialInfo>(x.SpecialInfo).TeamNumber == i + 1) .ToList(); Teams.Add(new Team(i + 1, team)); } var unassignedworkers = workerlist.Where(x => JsonConvert.DeserializeObject <SpecialInfo>(x.SpecialInfo).TeamNumber == null); foreach (var item in unassignedworkers) { var TeamToAdd = Teams.OrderBy(x => x.TeamMembers.Count).First(); item.SpecialInfo = JsonConvert.SerializeObject(new SpecialInfo { TeamNumber = TeamToAdd.TeamNumber }); db.Update(item); Teams[Teams.IndexOf(TeamToAdd)].TeamMembers.Add(item); } db.SaveChanges(); return(Teams); }
/// <summary> /// Takes the generated schedule and removes the dates from <see cref="Dictionary{TKey, TValue}"/> if they are present in <see cref="Leaves"/> table, and then saves it to database. /// </summary> /// <param name="schedule">Tuple containing Schedule in dictionary and list of LastShiftInfo.</param> /// <param name="coordinatorId">Id of coordinator that generates the schedule.</param> /// <param name="db">Instance of database context.</param> /// <returns>A schedule ready to be serialized.</returns> private Dictionary <ApplicationUser, List <SingleShift> > AdjustScheduleForLeaves(Tuple <Dictionary <ApplicationUser, List <SingleShift> >, List <LastShiftInfo> > schedule, string coordinatorId, P_zpp_2DbContext db) { List <Leaves> leaves = new(); var firstDay = schedule.Item1.First().Value.First().ShiftBegin; foreach (var item in schedule.Item1) { leaves = db.leaves.Where(x => x.Idusera.Id == item.Key.Id && x.Status_zaakceptopwane == true && x.CheckOut > firstDay).ToList(); foreach (var leave in leaves) { foreach (var item2 in item.Value) { if ((item2.ShiftBegin >= leave.CheckIn) && (item2.ShiftEnd <= leave.CheckOut)) { item.Value.Remove(item2); } } } } var x = ""; var eee = schedule.Item1.Last().Value.Last().ShiftBegin.Date; var yyy = JsonConvert.SerializeObject(schedule.Item1); var uuu = coordinatorId; Schedule sch = new(coordinatorId, "tes2t", schedule.Item1.Last().Value.Last().ShiftBegin.Date, JsonConvert.SerializeObject(schedule.Item1), null, "fbs"); db.schedules.Add(sch); db.SaveChanges(); return(schedule.Item1); }