using Company.Domain.RollCallAgg; using CompanyManagment.EFCore; using Microsoft.EntityFrameworkCore; using Query.AdminReports.Models; using System.Data; using _0_Framework.Application; using WorkFlow.Application.Contracts.WorkFlow; namespace Query.AdminReports.Handlers { public interface IGetWorkshopWithRollCallHandler { List Handle(WorkshopWithRollCallServiceQueryParameters parameters); } public class GetWorkshopWithRollCallHandler : IGetWorkshopWithRollCallHandler { private readonly CompanyContext _companyContext; private readonly IWorkFlowApplication workFlowApplication; public GetWorkshopWithRollCallHandler(CompanyContext companyContext, IWorkFlowApplication workFlowApplication) { _companyContext = companyContext; this.workFlowApplication = workFlowApplication; } public List Handle(WorkshopWithRollCallServiceQueryParameters parameters) { var now = DateTime.Now.Date; var lastWeek = now.AddDays(-7); //workshop filter by parameters var rollCallServiceQuery = _companyContext.RollCallServices.AsSplitQuery(); var allWorkshops = _companyContext.Workshops.AsSplitQuery().Select(x => new { x.id, x.WorkshopFullName }); if (parameters.WorkshopId != 0) allWorkshops = allWorkshops.Where(x => x.id == parameters.WorkshopId); if (!string.IsNullOrWhiteSpace(parameters.WorkshopName)) allWorkshops = allWorkshops.Where(x => x.WorkshopFullName.Contains(parameters.WorkshopName)); if (!string.IsNullOrWhiteSpace(parameters.RollCallServiceType)) rollCallServiceQuery = rollCallServiceQuery.Where(x => x.ServiceType == parameters.RollCallServiceType); if (parameters.FilterMode == FilterMode.Active) rollCallServiceQuery = rollCallServiceQuery.Where(x => x.StartService.Date <= now && x.EndService.Date >= now); else if (parameters.FilterMode == FilterMode.DeActive) rollCallServiceQuery = rollCallServiceQuery.Where(x => x.EndService.Date < now || x.StartService.Date > now); var workshopsWithService = rollCallServiceQuery.Join(allWorkshops, x => x.WorkshopId, y => y.id, (rcs, workshop) => new WorkshopWithRollCallServiceQueryModel() { WorkshopId = workshop.id, RollCallServiceType = rcs.ServiceType, WorkshopName = workshop.WorkshopFullName, MaxPersonValid = rcs.MaxPersonValid, IsActive = rcs.StartService <= DateTime.Now && rcs.EndService >= DateTime.Now, ServiceStart = rcs.StartService, ServiceEnd = rcs.EndService }); //workshop population var workshopLeftWorks = _companyContext.Workshops.AsSplitQuery() .Where(x => workshopsWithService.Any(y => y.WorkshopId == x.id)).Include(x => x.LeftWorks) .Include(x => x.LeftWorkInsurances) .Select(x => new { WorkshopId = x.id, LeftWorks = x.LeftWorks.Where(y => y.StartWorkDate <= lastWeek && y.LeftWorkDate > now) .Select(y => y.EmployeeId), LeftWorkInsurances = x.LeftWorkInsurances .Where(y => y.StartWorkDate <= lastWeek && (y.LeftWorkDate > now || y.LeftWorkDate == null)) .Select(y => y.EmployeeId) }).ToList(); var workshopsWorkingEmployeesList = workshopLeftWorks .Select(x => new { x.WorkshopId, TotalWorkingEmployeesCount = x.LeftWorks.Concat(x.LeftWorkInsurances).Distinct().Count(), EmployeeIds = x.LeftWorks.Concat(x.LeftWorkInsurances).Distinct() }).ToList(); var activeEmployees = _companyContext.RollCallEmployees.AsSplitQuery() .Include(x => x.EmployeesStatus) .Where(x => x.EmployeesStatus.Any(y => y.EndDate.Date >= now) && workshopsWithService.Any(y => y.WorkshopId == x.WorkshopId)) .Select(x => new { x.WorkshopId, x.EmployeeId }); var lastWeekRollCalls = _companyContext.RollCalls.AsSplitQuery() .Where(x => x.StartDate.HasValue && x.StartDate.Value >= lastWeek && workshopsWithService .Any(y => y.WorkshopId == x.WorkshopId)) .GroupBy(x => x.EmployeeId) .Select(x => x.Key); var leaves = _companyContext.LeaveList.AsSplitQuery().Where(x => x.StartLeave <= lastWeek && x.EndLeave >= now && (x.LeaveType == "استعلاجی" || x.PaidLeaveType == "روزانه") && workshopsWithService.Any(y => y.WorkshopId == x.WorkshopId)) .Select(x => x.EmployeeId); var activeEmployeesList = activeEmployees.ToList().Where(x => workshopsWorkingEmployeesList.Any(w => w.WorkshopId == x.WorkshopId && w.EmployeeIds.Contains(x.EmployeeId))); var lastWeekRollCallsList = lastWeekRollCalls.ToList(); var leavesList = leaves.ToList(); var workshopsWithServiceList = workshopsWithService.ToList(); return workshopsWithServiceList.GroupBy(x => x.WorkshopId) .Select(x => x.OrderByDescending(y => y.ServiceStartFa).First()) .Select(x => new WorkshopWithRollCallServiceQueryModel() { IsActive = x.IsActive, ServiceStartFa = x.ServiceStart.ToFarsi(), ServiceEndFa = x.ServiceEnd.ToFarsi(), WorkshopId = x.WorkshopId, RollCallServiceType = x.RollCallServiceType, MaxPersonValid = x.MaxPersonValid, WorkshopName = x.WorkshopName, ActiveEmployeesCount = activeEmployeesList.Count(y => y.WorkshopId == x.WorkshopId), ActiveEmployeesWithRollCallInLastWeekCount = activeEmployeesList.Count(y => y.WorkshopId == x.WorkshopId && lastWeekRollCallsList.Contains(y.EmployeeId) && !leavesList.Contains(y.EmployeeId)), TotalEmployeesCount = workshopsWorkingEmployeesList .FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.TotalWorkingEmployeesCount ?? 0, //UndoneWorkFlowsCount = workFlowApplication.GetAllWorkFlowCount(x.WorkshopId).Result }).OrderByDescending(x => x.IsActive).ToList(); } } }