From 361c6b37270f5203449fccee9804af7861b6aaa2 Mon Sep 17 00:00:00 2001 From: kgniazdowski Date: Wed, 1 Dec 2021 18:25:21 +0100 Subject: [PATCH] #129 Accessibility - overriding accessibilities by period of time and employee --- ...dateAvailabilitiesInPeriodOfTimeRequest.cs | 13 ------ .../Controllers/AvailabilitiesController.cs | 21 +++------ .../UpdateAvailabilitiesDto.cs | 18 ++++++++ ...dateAvailabilitiesInPeriodOfTimeCommand.cs | 14 ++---- ...ilabilitiesInPeriodOfTimeCommandHandler.cs | 34 ++++++++------- ...bilityCanNotDuplicateInPeriodOfTimeRule.cs | 38 ++++++++++++++++ ...nAvailabilitiesMustFitPeriodOfTimeRule.cs} | 9 ++-- ...bilityCanNotDuplicateInPeriodOfTimeRule.cs | 43 ------------------- .../Schedules/Schedule.cs | 33 +++++++------- 9 files changed, 105 insertions(+), 118 deletions(-) delete mode 100644 accessibility-service/src/Accessibility.Api/Availabilities/UpdateAvailabilitiesInPeriodOfTimeRequest.cs create mode 100644 accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesDto.cs create mode 100644 accessibility-service/src/Accessibility.Domain/Schedules/Rules/AvailabilityCanNotDuplicateInPeriodOfTimeRule.cs rename accessibility-service/src/Accessibility.Domain/Schedules/Rules/{OverridingAvailabilitiesMustFitPeriodOfTimeRule.cs => OverridenAvailabilitiesMustFitPeriodOfTimeRule.cs} (51%) delete mode 100644 accessibility-service/src/Accessibility.Domain/Schedules/Rules/WorkerAvailabilityCanNotDuplicateInPeriodOfTimeRule.cs diff --git a/accessibility-service/src/Accessibility.Api/Availabilities/UpdateAvailabilitiesInPeriodOfTimeRequest.cs b/accessibility-service/src/Accessibility.Api/Availabilities/UpdateAvailabilitiesInPeriodOfTimeRequest.cs deleted file mode 100644 index 34f4f461..00000000 --- a/accessibility-service/src/Accessibility.Api/Availabilities/UpdateAvailabilitiesInPeriodOfTimeRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using Accessibility.Application.Availabilities.Commands; - -namespace Accessibility.Api.Availabilities -{ - public class UpdateAvailabilitiesInPeriodOfTimeRequest - { - public DateTime DateFrom { get; set; } - public DateTime DateTo { get; set; } - public IEnumerable Availabilities { get; set; } - } -} diff --git a/accessibility-service/src/Accessibility.Api/Controllers/AvailabilitiesController.cs b/accessibility-service/src/Accessibility.Api/Controllers/AvailabilitiesController.cs index 28894184..ad5fc4c5 100644 --- a/accessibility-service/src/Accessibility.Api/Controllers/AvailabilitiesController.cs +++ b/accessibility-service/src/Accessibility.Api/Controllers/AvailabilitiesController.cs @@ -1,12 +1,9 @@ using System; using System.Net; using System.Threading.Tasks; -using Accessibility.Api.Availabilities; using Accessibility.Application.Availabilities.Commands.UpdateInPeriodOfTime; using Accessibility.Application.Availabilities.Queries; using Accessibility.Application.Availabilities.Queries.GetAvailabilites; -using Accessibility.Domain.Schedules; -using Accessibility.Domain.SharedKernel; using Core.Queries; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -38,26 +35,18 @@ public async Task Get( [HttpPatch] [ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)] - [ProducesResponseType((int)HttpStatusCode.BadRequest)] public async Task UpdateInPeriodOfTime( [FromRoute] Guid facilityId, [FromRoute] Guid scheduleId, - [FromBody] UpdateAvailabilitiesInPeriodOfTimeRequest request) + [FromBody] UpdateAvailabilitiesDto dto) { var result = await mediator.Send(new UpdateAvailabilitiesInPeriodOfTimeCommand( - new FacilityId(facilityId), - new ScheduleId(scheduleId), - request.DateFrom, - request.DateTo, - request.Availabilities + facilityId, + scheduleId, + dto )); - if (!result.Success) - { - return NotFound(); - } - - return Ok(result.Result); + return Ok(); } } } diff --git a/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesDto.cs b/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesDto.cs new file mode 100644 index 00000000..f1281842 --- /dev/null +++ b/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesDto.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace Accessibility.Application.Availabilities.Commands.UpdateInPeriodOfTime +{ + public record UpdateAvailabilitiesDto( + DateTime DateFrom, + DateTime DateTo, + Guid EmployeeId, + Guid CreatorId, + IEnumerable Availabilities + ); + + public record UpdatedAvailability( + DateTime StartTime, + DateTime EndTime + ); +} diff --git a/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesInPeriodOfTimeCommand.cs b/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesInPeriodOfTimeCommand.cs index 241db24e..a482a2f7 100644 --- a/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesInPeriodOfTimeCommand.cs +++ b/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesInPeriodOfTimeCommand.cs @@ -1,17 +1,11 @@ using System; -using System.Collections.Generic; -using Accessibility.Domain.Schedules; -using Accessibility.Domain.SharedKernel; using Core.Commands; -using MediatR; namespace Accessibility.Application.Availabilities.Commands.UpdateInPeriodOfTime { public record UpdateAvailabilitiesInPeriodOfTimeCommand( - FacilityId FacilityId, - ScheduleId ScheduleId, - DateTime DateFrom, - DateTime DateTo, - IEnumerable Availabilities - ) : IRequest>; + Guid FacilityId, + Guid ScheduleId, + UpdateAvailabilitiesDto Dto + ) : ICommand; } diff --git a/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesInPeriodOfTimeCommandHandler.cs b/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesInPeriodOfTimeCommandHandler.cs index f38d55be..059c0e21 100644 --- a/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesInPeriodOfTimeCommandHandler.cs +++ b/accessibility-service/src/Accessibility.Application/Availabilities/Commands/UpdateInPeriodOfTime/UpdateAvailabilitiesInPeriodOfTimeCommandHandler.cs @@ -2,15 +2,15 @@ using System.Threading; using System.Threading.Tasks; using Accessibility.Domain.Schedules; -using Accessibility.Domain.Schedules.Availabilities; using Accessibility.Domain.SharedKernel; using MediatR; using Core.Domain.UnitOfWork; using Core.Commands; +using System; namespace Accessibility.Application.Availabilities.Commands.UpdateInPeriodOfTime { - public class UpdateAvailabilitiesInPeriodOfTimeCommandHandler : IRequestHandler> + public class UpdateAvailabilitiesInPeriodOfTimeCommandHandler : ICommandHandler { private readonly IScheduleRepository repository; private readonly IUnitOfWork unitOfWork; @@ -21,28 +21,30 @@ public UpdateAvailabilitiesInPeriodOfTimeCommandHandler(IScheduleRepository repo this.unitOfWork = unitOfWork; } - public async Task> Handle(UpdateAvailabilitiesInPeriodOfTimeCommand request, CancellationToken cancellationToken) + public async Task Handle(UpdateAvailabilitiesInPeriodOfTimeCommand request, CancellationToken cancellationToken) { - var groupedAvailabilities = request.Availabilities.GroupBy(a => a.StartTime.Date); + var facilityId = new FacilityId(request.FacilityId); + var scheduleId = new ScheduleId(request.ScheduleId); + var employeeId = new EmployeeId(request.Dto.EmployeeId); + var creatorId = new EmployeeId(request.Dto.CreatorId); - var schedule = await repository.GetByIdAsync(request.ScheduleId, request.FacilityId); + var schedule = await repository.GetByIdAsync(scheduleId, facilityId); if (schedule == null) - return new CommandResult(false, "Schedule does not exist."); + throw new Exception("Schedule does not exist."); schedule.OverrideAvailabilitiesInPeriodOfTime( - new PeriodOfTime(request.DateFrom, request.DateTo), - request.Availabilities.Select(a => new AvailabilityData( - new EmployeeId(a.EmployeeId), - new PeriodOfTime(a.StartTime, a.EndTime), - new EmployeeId(a.CreatorId) - ))); + new PeriodOfTime(request.Dto.DateFrom, request.Dto.DateTo), + employeeId, + creatorId, + request.Dto.Availabilities.Select(a => new PeriodOfTime( + a.StartTime, + a.EndTime + )) + ); schedule.IncreaseVersion(); - - await unitOfWork.CommitAsync(); - - return new CommandResult(true, request.Availabilities.Count()); + return Unit.Value; } } } diff --git a/accessibility-service/src/Accessibility.Domain/Schedules/Rules/AvailabilityCanNotDuplicateInPeriodOfTimeRule.cs b/accessibility-service/src/Accessibility.Domain/Schedules/Rules/AvailabilityCanNotDuplicateInPeriodOfTimeRule.cs new file mode 100644 index 00000000..59f4ed70 --- /dev/null +++ b/accessibility-service/src/Accessibility.Domain/Schedules/Rules/AvailabilityCanNotDuplicateInPeriodOfTimeRule.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Linq; +using Accessibility.Domain.SharedKernel; +using Core.Domain; + +namespace Accessibility.Domain.Schedules.Rules +{ + public class AvailabilityCanNotDuplicateInPeriodOfTimeRule : IBusinessRule + { + private readonly IEnumerable availabilities; + + public AvailabilityCanNotDuplicateInPeriodOfTimeRule(IEnumerable availabilities) + { + this.availabilities = availabilities; + } + + public string Message => $"Employee can not have more than one record in the same period of time in rage of one schedule."; + + public bool IsBroken() + { + int skipCount = 1; + + foreach (var availability in availabilities) + { + if (availabilities + .Skip(skipCount) + .Any(a => a.HasCommonPeriodWithEdges(availability))) + { + return true; + } + + skipCount++; + } + + return false; + } + } +} diff --git a/accessibility-service/src/Accessibility.Domain/Schedules/Rules/OverridingAvailabilitiesMustFitPeriodOfTimeRule.cs b/accessibility-service/src/Accessibility.Domain/Schedules/Rules/OverridenAvailabilitiesMustFitPeriodOfTimeRule.cs similarity index 51% rename from accessibility-service/src/Accessibility.Domain/Schedules/Rules/OverridingAvailabilitiesMustFitPeriodOfTimeRule.cs rename to accessibility-service/src/Accessibility.Domain/Schedules/Rules/OverridenAvailabilitiesMustFitPeriodOfTimeRule.cs index ce3ef20d..607ab63b 100644 --- a/accessibility-service/src/Accessibility.Domain/Schedules/Rules/OverridingAvailabilitiesMustFitPeriodOfTimeRule.cs +++ b/accessibility-service/src/Accessibility.Domain/Schedules/Rules/OverridenAvailabilitiesMustFitPeriodOfTimeRule.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; using System.Linq; -using Accessibility.Domain.Schedules.Availabilities; using Core.Domain; using Accessibility.Domain.SharedKernel; namespace Accessibility.Domain.Schedules.Rules { - public class OverridingAvailabilitiesMustFitPeriodOfTimeRule : IBusinessRule + public class OverridenAvailabilitiesMustFitPeriodOfTimeRule : IBusinessRule { private readonly PeriodOfTime periodOfTime; - private readonly IEnumerable availabilities; + private readonly IEnumerable availabilities; - public OverridingAvailabilitiesMustFitPeriodOfTimeRule(PeriodOfTime periodOfTime, IEnumerable availabilities) + public OverridenAvailabilitiesMustFitPeriodOfTimeRule(PeriodOfTime periodOfTime, IEnumerable availabilities) { this.periodOfTime = periodOfTime; this.availabilities = availabilities; @@ -20,6 +19,6 @@ public OverridingAvailabilitiesMustFitPeriodOfTimeRule(PeriodOfTime periodOfTime public string Message => "Not all availabilities are within specified period of time."; public bool IsBroken() => - availabilities.Any(a => !a.PeriodOfTime.IsInRange(periodOfTime)); + availabilities.Any(a => !a.IsInRange(periodOfTime)); } } diff --git a/accessibility-service/src/Accessibility.Domain/Schedules/Rules/WorkerAvailabilityCanNotDuplicateInPeriodOfTimeRule.cs b/accessibility-service/src/Accessibility.Domain/Schedules/Rules/WorkerAvailabilityCanNotDuplicateInPeriodOfTimeRule.cs deleted file mode 100644 index 2e2d5f3e..00000000 --- a/accessibility-service/src/Accessibility.Domain/Schedules/Rules/WorkerAvailabilityCanNotDuplicateInPeriodOfTimeRule.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Accessibility.Domain.Schedules.Availabilities; -using Core.Domain; - -namespace Accessibility.Domain.Schedules.Rules -{ - public class WorkerAvailabilityCanNotDuplicateInPeriodOfTimeRule : IBusinessRule - { - private readonly IEnumerable availabilities; - private AvailabilityData incorrectAvailability; - - public WorkerAvailabilityCanNotDuplicateInPeriodOfTimeRule(IEnumerable availabilities) - { - this.availabilities = availabilities; - } - - public string Message => $"Employee can not have more than one record in the same period of time in rage of one schedule. ({incorrectAvailability.EmployeeId.Value})"; - - public bool IsBroken() - { - foreach (var workerGroup in availabilities.GroupBy(a => a.EmployeeId)) - { - int skipCount = 1; - - foreach (var availability in workerGroup) - { - if (workerGroup - .Skip(skipCount) - .Any(a => a.PeriodOfTime.HasCommonPeriodWithEdges(availability.PeriodOfTime))) - { - incorrectAvailability = availability; - return true; - } - - skipCount++; - } - } - - return false; - } - } -} diff --git a/accessibility-service/src/Accessibility.Domain/Schedules/Schedule.cs b/accessibility-service/src/Accessibility.Domain/Schedules/Schedule.cs index eb4e5c87..1700d49f 100644 --- a/accessibility-service/src/Accessibility.Domain/Schedules/Schedule.cs +++ b/accessibility-service/src/Accessibility.Domain/Schedules/Schedule.cs @@ -39,29 +39,32 @@ public Schedule( AddDomainEvent(new ScheduleCreatedEvent(Id)); } - public void OverrideAvailabilitiesInPeriodOfTime(PeriodOfTime periodOfTime, IEnumerable availabilities) + public void OverrideAvailabilitiesInPeriodOfTime( + PeriodOfTime periodOfTime, + EmployeeId employeeId, + EmployeeId creatorId, + IEnumerable availabilities) { - CheckRule(new OverridingAvailabilitiesMustFitPeriodOfTimeRule(periodOfTime, availabilities)); - CheckRule(new WorkerAvailabilityCanNotDuplicateInPeriodOfTimeRule(availabilities)); - - var oldAvailabilities = this.availabilities.Where(a => a.PeriodOfTime.IsInRange(periodOfTime)).ToList(); - + CheckRule(new OverridenAvailabilitiesMustFitPeriodOfTimeRule(periodOfTime, availabilities)); + CheckRule(new AvailabilityCanNotDuplicateInPeriodOfTimeRule(availabilities)); + + var oldAvailabilities = this.availabilities + .Where(a => + a.PeriodOfTime.IsInRange(periodOfTime) && + a.EmployeeId == employeeId) + .ToList(); + var foundAvailabilities = new List(); foreach (var availability in availabilities) { var old = oldAvailabilities.FirstOrDefault(a => - a.EmployeeId == availability.EmployeeId && - a.PeriodOfTime.Equals(availability.PeriodOfTime)); - + a.PeriodOfTime.Equals(availability)); + if (old == null) - { - this.availabilities.Add(Availability.Create(availability.EmployeeId, availability.PeriodOfTime, availability.CreatorId)); - } + this.availabilities.Add(Availability.Create(employeeId, availability, creatorId)); else - { foundAvailabilities.Add(old); - } } foreach (var old in oldAvailabilities) @@ -87,7 +90,7 @@ public void Modify( public void CreateCorrection(List corrections) { - CheckRule(new WorkerAvailabilityCanNotDuplicateInPeriodOfTimeRule(corrections)); + CheckRule(new AvailabilityCanNotDuplicateInPeriodOfTimeRule(corrections.Select(c => c.PeriodOfTime))); var currentPriority = availabilities.Max(a => a.Priority); var nextPriority = (short)(currentPriority + 1);