public List <BauSchedule> GenerateBauSchedules(DateTime startDate, DateTime endDate, int numberOfShifts, int numberOfEmployees) { List <Shift> shifts = EntityGenerator.GenerateShifts(numberOfShifts); List <Employee> employees = EntityGenerator.GenerateEmployees(numberOfEmployees); // Determine total slots available based on the period and number of shifts var numSlots = startDate.GetTotalWorkingDays(endDate, false) * numberOfShifts; // Example: 20 slots = 2 slots by day * 10 days // Determine max number of employees allowed by shift var maxEmployeesByShift = Math.Ceiling(((double)numSlots) / ((double)numberOfEmployees)); // Example: 2 slots/employees = 20 slots / 10 employees List <BauSchedule> bauSchedule = new List <BauSchedule>(); // Iterate through all days in the provided period for (DateTime currentDate = startDate; currentDate.Date <= endDate.Date; currentDate = currentDate.AddDays(1)) { // BUSINESS RULE: only consider weekdays if (currentDate.DayOfWeek == DayOfWeek.Saturday || currentDate.DayOfWeek == DayOfWeek.Sunday) { continue; } BauSchedule currentSchedule = new BauSchedule(currentDate); // Iterate through all shifts foreach (var currentShift in shifts) { // choose randomly a employee which haven't filled all slots yet var randomEmployee = employees .Where(e => e.Schedules.Count < maxEmployeesByShift) // BUSINESS RULE: An engineer can do at most one half day shift in a day .Where(e => e.Schedules.LastOrDefault() == null || e.Schedules.LastOrDefault().Date != currentDate.Date) // BUSINESS RULE: An engineer cannot have half day shifts on consecutive days .Where(e => e.Schedules.LastOrDefault() == null || e.Schedules.LastOrDefault().Date != new DateTime(currentDate.Year, currentDate.Month, currentDate.Day).AddDays(-1).Date) // Enforce a full cycle of employees .Where(e => e.Schedules.Count <= employees.Min(min => min.Schedules.Count)) // BUSINESS RULE: This should select engineers at random .OrderBy(random => Guid.NewGuid()).FirstOrDefault(); if (randomEmployee != null) { // Using DDD to modify a domain entity randomEmployee.AddSchedule(new BauSchedule(currentDate)); currentSchedule.Baus.Add(new Bau(randomEmployee, currentShift)); } } bauSchedule.Add(currentSchedule); } return(bauSchedule); }
public void Should_return_employee_with_one_bauschedule_and_last_assigned_date() { // Arrange var employee = new Employee(1, "Employee 1"); var expectedLastAssignedDate = DateTime.Now; var bauSchedule = new BauSchedule(expectedLastAssignedDate); // Act employee.AddSchedule(bauSchedule); var result = employee.LastAssignedDate; // Assert Assert.Equal(expectedLastAssignedDate, result); }
public void Should_return_JsonResult_with_bauschedules() { // Assert var startDate = new DateTime(2018, 6, 11); var endDate = new DateTime(2018, 6, 22); var numShifts = 2; var numEmployees = 10; var expectedBauSchedules = new List <BauSchedule>(); var bauSchedule1 = new BauSchedule(startDate); bauSchedule1.Baus.AddRange(new Bau[] { new Bau(new Employee(1, "Employee 1"), new Shift("Shift 1")), new Bau(new Employee(1, "Employee 2"), new Shift("Shift 2")) }); var bauSchedule2 = new BauSchedule(startDate.AddDays(1)); bauSchedule2.Baus.AddRange(new Bau[] { new Bau(new Employee(1, "Employee 3"), new Shift("Shift 1")), new Bau(new Employee(1, "Employee 4"), new Shift("Shift 2")) }); var bauSchedule3 = new BauSchedule(startDate.AddDays(2)); bauSchedule3.Baus.AddRange(new Bau[] { new Bau(new Employee(1, "Employee 5"), new Shift("Shift 1")), new Bau(new Employee(1, "Employee 6"), new Shift("Shift 2")) }); expectedBauSchedules.AddRange(new BauSchedule[] { bauSchedule1, bauSchedule2, bauSchedule3 }); BauServiceMock .Setup(x => x.GenerateBauSchedules(startDate, endDate, numShifts, numEmployees)) .Returns(expectedBauSchedules); // Mocked the GenerateBauSchedules() method // Act var result = ControllerUnderTest.GenerateBauSchedule(startDate, endDate, numShifts, numEmployees); // Assert var jsonResult = Assert.IsType <JsonResult>(result); Assert.Same(expectedBauSchedules, jsonResult.Value); }