using MD.PersianDateTime.Standard; using Activity = Brizco.Domain.Entities.Tasks.Activity; namespace Brizco.Repository.Handlers.Users; public class GetStaffQueryHandler(IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService) : IRequestHandler> { public async Task> Handle(GetStaffQuery request, CancellationToken cancellationToken) { var count = request.Count ?? 10; 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); var baseQuery = repositoryWrapper.SetRepository() .TableNoTracking .OrderByDescending(s => s.CreatedAt) .Where(s => s.ComplexId == complexId); List activities = new List(); switch (request.DateTimeQuery) { case DateTimeQueryFilter.Today: activities = await baseQuery.Where(s => s.SetFor.Date == DateTime.Now.Date) .Skip(request.Page * count).Take(count) .Select(ActivityMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.Yesterday: activities = await baseQuery.Where(s => s.SetFor.Date == DateTime.Now.AddDays(-1).Date) .Skip(request.Page * count).Take(count) .Select(ActivityMapper.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); activities = await baseQuery.Where(s => s.SetFor.Date >= startOfPastWeek.Date && s.SetFor.Date <= endOfPastWeek.Date) .OrderByDescending(s => s.CreatedAt) .Select(ActivityMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.NextWeek: DateTime startOfNextWeek = DateTime.Today.AddDays(7 - (int)DateTime.Today.DayOfWeek + 1); DateTime endOfNextWeek = startOfNextWeek.AddDays(6); activities = await baseQuery.Where(s => s.SetFor.Date >= startOfNextWeek.Date && s.SetFor.Date <= endOfNextWeek.Date) .OrderByDescending(s => s.CreatedAt) .Select(ActivityMapper.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); activities = await baseQuery.Where(s => s.SetFor.Date >= startOfWeek.Date && s.SetFor.Date <= endOfWeek.Date) .OrderByDescending(s => s.CreatedAt) .Select(ActivityMapper.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); activities = await baseQuery.Where(s => s.SetFor.Date >= startOfPastMonth.Date && s.SetFor.Date < endOfPastMonth.Date) .OrderByDescending(s => s.CreatedAt) .Select(ActivityMapper.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); activities = await baseQuery.Where(s => s.SetFor.Date >= startOfNextMonth.Date && s.SetFor.Date < endOfNextMonth.Date) .OrderByDescending(s => s.CreatedAt) .Select(ActivityMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; case DateTimeQueryFilter.ThisMonth: DateTime startOfThisMonth = new PersianDateTime(PersianDateTime.Today.Year, PersianDateTime.Today.Month, 1).ToDateTime(); DateTime endOfThisMonth = startOfThisMonth.AddMonths(1); activities = await baseQuery.Where(s => s.SetFor.Date >= startOfThisMonth.Date && s.SetFor.Date < endOfThisMonth.Date) .OrderByDescending(s => s.CreatedAt) .Select(ActivityMapper.ProjectToSDto) .ToListAsync(cancellationToken); break; default: throw new ArgumentOutOfRangeException(); } var staffs = activities.Select(a => new StaffResponseSDto { FirstName = a.UserFirstName, LastName = a.UserLastName, Id = a.UserId }).ToList(); return staffs.DistinctBy(d => d.Id).ToList(); } }