/// <summary>
        ///  This can be used to add / update / remove slots.
        /// </summary>
        public async Task <List <Duty> > UpdateDuties(List <Duty> duties, bool overrideValidation)
        {
            if (!duties.Any())
            {
                throw new BusinessLayerException("Didn't provide any duties.");
            }

            await CheckForDutySlotOverlap(duties, overrideValidation);

            var dutyIds     = duties.SelectToList(duty => duty.Id);
            var savedDuties = Db.Duty.AsSingleQuery()
                              .Include(d => d.DutySlots)
                              .Where(s => dutyIds.Contains(s.Id) && s.ExpiryDate == null);


            var shiftIds = duties.SelectMany(d => d.DutySlots).SelectDistinctToList(ds => ds.ShiftId);
            var shifts   = Db.Shift.Where(s => shiftIds.Contains(s.Id));

            foreach (var duty in duties)
            {
                var savedDuty = await savedDuties.FirstOrDefaultAsync(s => s.Id == duty.Id);

                savedDuty.ThrowBusinessExceptionIfNull($"{nameof(Duty)} with the id: {duty.Id} could not be found. ");
                duty.Timezone.GetTimezone().ThrowBusinessExceptionIfNull($"A valid {nameof(duty.Timezone)} must be provided.");
                Db.Entry(savedDuty !).CurrentValues.SetValues(duty);
                Db.Entry(savedDuty).Property(x => x.LocationId).IsModified = false;
                Db.Entry(savedDuty).Property(x => x.ExpiryDate).IsModified = false;

                foreach (var dutySlot in duty.DutySlots)
                {
                    var savedDutySlot = await Db.DutySlot
                                        .FirstOrDefaultAsync(ds => ds.Id == dutySlot.Id && ds.ExpiryDate == null);

                    dutySlot.LocationId = duty.LocationId;
                    dutySlot.DutyId     = duty.Id;
                    dutySlot.Timezone   = duty.Timezone;
                    dutySlot.Duty       = null;
                    dutySlot.Sheriff    = null;
                    dutySlot.Shift      = null;
                    dutySlot.Location   = null;
                    dutySlot.IsOvertime = false;

                    var shift = shifts.FirstOrDefault(s => s.Id == dutySlot.ShiftId && s.ExpiryDate == null);
                    if (shift != null)
                    {
                        if (shift.StartDate > dutySlot.StartDate)
                        {
                            shift.StartDate  = dutySlot.StartDate;
                            shift.IsOvertime = ShiftService.IsShiftOvertime(shift.StartDate, shift.EndDate,
                                                                            shift.Timezone, OvertimeHours);
                            dutySlot.IsOvertime = shift.IsOvertime;
                        }
                        if (shift.EndDate < dutySlot.EndDate)
                        {
                            shift.EndDate    = dutySlot.EndDate;
                            shift.IsOvertime = ShiftService.IsShiftOvertime(shift.StartDate, shift.EndDate,
                                                                            shift.Timezone, OvertimeHours);
                            dutySlot.IsOvertime = shift.IsOvertime;
                        }
                    }

                    if (savedDutySlot == null)
                    {
                        await Db.DutySlot.AddAsync(dutySlot);
                    }
                    else
                    {
                        Db.Entry(savedDutySlot).CurrentValues.SetValues(dutySlot);
                    }
                }
                Db.RemoveRange(savedDuty.DutySlots.Where(ds => duty.DutySlots.All(d => d.Id != ds.Id)));
            }

            await Db.SaveChangesAsync();

            return(await savedDuties.ToListAsync());
        }