using Brizco.Domain.Entities.Shifts; using MD.PersianDateTime.Standard; namespace Brizco.Repository.Handlers.ShiftPlan; public class GetShiftPlansQueryHandler : IRequestHandler> { private readonly IRepositoryWrapper _repositoryWrapper; private readonly ICurrentUserService _currentUserService; public GetShiftPlansQueryHandler(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService) { _repositoryWrapper = repositoryWrapper; _currentUserService = currentUserService; } public async Task> Handle(GetShiftPlansQuery request, CancellationToken cancellationToken) { if (_currentUserService.ComplexId == null) throw new AppException("ComplexId is null", ApiResultStatusCode.NotFound); if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) throw new AppException("ComplexId is wrong", ApiResultStatusCode.NotFound); IQueryable baseQuery = _repositoryWrapper.SetRepository() .TableNoTracking .OrderByDescending(s => s.CreatedAt) .Where(s => s.ComplexId == complexId); List shiftPlans = new List(); bool setActiviesCount = false; if (request.SelectedDate == 0) { shiftPlans = await baseQuery .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); } else if (request.SelectedDate > 0) { var selectedDate = DateTimeExtensions.UnixTimeStampToDateTime(request.SelectedDate); shiftPlans = await baseQuery.Where(s => s.PlanFor.Date == selectedDate.Date) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); setActiviesCount = true; } if (request.DateTimeQueryFilter != null) { setActiviesCount = true; switch (request.DateTimeQueryFilter) { case DateTimeQueryFilter.Today: shiftPlans = await baseQuery.Where(s => s.PlanFor.Date == DateTime.Now.Date) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.Yesterday: shiftPlans = await baseQuery.Where(s => s.PlanFor.Date == DateTime.Now.AddDays(-1).Date) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.PastWeek: DateTime pastWeekToday = DateTime.Today; int pastWeekDelta = DayOfWeek.Saturday - pastWeekToday.DayOfWeek; if (pastWeekDelta > 0) pastWeekDelta -= 7; DateTime startOfPastWeek = DateTime.Today.AddDays(pastWeekDelta).AddDays(-7); DateTime endOfPastWeek = startOfPastWeek.AddDays(6); shiftPlans = await baseQuery.Where(s => s.PlanFor.Date >= startOfPastWeek.Date && s.PlanFor.Date <= endOfPastWeek.Date) .OrderByDescending(s => s.CreatedAt) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.NextWeek: DateTime startOfNextWeek = DateTime.Today.AddDays(7 - (int)DateTime.Today.DayOfWeek + 1); DateTime endOfNextWeek = startOfNextWeek.AddDays(5); shiftPlans = await baseQuery.Where(s => s.PlanFor.Date >= startOfNextWeek.Date && s.PlanFor.Date <= endOfNextWeek.Date) .OrderByDescending(s => s.CreatedAt) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.ThisWeek: DateTime today = DateTime.Today; int delta = DayOfWeek.Saturday - today.DayOfWeek; if (delta > 0) delta -= 7; DateTime startOfWeek = today.AddDays(delta); DateTime endOfWeek = startOfWeek.AddDays(6); shiftPlans = await baseQuery.Where(s => s.PlanFor.Date >= startOfWeek.Date && s.PlanFor.Date <= endOfWeek.Date) .OrderByDescending(s => s.CreatedAt) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.PastMonth: DateTime startOfPastMonth = new PersianDateTime(PersianDateTime.Today.AddMonths(-1).Year, PersianDateTime.Today.AddMonths(-1).Month, 1).ToDateTime(); DateTime endOfPastMonth = startOfPastMonth.AddMonths(1); shiftPlans = await baseQuery.Where(s => s.PlanFor.Date >= startOfPastMonth.Date && s.PlanFor.Date < endOfPastMonth.Date) .OrderByDescending(s => s.CreatedAt) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.NextMonth: DateTime startOfNextMonth = new PersianDateTime(PersianDateTime.Today.AddMonths(1).Year, PersianDateTime.Today.AddMonths(1).Month, 1).ToDateTime(); DateTime endOfNextMonth = startOfNextMonth.AddMonths(1); shiftPlans = await baseQuery.Where(s => s.PlanFor.Date >= startOfNextMonth.Date && s.PlanFor.Date < endOfNextMonth.Date) .OrderByDescending(s => s.CreatedAt) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.ThisMonth: DateTime startOfThisMonth = new PersianDateTime(PersianDateTime.Today.Year, PersianDateTime.Today.Month, 1).ToDateTime(); DateTime endOfThisMonth = startOfThisMonth.AddMonths(1); shiftPlans = await baseQuery.Where(s => s.PlanFor.Date >= startOfThisMonth.Date && s.PlanFor.Date < endOfThisMonth.Date) .OrderByDescending(s => s.CreatedAt) .Skip(request.Page * 15).Take(15) .Select(ShiftPlanMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case null: break; default: throw new ArgumentOutOfRangeException(); } } if (setActiviesCount) { foreach (var shiftPlan in shiftPlans) { var activitiesCount = await _repositoryWrapper.SetRepository() .TableNoTracking .CountAsync(a => a.SetFor.Date == shiftPlan.PlanFor.Date && a.ShiftPlanId == shiftPlan.Id, cancellationToken); var doneActivitiesCount = await _repositoryWrapper.SetRepository() .TableNoTracking .CountAsync(a => a.Status == ActivityStatus.Done && a.SetFor.Date == shiftPlan.PlanFor.Date && a.ShiftPlanId == shiftPlan.Id, cancellationToken); var undoneActivitiesCount = await _repositoryWrapper.SetRepository() .TableNoTracking .CountAsync(a => a.Status == ActivityStatus.UnDone && a.SetFor.Date == shiftPlan.PlanFor.Date && a.ShiftPlanId == shiftPlan.Id, cancellationToken); shiftPlan.UndoneActivitiesCount = undoneActivitiesCount; shiftPlan.DoneActivitiesCount = doneActivitiesCount; shiftPlan.TotalActivitiesCount = activitiesCount; } } foreach (var shiftPlan in shiftPlans) { shiftPlan.StaffCount = await _repositoryWrapper.SetRepository() .TableNoTracking .CountAsync(spu => spu.ShiftPlanId == shiftPlan.Id, cancellationToken); } return shiftPlans; } }