/// <summary> /// Return true if the shifts overlap, return false if they do not. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool DoesShiftsOverlap(Shift a, EditShiftRequest b) { if (a.Year == b.Year && a.Month == b.Month && a.Day == b.Day && !(a.EndTime <= b.StartTime || a.StartTime >= b.EndTime)) { return(true); } return(false); }
public async Task <IActionResult> Edit([FromRoute] Guid shiftId, [FromBody] EditShiftRequest request) { #region Error handling // In case of bad user input, gets Guid as string an parses to Guid - this shouldn't be nessecary with proper front-end setup if (!Guid.TryParse(request.ShiftOwnerId, out Guid requestOwnerId)) { return(StatusCode(StatusCodes.Status406NotAcceptable, "The given Id is not a valid Guid!")); } List <Employee> allEmployees = await _employeeService.GetAllEmployeesAsync(); bool _ownerIdExists = false; for (int i = 0; i < allEmployees.Count; i++) { if (allEmployees[i].Id == requestOwnerId) { _ownerIdExists = true; break; } } if (!_ownerIdExists) { return(StatusCode(StatusCodes.Status406NotAcceptable, "No owner with the given Id exists!")); } if (request.Day < 1 || request.Day > 31 || request.Month < 1 || request.Month > 12 || request.Year < 1 || new DateTime(request.Year, request.Month, request.Day) < DateTime.Now) { return(StatusCode(StatusCodes.Status406NotAcceptable, "The given date for the shift is not valid!" + "\nMake sure the date is not in the past, and that Day is between 1-31, and Month is between 1-12!")); } if (request.StartTime < 0 || request.StartTime > 23) { return(StatusCode(StatusCodes.Status406NotAcceptable, "The time given for the start of the shift is not valid! Must be between 0 and 23!")); } if (request.EndTime <= request.StartTime || request.EndTime > 24) { return(StatusCode(StatusCodes.Status406NotAcceptable, "The time given for the end of the shift is not valid! Must be higher than the start time (" + request.StartTime + "), but no higher than 24!")); } List <Shift> allShiftForEmployee = await _shiftService.GetShiftsForSpecificEmployeeByIdAsync(requestOwnerId); for (int i = 0; i < allShiftForEmployee.Count; i++) { if (shiftId != allShiftForEmployee[i].Id && DoesShiftsOverlap(allShiftForEmployee[i], request)) { return(StatusCode(StatusCodes.Status406NotAcceptable, "The new time for this shift overlaps with a different shift (Id:" + allShiftForEmployee[i].Id + ") for this employee (Id:" + allShiftForEmployee[i].ShiftOwnerId + ")")); } } #endregion // NOTE: Ideally i would simply create a new shift, and update the database with the given shift, // However this causes a tracking error for the given Id, which is only allowed 1 tracker, // So as a patchwerk solution i instead change each individual value for that shift. Shift shift = await _shiftService.GetShiftByIdAsync(shiftId); shift.ShiftOwnerId = Guid.Parse(request.ShiftOwnerId); shift.Day = request.Day; shift.Month = request.Month; shift.Year = request.Year; shift.StartTime = request.StartTime; shift.EndTime = request.EndTime; bool updated = await _shiftService.UpdateShiftAsync(shift); if (updated) { return(Ok(shift)); } return(NotFound()); }