private void Button_Click(object sender, RoutedEventArgs e) { Button b = sender as Button; if (b.Name == "btnRemove") { //Look for the row in the database, in order to remove it. if ((dg.SelectedItem as ScheduleSlot).idTimeSlot != 0) { int tsId = (dg.SelectedItem as ScheduleSlot).idTimeSlot; ScheduleSlot sl = (from r in bdModel.ScheduleSlots where r.idTimeSlot == tsId select r).SingleOrDefault(); bdModel.ScheduleSlots.Remove(sl); bdModel.SaveChanges(); dg.ItemsSource = bdModel.ScheduleSlots.ToList(); } } else if (b.Name == "btnUpdate") { int tsId = (dg.SelectedItem as ScheduleSlot).idTimeSlot; ScheduleSlot s1 = (from r in bdModel.ScheduleSlots where r.idTimeSlot == tsId select r).SingleOrDefault(); ScheduleSlot tmp = s1; AddPlotWindow apw = new AddPlotWindow(tmp, bdModel); //bd.ScheduleSlots.Remove(s1); apw.ShowDialog(); bdModel.SaveChanges(); dg.ItemsSource = bdModel.ScheduleSlots.ToList(); } }
// <summary> /// Populate data in the fields with the existing ScheduleSlot /// set the (ScheduleSlot) current as the current scheduleslot /// </summary> /// <param name = "ss" >A Schedule slot already existing to get the data</param> /// /// <param name = "bd" >the current easyplanner entity</param> public AddPlotWindow(ScheduleSlot ss, bd_easyplannerEntities bd) { InitializeComponent(); foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek))) { cbxDayOfWeek.Items.Add(DateTimeFormatInfo.CurrentInfo.GetDayName(day)); } cbxDayOfWeek.SelectedIndex = ss.dayOfWeek; cbxStartHourHour.Text = formatHoursMinutes(ss.startHour.Hours); cbxStartHourMinute.Text = formatHoursMinutes(ss.startHour.Minutes); cbxEndHourHour.Text = formatHoursMinutes(ss.endHour.Hours); cbxEndHourMinute.Text = formatHoursMinutes(ss.endHour.Minutes); cbxAttendency.Text = ss.minAttendency.ToString(); if (ss.firstDay.ToString() != "") { DateTime dt = (DateTime)ss.firstDay; dpFirstDay.SelectedDate = dt; } if (ss.lastDay.ToString() != "") { DateTime dt = (DateTime)ss.lastDay; dpLastDay.SelectedDate = dt; } this.bdModel = bd; this.current = ss; current.idTimeSlot = ss.idTimeSlot; modified = true; }
// <summary> /// create a ScheduleSlot /// Populate an enum with days of week /// </summary> /// <param>None</param> public AddPlotWindow() { InitializeComponent(); current = new ScheduleSlot(); bdModel = bd_easyplannerEntities.OpenWithFallback(); modified = false; foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek))) { cbxDayOfWeek.Items.Add(DateTimeFormatInfo.CurrentInfo.GetDayName(day)); } cbxDayOfWeek.SelectedIndex = 1; dpFirstDay.SelectedDate = DateTime.Today; dpLastDay.SelectedDate = DateTime.Today; }
/// <summary> /// Spliting slots before simulation /// !!! slot list will be modified so /// use a copy if you don't want that /// </summary> /// <param name="slots"></param> /// <param name="absences"></param> /// <returns></returns> private List <ScheduleSlot> SplitSlots(List <ScheduleSlot> slots, List <AbsenceDemand> absences) { int count = slots.Count; // parsing slots for (int i = 0; i < count; i++) { ScheduleSlot slot = slots[i]; // parsing absences for (int j = 0; j < absences.Count; j++) { AbsenceDemand absence = absences[j]; // check on absence's end if ((int)absence.end.DayOfWeek == slot.dayOfWeek) { if (absence.end.TimeOfDay > slot.startHour && absence.end.TimeOfDay < slot.endHour) { ScheduleSlot newSlot = new ScheduleSlot(); newSlot.dayOfWeek = slot.dayOfWeek; newSlot.firstDay = slot.firstDay; newSlot.lastDay = slot.lastDay; newSlot.minAttendency = slot.minAttendency; newSlot.startHour = absence.end.TimeOfDay; newSlot.endHour = slot.endHour; slots.Add(newSlot); slot.endHour = absence.end.TimeOfDay; } } // check on absence's start if ((int)absence.start.DayOfWeek == slot.dayOfWeek) { if (absence.start.TimeOfDay > slot.startHour && absence.start.TimeOfDay < slot.endHour) { ScheduleSlot newSlot = new ScheduleSlot(); newSlot.dayOfWeek = slot.dayOfWeek; newSlot.firstDay = slot.firstDay; newSlot.lastDay = slot.lastDay; newSlot.minAttendency = slot.minAttendency; newSlot.startHour = absence.start.TimeOfDay; newSlot.endHour = slot.endHour; slots.Add(newSlot); slot.endHour = absence.start.TimeOfDay; } } } } return(slots); }
/// <summary> /// Save to the database the slots showed in the scheduler. /// </summary> private void btnSlotScheduleGeneration_Click(object sender, RoutedEventArgs e) { //Create a ScheduleSlot foreach event in the scheduler foreach (Event ev in slotGenerationScheduler.Events) { if (ev.IdShift == 0) //it's a new slot { bdModel.ScheduleSlots.Add(new ScheduleSlot() { dayOfWeek = ev.DayOfWeek, firstDay = ev.FirstDay, lastDay = ev.LastDay, minAttendency = ev.MinAttendency, startHour = new TimeSpan(ev.Start.Hour, ev.Start.Minute, 0), endHour = new TimeSpan(ev.End.Hour, ev.End.Minute, 0), }); } else if (ev.Color.ToString() == Colors.Red.ToString()) //if the color is red, then remove it from the database { ScheduleSlot ss = bdModel.ScheduleSlots.Single(s => s.idTimeSlot == ev.IdShift); bdModel.ScheduleSlots.Remove(ss); } else //otherwise update it { ScheduleSlot ss = bdModel.ScheduleSlots.Single(s => s.idTimeSlot == ev.IdShift); ss.dayOfWeek = ev.DayOfWeek; ss.lastDay = ev.LastDay; ss.firstDay = ev.FirstDay; ss.minAttendency = ev.MinAttendency; ss.startHour = new TimeSpan(ev.Start.Hour, ev.Start.Minute, 0); ss.endHour = new TimeSpan(ev.End.Hour, ev.End.Minute, 0); } } bdModel.SaveChanges(); MessageBox.Show("Traitement terminé", "Plages horaires sauvegardées dans la BD"); this.Close(); }
/// <summary> /// Generating of the workingshifts from the calculated flows /// </summary> /// <returns>List of coherents shifts given the constructed graph</returns> public Tuple <List <WorkingShift>, List <string> > GetShifts() { List <WorkingShift> shifts = new List <WorkingShift>(); List <string> problems = new List <string>(); CalculateMaximumFlow(); // init quotas dict Dictionary <ScheduleSlot, List <Tuple <Person, double> > > quotas = new Dictionary <ScheduleSlot, List <Tuple <Person, double> > >(); foreach (FlowNode node in this.Nodes) { if (node.Type == FlowNodeType.Slot) { quotas.Add(((SlotFlowNode)node).Slot, new List <Tuple <Person, double> >()); } } // recup quotas foreach (KeyValuePair <FlowArc, double> flowDict in this.Flows) { FlowArc arc = flowDict.Key; double flow = flowDict.Value; switch (arc.Start.Type) { case FlowNodeType.Virtual: // si flow < capacité alors personne pas complètement occupée => trop de RH if (flow < arc.Capacity) { Person person = ((PersonFlowNode)arc.End).Person; string problem = person.firstName + " " + person.name + " : " + (arc.Capacity - flow) + " heure(s) manquante(s) pour atteindre " + person.occupancyRate + "%"; problems.Add(problem); } break; case FlowNodeType.Person: if (flow > 0) { quotas[((SlotFlowNode)arc.End).Slot].Add(new Tuple <Person, double>(((PersonFlowNode)arc.Start).Person, flow)); } break; case FlowNodeType.Slot: // si flow < capacité alors plage pas complètement couverte => pas assez de RH if (flow < arc.Capacity) { ScheduleSlot slot = ((SlotFlowNode)arc.Start).Slot; string problem = DateTimeFormatInfo.CurrentInfo.GetDayName((DayOfWeek)Enum.GetValues(typeof(DayOfWeek)).GetValue(slot.dayOfWeek)) + " " + slot.startHour.ToString(@"hh\:mm") + " - " + slot.endHour.ToString(@"hh\:mm") + " : " + (arc.Capacity - flow) + " heure(s) manquante(s) pour remplir " + slot.minAttendency + " présence(s)"; problems.Add(problem); } break; default: break; } } // create shifts foreach (KeyValuePair <ScheduleSlot, List <Tuple <Person, double> > > quotaDict in quotas) { ScheduleSlot slot = quotaDict.Key; List <Tuple <Person, double> > liste = quotaDict.Value; TimeSpan start = slot.startHour; TimeSpan end = slot.endHour; TimeSpan fromThere = start; foreach (Tuple <Person, double> quotaTuple in liste) { Person person = quotaTuple.Item1;; double hours = quotaTuple.Item2; while (hours > 0) { TimeSpan toThere = TimeSpan.FromTicks(Math.Min(end.Ticks, fromThere.Add(TimeSpan.FromHours(hours)).Ticks)); WorkingShift shift = new WorkingShift(); DateTime theDay = WeekStart.AddDays(((int)slot.dayOfWeek - (int)WeekStart.DayOfWeek) % 7); shift.start = theDay.Add(fromThere); shift.end = theDay.Add(toThere); shift.Person = person; shifts.Add(shift); hours -= toThere.Subtract(fromThere).TotalHours; if (toThere == end) { fromThere = start; } else { fromThere = toThere; } } } } // merging contiguous shifts int i = 0; while (i < shifts.Count) { WorkingShift shiftI = shifts[i]; int j = i + 1; while (j < shifts.Count) { WorkingShift shiftJ = shifts[j]; if (shiftJ.Person == shiftI.Person) { if (shiftJ.start == shiftI.end) { shiftI.end = shiftJ.end; shifts.Remove(shiftJ); } else if (shiftJ.end == shiftI.start) { shiftI.start = shiftJ.start; shifts.Remove(shiftJ); } else { j++; } } else { j++; } } i++; } return(new Tuple <List <WorkingShift>, List <string> >(shifts, problems)); }
/// <summary> /// Constructor /// adds a slot's reference in addition of base constuctor /// </summary> /// <param name="slot">The Slot</param> public SlotFlowNode(ScheduleSlot slot) : base(slot.dayOfWeek + " : " + slot.startHour.ToString(@"hh\:mm") + "-" + slot.endHour.ToString(@"hh\:mm")) { this.Slot = slot; this.Type = FlowNodeType.Slot; }