public void AddShiftMissingEmployeeId() { ProposedShift proposedShift = new ProposedShift() { dateTime = new DateTimeOffset(), ShiftId = new Guid() }; var mockRepository = new Mock <INowRepository>(); var controller = new ScheduleController(mockRepository.Object); var response = controller.AddShift(proposedShift); Assert.Equal("Invalid Data", response.Value); }
public JsonResult AddShift([FromBody] ProposedShift proposedShift) { if (proposedShift is null) { return(new JsonResult("Invalid Data")); } //Need to add validation for modelstate var shift = _nowRepository.Shifts.GetById(proposedShift.ShiftId); //var dateTimeOffset = proposedShift.dateTime.ToUniversalTime(); //Need more testing on timezone conversion var timeSpan = proposedShift.dateTime - shift.StartTime; //var sampledate = new DateTimeOffset(); var proposedSchedule = new Schedule() { Employee = proposedShift.EmployeeId.ToString(), ScheduleId = Guid.NewGuid(), ShiftId = shift.ShiftId, StartTime = shift.StartTime.AddDays(timeSpan.Days + 1), EndTime = shift.EndTime.AddDays(timeSpan.Days + 1) }; var conflict = _nowRepository.Schedules.GetAll() .Where(x => (x.Employee == proposedShift.EmployeeId.ToString()) && ( (x.StartTime <= proposedSchedule.EndTime && x.StartTime >= proposedSchedule.StartTime) || (x.EndTime <= proposedSchedule.EndTime && x.StartTime >= proposedSchedule.EndTime) || (x.EndTime >= proposedSchedule.EndTime && x.StartTime <= proposedSchedule.StartTime) ) ); if (conflict.Any()) { //provide more details on conflict return(new JsonResult("Conflict")); } else { //static operating Hours var operatingHours = new List <ScheduleVM>() { new ScheduleVM() { StartTime = new DateTimeOffset(2019, 2, 1, 8, 0, 0, TimeSpan.Zero), EndTime = new DateTimeOffset(2019, 2, 1, 17, 0, 0, TimeSpan.Zero), ShiftId = new Guid("00000000-0000-0000-0000-000000000100"), isOpen = true, isWholeDay = true, timeZone = "China Standard Time" }, new ScheduleVM() { StartTime = new DateTimeOffset(2019, 2, 2, 8, 0, 0, TimeSpan.Zero), EndTime = new DateTimeOffset(2019, 2, 2, 17, 0, 0, TimeSpan.Zero), ShiftId = new Guid("00000000-0000-0000-0000-000000000100"), isOpen = true, isWholeDay = true, timeZone = "China Standard Time" }, new ScheduleVM() { StartTime = new DateTimeOffset(2019, 2, 3, 8, 0, 0, TimeSpan.Zero), EndTime = new DateTimeOffset(2019, 2, 3, 17, 0, 0, TimeSpan.Zero), ShiftId = new Guid("00000000-0000-0000-0000-000000000100"), isOpen = true, isWholeDay = true, timeZone = "China Standard Time" }, new ScheduleVM() { StartTime = new DateTimeOffset(2019, 2, 4, 8, 0, 0, TimeSpan.Zero), EndTime = new DateTimeOffset(2019, 2, 4, 17, 0, 0, TimeSpan.Zero), ShiftId = new Guid("00000000-0000-0000-0000-000000000100"), isOpen = true, isWholeDay = true, timeZone = "China Standard Time" }, new ScheduleVM() { StartTime = new DateTimeOffset(2019, 2, 5, 8, 0, 0, TimeSpan.Zero), EndTime = new DateTimeOffset(2019, 2, 5, 17, 0, 0, TimeSpan.Zero), ShiftId = new Guid("00000000-0000-0000-0000-000000000100"), isOpen = true, isWholeDay = true, timeZone = "China Standard Time" }, new ScheduleVM() { StartTime = new DateTimeOffset(2019, 2, 5, 0, 0, 0, TimeSpan.Zero), EndTime = new DateTimeOffset(2019, 2, 6, 0, 0, 0, TimeSpan.Zero), ShiftId = new Guid("00000000-0000-0000-0000-000000000100"), isOpen = false, isWholeDay = true, timeZone = "China Standard Time" }, new ScheduleVM() { StartTime = new DateTimeOffset(2019, 2, 6, 0, 0, 0, TimeSpan.Zero), EndTime = new DateTimeOffset(2019, 2, 7, 0, 0, 0, TimeSpan.Zero), ShiftId = new Guid("00000000-0000-0000-0000-000000000100"), isOpen = false, isWholeDay = true, timeZone = "China Standard Time" } }; var schedules = _nowRepository.Schedules.GetAll().Where(x => x.Employee == proposedSchedule.Employee).ToList(); if (schedules.Any()) { #region PreviousSchedule //get previous and next schedule base on proposed schedule var previousSchedule = schedules.Where(x => x.EndTime < proposedSchedule.StartTime).OrderByDescending(x => x.EndTime).FirstOrDefault(); //calculate startRange if (previousSchedule != null) { var StartTimeSpan = proposedSchedule.StartTime - previousSchedule.EndTime; if (StartTimeSpan.TotalHours >= 24) { var previousOperatingHours = operatingHours.Where(x => x.EndTime < proposedSchedule.StartTime).OrderByDescending(x => x.EndTime).FirstOrDefault(); if (previousOperatingHours.isOpen && !previousOperatingHours.isWholeDay) { var startTimeSpan = (proposedSchedule.StartTime - previousOperatingHours.EndTime) / 2; proposedSchedule.StartRange = proposedSchedule.StartTime.AddTicks(startTimeSpan.Ticks + 1); } else { var timeZone = TimeZoneInfo.FindSystemTimeZoneById(previousOperatingHours.timeZone); previousOperatingHours.EndTime = TimeZoneInfo.ConvertTimeToUtc(previousOperatingHours.EndTime.DateTime, timeZone); var startTimeSpan = (previousOperatingHours.EndTime - proposedSchedule.StartTime) / 2; proposedSchedule.StartRange = proposedSchedule.StartTime.AddTicks(startTimeSpan.Ticks + 1); } } else { StartTimeSpan = StartTimeSpan / 2; proposedSchedule.StartRange = proposedSchedule.StartTime.AddTicks(StartTimeSpan.Ticks + 1); previousSchedule.EndRange = proposedSchedule.StartTime.AddTicks(StartTimeSpan.Ticks); } } else { var previousOperatingHours = operatingHours.Where(x => x.EndTime < proposedSchedule.StartTime).OrderByDescending(x => x.EndTime).FirstOrDefault(); if (previousOperatingHours.isOpen && !previousOperatingHours.isWholeDay) { var StartTimeSpan = (proposedSchedule.StartTime - previousOperatingHours.EndTime) / 2; proposedSchedule.StartRange = proposedSchedule.StartTime.AddTicks(StartTimeSpan.Ticks + 1); } else { var timeZone = TimeZoneInfo.FindSystemTimeZoneById(previousOperatingHours.timeZone); previousOperatingHours.EndTime = TimeZoneInfo.ConvertTimeToUtc(previousOperatingHours.EndTime.DateTime, timeZone); var startTimeSpan = (previousOperatingHours.EndTime - proposedSchedule.StartTime) / 2; proposedSchedule.StartRange = proposedSchedule.StartTime.AddTicks(startTimeSpan.Ticks + 1); } } #endregion #region NextSchedule var nextSchedule = schedules.Where(x => x.StartTime > proposedSchedule.EndTime).OrderByDescending(x => x.StartTime).FirstOrDefault(); //calculating endRange if (nextSchedule != null) { var EndTimeSpan = nextSchedule.StartTime - proposedSchedule.EndTime; if (EndTimeSpan.TotalHours >= 24) { var nextOperatingHours = operatingHours.Where(x => x.StartTime > proposedSchedule.EndTime).OrderByDescending(x => x.StartTime).FirstOrDefault(); if (nextOperatingHours.isOpen && !nextOperatingHours.isWholeDay) { var endTimeSpan = (nextOperatingHours.StartTime - proposedSchedule.EndTime) / 2; proposedSchedule.EndRange = proposedSchedule.EndTime.AddTicks(endTimeSpan.Ticks); } else { var timeZone = TimeZoneInfo.FindSystemTimeZoneById(nextOperatingHours.timeZone); nextOperatingHours.StartTime = TimeZoneInfo.ConvertTimeToUtc(nextOperatingHours.StartTime.DateTime, timeZone); var endTimeSpan = (nextOperatingHours.StartTime - proposedSchedule.EndTime) / 2; proposedSchedule.EndRange = proposedSchedule.EndTime.AddTicks(endTimeSpan.Ticks); } } else { EndTimeSpan = EndTimeSpan / 2; proposedSchedule.EndRange = proposedSchedule.EndTime.AddTicks(EndTimeSpan.Ticks); nextSchedule.StartRange = proposedSchedule.EndTime.AddTicks(EndTimeSpan.Ticks + 1); } } else { var nextOperatingHours = operatingHours.Where(x => x.StartTime > proposedSchedule.EndTime).OrderByDescending(x => x.StartTime).FirstOrDefault(); if (nextOperatingHours.isOpen && !nextOperatingHours.isWholeDay) { var EndTimeSpan = nextOperatingHours.StartTime - proposedSchedule.EndTime; proposedSchedule.EndRange = proposedSchedule.EndTime.AddTicks(EndTimeSpan.Ticks); } else { var timeZone = TimeZoneInfo.FindSystemTimeZoneById(nextOperatingHours.timeZone); nextOperatingHours.StartTime = TimeZoneInfo.ConvertTimeToUtc(nextOperatingHours.StartTime.DateTime, timeZone); var endTimeSpan = (nextOperatingHours.StartTime - proposedSchedule.EndTime) / 2; proposedSchedule.EndRange = proposedSchedule.EndTime.AddTicks(endTimeSpan.Ticks); } } #endregion } else { if (operatingHours.Any()) { #region PreviousOperatingHours var previousOperatingHours = operatingHours.Where(x => x.EndTime < proposedSchedule.StartTime).OrderByDescending(x => x.EndTime).FirstOrDefault(); if (previousOperatingHours.isOpen && !previousOperatingHours.isWholeDay) { //calculate the startRange of proposedSchedule var startTimeSpan = ((proposedSchedule.StartTime - previousOperatingHours.EndTime) / 2); proposedSchedule.StartRange = proposedSchedule.StartTime.AddTicks(startTimeSpan.Ticks + 1); } else { var timeZone = TimeZoneInfo.FindSystemTimeZoneById(previousOperatingHours.timeZone); previousOperatingHours.EndTime = TimeZoneInfo.ConvertTimeToUtc(previousOperatingHours.EndTime.DateTime, timeZone); var startTimeSpan = (previousOperatingHours.EndTime - proposedSchedule.StartTime) / 2; proposedSchedule.StartRange = proposedSchedule.StartTime.AddTicks(startTimeSpan.Ticks + 1); } #endregion #region nextOperatingHours var nextOperatingHours = operatingHours.Where(x => x.StartTime > proposedSchedule.EndTime).OrderBy(x => x.StartTime.DateTime).FirstOrDefault(); if (nextOperatingHours.isOpen && !nextOperatingHours.isWholeDay) { //calculate the endRange of proposedSchedule var endTimeSpan = ((nextOperatingHours.StartTime - proposedSchedule.EndTime) / 2); proposedSchedule.EndRange = proposedSchedule.EndTime.AddTicks(endTimeSpan.Ticks); } else { var timeZone = TimeZoneInfo.FindSystemTimeZoneById(nextOperatingHours.timeZone); nextOperatingHours.StartTime = TimeZoneInfo.ConvertTimeToUtc(nextOperatingHours.StartTime.DateTime, timeZone); var endTimeSpan = (nextOperatingHours.StartTime - proposedSchedule.EndTime) / 2; proposedSchedule.EndRange = proposedSchedule.EndTime.AddTicks(endTimeSpan.Ticks); } #endregion } else { return(new JsonResult("No Operating Hours yet!")); } } _nowRepository.Schedules.Add(proposedSchedule); _nowRepository.SaveAsync(); return(new JsonResult(proposedSchedule)); } }