示例#1
0
        public async Task <SheriffTraining> UpdateSheriffTraining(DutyRosterService dutyRosterService, ShiftService shiftService, SheriffTraining sheriffTraining, bool overrideConflicts)
        {
            ValidateStartAndEndDates(sheriffTraining.StartDate, sheriffTraining.EndDate);
            await ValidateSheriffExists(sheriffTraining.SheriffId);

            var savedTraining = await Db.SheriffTraining.FindAsync(sheriffTraining.Id);

            savedTraining.ThrowBusinessExceptionIfNull(
                $"{nameof(SheriffTraining)} with the id: {sheriffTraining.Id} could not be found. ");

            if (savedTraining.ExpiryDate.HasValue)
            {
                throw new BusinessLayerException($"{nameof(SheriffTraining)} with the id: {sheriffTraining.Id} has been expired");
            }

            await ValidateNoOverlapAsync(dutyRosterService, shiftService, sheriffTraining, overrideConflicts, sheriffTraining.Id);

            Db.Entry(savedTraining).CurrentValues.SetValues(sheriffTraining);
            Db.Entry(savedTraining).Property(x => x.SheriffId).IsModified    = false;
            Db.Entry(savedTraining).Property(x => x.ExpiryDate).IsModified   = false;
            Db.Entry(savedTraining).Property(x => x.ExpiryReason).IsModified = false;

            await Db.SaveChangesAsync();

            return(savedTraining);
        }
示例#2
0
        private async Task ValidateNoOverlapAsync <T>(DutyRosterService dutyRosterService, ShiftService shiftService, T data, bool overrideConflicts, int?updateOnlyId = null) where T : SheriffEvent
        {
            var sheriffEventConflicts = new List <SheriffEvent>
            {
                await LookForSheriffEventConflictAsync(Db.SheriffLeave, data, updateOnlyId),
                await LookForSheriffEventConflictAsync(Db.SheriffTraining, data, updateOnlyId),
                await LookForSheriffEventConflictAsync(Db.SheriffAwayLocation, data, updateOnlyId)
            }.WhereToList(se => se != null);

            var shiftConflicts = await Db.Shift.AsNoTracking().Include(d => d.Location)
                                 .Where(sal =>
                                        sal.SheriffId == data.SheriffId && (sal.StartDate < data.EndDate && data.StartDate < sal.EndDate) &&
                                        sal.ExpiryDate == null).ToListAsync();

            sheriffEventConflicts = AllowDifferentTimezonesCloseTimeGap(sheriffEventConflicts, data);

            if (!overrideConflicts)
            {
                DisplayConflicts(data.SheriffId, sheriffEventConflicts, shiftConflicts);
            }
            else
            {
                await OverrideConflicts(data, dutyRosterService, shiftService, sheriffEventConflicts, shiftConflicts);
            }
        }
示例#3
0
        private async Task OverrideConflicts <T>(T data, DutyRosterService dutyRosterService, ShiftService shiftService, List <SheriffEvent> sheriffEventConflicts, List <Shift> shiftConflicts) where T : SheriffEvent
        {
            foreach (var eventConflict in sheriffEventConflicts)
            {
                switch (eventConflict)
                {
                case SheriffAwayLocation _:
                    var sheriffAwayLocation = Db.SheriffAwayLocation.First(sl => sl.Id == eventConflict.Id);
                    sheriffAwayLocation.ExpiryDate   = DateTimeOffset.UtcNow;
                    sheriffAwayLocation.ExpiryReason = "OVERRIDE";
                    break;

                case SheriffTraining _:
                    var sheriffTraining = Db.SheriffTraining.First(sl => sl.Id == eventConflict.Id);
                    sheriffTraining.ExpiryDate   = DateTimeOffset.UtcNow;
                    sheriffTraining.ExpiryReason = "OVERRIDE";
                    break;

                case SheriffLeave _:
                    var sheriffLeave = Db.SheriffLeave.First(sl => sl.Id == eventConflict.Id);
                    sheriffLeave.ExpiryDate   = DateTimeOffset.UtcNow;
                    sheriffLeave.ExpiryReason = "OVERRIDE";
                    break;
                }
            }

            await shiftService.HandleShiftOverrides(data, dutyRosterService, shiftConflicts);
        }
示例#4
0
 public ShiftController(ShiftService shiftService, DutyRosterService dutyRosterService, SheriffDbContext db, IConfiguration configuration)
 {
     ShiftService      = shiftService;
     DutyRosterService = dutyRosterService;
     Db            = db;
     Configuration = configuration;
 }
示例#5
0
 public SheriffController(SheriffService sheriffService, DutyRosterService dutyRosterService, ShiftService shiftService, UserService userUserService, IConfiguration configuration, SheriffDbContext db) : base(userUserService)
 {
     SheriffService    = sheriffService;
     ShiftService      = shiftService;
     DutyRosterService = dutyRosterService;
     Db = db;
     _uploadPhotoSizeLimitKB = Convert.ToInt32(configuration.GetNonEmptyValue("UploadPhotoSizeLimitKB"));
 }
示例#6
0
        public async Task <ActionResult <List <DutyDto> > > GetDuties(int locationId, DateTimeOffset start, DateTimeOffset end)
        {
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, locationId))
            {
                return(Forbid());
            }

            var duties = await DutyRosterService.GetDutiesForLocation(locationId, start, end);

            return(Ok(duties.Adapt <List <DutyDto> >()));
        }
示例#7
0
        public async Task<SheriffTraining> AddSheriffTraining(DutyRosterService dutyRosterService, ShiftService shiftService, SheriffTraining sheriffTraining, bool overrideConflicts)
        {
            ValidateStartAndEndDates(sheriffTraining.StartDate, sheriffTraining.EndDate);
            await ValidateSheriffExists(sheriffTraining.SheriffId);
            await ValidateNoOverlapAsync(dutyRosterService, shiftService, sheriffTraining, overrideConflicts);

            sheriffTraining.Sheriff = await Db.Sheriff.FindAsync(sheriffTraining.SheriffId);
            sheriffTraining.TrainingType = await Db.LookupCode.FindAsync(sheriffTraining.TrainingTypeId);
            await Db.SheriffTraining.AddAsync(sheriffTraining);
            await Db.SaveChangesAsync();
            return sheriffTraining;
        }
示例#8
0
        public async Task<SheriffLeave> AddSheriffLeave(DutyRosterService dutyRosterService, ShiftService shiftService, SheriffLeave sheriffLeave, bool overrideConflicts)
        {
            ValidateStartAndEndDates(sheriffLeave.StartDate, sheriffLeave.EndDate);
            await ValidateSheriffExists(sheriffLeave.SheriffId);
            await ValidateNoOverlapAsync(dutyRosterService, shiftService, sheriffLeave, overrideConflicts);

            sheriffLeave.LeaveType = await Db.LookupCode.FindAsync(sheriffLeave.LeaveTypeId);
            sheriffLeave.Sheriff = await Db.Sheriff.FindAsync(sheriffLeave.SheriffId);
            await Db.SheriffLeave.AddAsync(sheriffLeave);
            await Db.SaveChangesAsync();
            return sheriffLeave;
        }
示例#9
0
        public async Task<SheriffAwayLocation> AddSheriffAwayLocation(DutyRosterService dutyRosterService, ShiftService shiftService, SheriffAwayLocation awayLocation, bool overrideConflicts)
        {
            ValidateStartAndEndDates(awayLocation.StartDate, awayLocation.EndDate);
            await ValidateSheriffExists(awayLocation.SheriffId);
            await ValidateNoOverlapAsync(dutyRosterService, shiftService, awayLocation, overrideConflicts);

            awayLocation.Location = await Db.Location.FindAsync(awayLocation.LocationId);
            awayLocation.Sheriff = await Db.Sheriff.FindAsync(awayLocation.SheriffId);
            await Db.SheriffAwayLocation.AddAsync(awayLocation);
            await Db.SaveChangesAsync();
            return awayLocation;
        }
示例#10
0
        public async Task<SheriffActingRank> AddSheriffActingRank(DutyRosterService dutyRosterService, ShiftService shiftService, SheriffActingRank actingRank, bool overrideConflicts)
        {
            ValidateStartAndEndDates(actingRank.StartDate, actingRank.EndDate);
            await ValidateSheriffExists(actingRank.SheriffId);

            await ValidateSheriffActingRankExists(actingRank);

            actingRank.Sheriff = await Db.Sheriff.FindAsync(actingRank.SheriffId);
            await Db.SheriffActingRank.AddAsync(actingRank);
            await Db.SaveChangesAsync();
            return actingRank;
        }
示例#11
0
        public ShiftControllerTests() : base(false)
        {
            var environment  = new EnvironmentBuilder("LocationServicesClient:Username", "LocationServicesClient:Password", "LocationServicesClient:Url");
            var shiftService = new ShiftService(Db, new SheriffService(Db, environment.Configuration),
                                                environment.Configuration);
            var dutyRosterService = new DutyRosterService(Db, environment.Configuration,
                                                          shiftService, environment.LogFactory.CreateLogger <DutyRosterService>());

            ShiftController = new ShiftController(shiftService, dutyRosterService, Db, environment.Configuration)
            {
                ControllerContext = HttpResponseTest.SetupMockControllerContext()
            };
        }
示例#12
0
        public async Task <ActionResult <DutyDto> > AddDuty(AddDutyDto newDuty)
        {
            if (newDuty == null)
            {
                return(BadRequest(InvalidDutyErrorMessage));
            }
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, newDuty.LocationId))
            {
                return(Forbid());
            }

            var duty = await DutyRosterService.AddDuty(newDuty.Adapt <Duty>());

            return(Ok(duty.Adapt <DutyDto>()));
        }
示例#13
0
        public async Task <ActionResult <DutyDto> > MoveSheriffFromDutySlot(int fromDutySlotId, int toDutyId, DateTimeOffset?separationTime = null)
        {
            var duty = await DutyRosterService.GetDutyByDutySlot(fromDutySlotId);

            if (duty == null)
            {
                return(NotFound());
            }
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, duty.LocationId))
            {
                return(Forbid());
            }

            duty = await DutyRosterService.MoveSheriffFromDutySlot(fromDutySlotId, toDutyId, separationTime);

            return(Ok(duty.Adapt <DutyDto>()));
        }
示例#14
0
        public async Task <ActionResult> ExpireDuty(int id)
        {
            var duty = await DutyRosterService.GetDuty(id);

            if (duty == null)
            {
                return(NotFound());
            }
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, duty.LocationId))
            {
                return(Forbid());
            }

            await DutyRosterService.ExpireDuty(id);

            return(NoContent());
        }
示例#15
0
        public async Task <ActionResult> UpdateDutyComment(int dutyId, string comment)
        {
            var locationIds = await DutyRosterService.GetDutiesLocations(new List <int> {
                dutyId
            });

            if (locationIds.Count != 1)
            {
                return(BadRequest(CannotUpdateCrossLocationError));
            }
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, locationIds.First()))
            {
                return(Forbid());
            }

            await DutyRosterService.UpdateDutyComment(dutyId, comment);

            return(NoContent());
        }
示例#16
0
        public async Task<SheriffActingRank> UpdateSheriffActingRank(DutyRosterService dutyRosterService, ShiftService shiftService, SheriffActingRank actingRank, bool overrideConflicts)
        {
            ValidateStartAndEndDates(actingRank.StartDate, actingRank.EndDate);
            await ValidateSheriffExists(actingRank.SheriffId);

            var savedActingRank = await Db.SheriffActingRank.FindAsync(actingRank.Id);
            savedActingRank.ThrowBusinessExceptionIfNull($"{nameof(SheriffActingRank)} with the id: {actingRank.Id} could not be found. ");

            if (savedActingRank.ExpiryDate.HasValue)
                throw new BusinessLayerException($"{nameof(SheriffActingRank)} with the id: {actingRank.Id} has been expired");

            await ValidateSheriffActingRankExists(actingRank);

            Db.Entry(savedActingRank).CurrentValues.SetValues(actingRank);
            Db.Entry(savedActingRank).Property(x => x.SheriffId).IsModified = false;
            Db.Entry(savedActingRank).Property(x => x.ExpiryDate).IsModified = false;
            Db.Entry(savedActingRank).Property(x => x.ExpiryReason).IsModified = false;
            await Db.SaveChangesAsync();
            return savedActingRank;
        }
示例#17
0
        public async Task <ActionResult <List <DutyDto> > > UpdateDuties(List <UpdateDutyDto> editDuties, bool overrideValidation = false)
        {
            if (editDuties == null)
            {
                return(BadRequest(InvalidDutyErrorMessage));
            }
            var locationIds = await DutyRosterService.GetDutiesLocations(editDuties.SelectToList(d => d.Id));

            if (locationIds.Count != 1)
            {
                return(BadRequest(CannotUpdateCrossLocationError));
            }
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, locationIds.First()))
            {
                return(Forbid());
            }

            var duties = await DutyRosterService.UpdateDuties(editDuties.Adapt <List <Duty> >(), overrideValidation);

            return(Ok(duties.Adapt <List <DutyDto> >()));
        }
示例#18
0
        public async Task <ActionResult <List <DutyDto> > > AddDuties(List <AddDutyDto> newDuties)
        {
            if (newDuties == null)
            {
                return(BadRequest(InvalidDutyErrorMessage));
            }
            var locationIds = newDuties.SelectDistinctToList(d => d.LocationId);

            if (locationIds.Count != 1)
            {
                return(BadRequest(CannotUpdateCrossLocationError));
            }
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, locationIds.First()))
            {
                return(Forbid());
            }

            var duty = await DutyRosterService.AddDuties(newDuties.Adapt <List <Duty> >());

            return(Ok(duty.Adapt <List <DutyDto> >()));
        }
示例#19
0
        public async Task <ActionResult <List <DutyDto> > > GetDuties(int locationId, DateTimeOffset start, DateTimeOffset end)
        {
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, locationId))
            {
                return(Forbid());
            }
            var duties = await DutyRosterService.GetDutiesForLocation(locationId, start, end);

            if (!User.HasPermission(Permission.ViewDutyRosterInFuture))
            {
                var location = await Db.Location.AsNoTracking().FirstOrDefaultAsync(l => l.Id == locationId);

                var timezone         = location.Timezone;
                var currentDate      = DateTimeOffset.UtcNow.ConvertToTimezone(timezone).DateOnly();
                var restrictionHours = float.Parse(Configuration.GetNonEmptyValue("ViewDutyRosterRestrictionHours"));
                var endDate          = currentDate.TranslateDateForDaylightSavings(timezone, hoursToShift: restrictionHours);
                duties = duties.WhereToList(d => d.StartDate < endDate);
            }

            return(Ok(duties.Adapt <List <DutyDto> >()));
        }
示例#20
0
        public async Task <ActionResult> ExpireDuties(List <int> ids)
        {
            if (ids == null)
            {
                return(BadRequest(InvalidDutyErrorMessage));
            }
            var locationIds = await DutyRosterService.GetDutiesLocations(ids);

            if (locationIds.Count != 1)
            {
                return(BadRequest(CannotUpdateCrossLocationError));
            }
            if (!PermissionDataFiltersExtensions.HasAccessToLocation(User, Db, locationIds.First()))
            {
                return(Forbid());
            }

            await DutyRosterService.ExpireDuties(ids);

            return(NoContent());
        }
示例#21
0
 public DutyRosterController(DutyRosterService dutyRosterService, SheriffDbContext db)
 {
     DutyRosterService = dutyRosterService;
     Db = db;
 }
示例#22
0
 public DutyRosterController(DutyRosterService dutyRosterService, SheriffDbContext db, IConfiguration configuration)
 {
     DutyRosterService = dutyRosterService;
     Db            = db;
     Configuration = configuration;
 }