diff --git a/CompanyManagment.EFCore/Repository/AdminMonthlyOverviewRepository.cs b/CompanyManagment.EFCore/Repository/AdminMonthlyOverviewRepository.cs index 05823b6c..71b7b637 100644 --- a/CompanyManagment.EFCore/Repository/AdminMonthlyOverviewRepository.cs +++ b/CompanyManagment.EFCore/Repository/AdminMonthlyOverviewRepository.cs @@ -18,332 +18,421 @@ namespace CompanyManagment.EFCore.Repository; public class AdminMonthlyOverviewRepository : RepositoryBase, IAdminMonthlyOverviewRepository { - private readonly CompanyContext _companyContext; - private readonly AccountContext _accountContext; - public AdminMonthlyOverviewRepository(CompanyContext companyContext, AccountContext accountContext) : base(companyContext) - { - _companyContext = companyContext; - _accountContext = accountContext; - } + private readonly CompanyContext _companyContext; + private readonly AccountContext _accountContext; + public AdminMonthlyOverviewRepository(CompanyContext companyContext, AccountContext accountContext) : base(companyContext) + { + _companyContext = companyContext; + _accountContext = accountContext; + } - public async Task> GetWorkshopStatus(AdminMonthlyOverviewSearchModel searchModel) - { + public async Task> GetWorkshopStatus(AdminMonthlyOverviewSearchModel searchModel) + { - var year = searchModel.Year; - var month = searchModel.Month; - var accountId = searchModel.AdminAccountId; - // اگر تبدیل تاریخ به میلادی موفق نبود، لیست خالی برگردان - if ($"{year:0000}/{month:00}/01".TryToGeorgianDateTime(out var targetStartDate) == false) - return []; - var targetEndDate = Tools.FindeEndOfMonth(targetStartDate.ToFarsi()).ToGeorgianDateTime(); + var year = searchModel.Year; + var month = searchModel.Month; + var accountId = searchModel.AdminAccountId; + // اگر تبدیل تاریخ به میلادی موفق نبود، لیست خالی برگردان + if ($"{year:0000}/{month:00}/01".TryToGeorgianDateTime(out var targetStartDate) == false) + return []; + var targetEndDate = Tools.FindeEndOfMonth(targetStartDate.ToFarsi()).ToGeorgianDateTime(); - _ = $"{year:0000}/{month:00}/01".ToGeorgianDateTime().AddMonthsFa(1, out var nextFirstMonth); - var nextEndMonth = Tools.FindeEndOfMonth(nextFirstMonth.ToFarsi()).ToGeorgianDateTime(); + _ = $"{year:0000}/{month:00}/01".ToGeorgianDateTime().AddMonthsFa(1, out var nextFirstMonth); + var nextEndMonth = Tools.FindeEndOfMonth(nextFirstMonth.ToFarsi()).ToGeorgianDateTime(); - // دریافت اطلاعات ادمین - var adminAccount = await _accountContext.Accounts.FirstOrDefaultAsync(x => x.id == searchModel.AdminAccountId); + // دریافت اطلاعات ادمین + var adminAccount = await _accountContext.Accounts.FirstOrDefaultAsync(x => x.id == searchModel.AdminAccountId); - // اگر ادمین پیدا نشد، لیست خالی برگردان - if (adminAccount == null) - return []; + // اگر ادمین پیدا نشد، لیست خالی برگردان + if (adminAccount == null) + return []; - // دریافت طرف حساب های معتبر برای تاریخ مورد نظر - var contractingPartyIds = _companyContext.InstitutionContractSet.AsNoTracking() - .Where(c => c.ContractStartGr <= targetEndDate && c.ContractEndGr >= targetStartDate) - .Select(c => c.ContractingPartyId); + // دریافت طرف حساب های معتبر برای تاریخ مورد نظر + var contractingPartyIds = _companyContext.InstitutionContractSet.AsNoTracking() + .Where(c => c.ContractStartGr <= targetEndDate && c.ContractEndGr >= targetStartDate) + .Select(c => c.ContractingPartyId); - // دریافت کارگاه‌های مرتبط با اکانت + // دریافت کارگاه‌های مرتبط با اکانت - var workshopAccounts = _companyContext.WorkshopAccounts - .AsNoTracking() - .Where(w => w.AccountId == accountId) - .Select(w => w.WorkshopId).ToList(); + var workshopAccounts = _companyContext.WorkshopAccounts + .AsNoTracking() + .Where(w => w.AccountId == accountId) + .Select(w => w.WorkshopId).ToList(); - var workshopsHasLeftWorkEmployees = _companyContext.LeftWorkList.Where(x => - ((x.StartWorkDate <= targetEndDate && x.LeftWorkDate.AddDays(-1) >= targetStartDate) - || (x.StartWorkDate <= nextEndMonth && x.LeftWorkDate.AddDays(-1) >= nextFirstMonth)) && workshopAccounts.Contains(x.WorkshopId)).Select(x => x.WorkshopId); + var workshopsHasLeftWorkEmployees = _companyContext.LeftWorkList.Where(x => + ((x.StartWorkDate <= targetEndDate && x.LeftWorkDate.AddDays(-1) >= targetStartDate) + || (x.StartWorkDate <= nextEndMonth && x.LeftWorkDate.AddDays(-1) >= nextFirstMonth)) && workshopAccounts.Contains(x.WorkshopId)).Select(x => x.WorkshopId); - // دریافت کارگاه‌های مربوط به طرف حساب و اکانت - // Replace the selected code with the following to return a list of anonymous objects containing both workshop and contractingParty - var workshopsWithContractingParty = await _companyContext.Workshops - .AsNoTracking() - .Where(w => workshopsHasLeftWorkEmployees.Contains(w.id) && w.IsActive) - .Include(w => w.WorkshopEmployers) - .ThenInclude(we => we.Employer) - .ThenInclude(e => e.ContractingParty).AsSplitQuery(). - Where(w => w.WorkshopEmployers.Any(we => - we.Employer != null && - contractingPartyIds.Contains(we.Employer.ContractingPartyId))) - .Select(w => new - { - Workshop = w, - ContractingParty = w.WorkshopEmployers - .Where(we => we.Employer != null && contractingPartyIds.Contains(we.Employer.ContractingPartyId)) - .Select(we => we.Employer.ContractingParty) - .FirstOrDefault() - }) - .ToListAsync(); + // دریافت کارگاه‌های مربوط به طرف حساب و اکانت + // Replace the selected code with the following to return a list of anonymous objects containing both workshop and contractingParty + var workshopsWithContractingParty = await _companyContext.Workshops + .AsNoTracking() + .Where(w => workshopsHasLeftWorkEmployees.Contains(w.id) && w.IsActive) + .Include(w => w.WorkshopEmployers) + .ThenInclude(we => we.Employer) + .ThenInclude(e => e.ContractingParty).AsSplitQuery(). + Where(w => w.WorkshopEmployers.Any(we => + we.Employer != null && + contractingPartyIds.Contains(we.Employer.ContractingPartyId))) + .Select(w => new + { + Workshop = w, + ContractingParty = w.WorkshopEmployers + .Where(we => we.Employer != null && contractingPartyIds.Contains(we.Employer.ContractingPartyId)) + .Select(we => we.Employer.ContractingParty) + .FirstOrDefault() + }) + .ToListAsync(); - var workshopIds = workshopsWithContractingParty.Select(x => x.Workshop.id).ToList(); + var workshopIds = workshopsWithContractingParty.Select(x => x.Workshop.id).ToList(); - // پیدا کردن کارگاه‌هایی که قبلاً برای این ماه/سال AdminMonthlyOverview دارند - var adminMonthlyOverviewWorkshopIds = await _companyContext.AdminMonthlyOverviews - .AsNoTracking() - .Where(x => workshopIds.Contains(x.WorkshopId) && x.Month == month && x.Year == year) - .Select(x => x.WorkshopId) - .ToListAsync(); + // پیدا کردن کارگاه‌هایی که قبلاً برای این ماه/سال AdminMonthlyOverview دارند + var adminMonthlyOverviewWorkshopIds = await _companyContext.AdminMonthlyOverviews + .AsNoTracking() + .Where(x => workshopIds.Contains(x.WorkshopId) && x.Month == month && x.Year == year) + .Select(x => x.WorkshopId) + .ToListAsync(); - // پیدا کردن کارگاه‌هایی که نیاز به ایجاد AdminMonthlyOverview جدید دارند - var notExistAdminMonthlyReviewsWorkshopIds = workshopIds - .Except(adminMonthlyOverviewWorkshopIds) - .ToList(); + // پیدا کردن کارگاه‌هایی که نیاز به ایجاد AdminMonthlyOverview جدید دارند + var notExistAdminMonthlyReviewsWorkshopIds = workshopIds + .Except(adminMonthlyOverviewWorkshopIds) + .ToList(); - // ایجاد رکوردهای AdminMonthlyOverview که وجود ندارند - if (notExistAdminMonthlyReviewsWorkshopIds.Any()) - await CreateRangeAdminMonthlyOverview(notExistAdminMonthlyReviewsWorkshopIds, month, year); - - // به‌روزرسانی وضعیت‌ها - await UpdateAdminMonthlyOverviewStatus(year, month, workshopIds, targetStartDate,targetEndDate, nextFirstMonth,nextEndMonth); + // ایجاد رکوردهای AdminMonthlyOverview که وجود ندارند + if (notExistAdminMonthlyReviewsWorkshopIds.Any()) + await CreateRangeAdminMonthlyOverview(notExistAdminMonthlyReviewsWorkshopIds, month, year); + + // به‌روزرسانی وضعیت‌ها + await UpdateAdminMonthlyOverviewStatus(year, month, workshopIds, targetStartDate, targetEndDate, nextFirstMonth, nextEndMonth); - if (searchModel.ActivationStatus != IsActive.None) - { - var isBlock = searchModel.ActivationStatus == IsActive.True ? "false" : "true"; - - workshopsWithContractingParty = workshopsWithContractingParty - .Where(x => x.ContractingParty?.IsBlock == isBlock).ToList(); + if (searchModel.ActivationStatus != IsActive.None) + { + var isBlock = searchModel.ActivationStatus == IsActive.True ? "false" : "true"; + + workshopsWithContractingParty = workshopsWithContractingParty + .Where(x => x.ContractingParty?.IsBlock == isBlock).ToList(); - workshopIds = workshopsWithContractingParty.Select(x => x.Workshop.id).ToList(); - } - - // دریافت همه AdminMonthlyOverview برای این کارگاه‌ها/ماه/سال - var adminMonthlyOverviewsQuery = _companyContext.AdminMonthlyOverviews - .Where(x => workshopIds.Contains(x.WorkshopId) && x.Month == month && x.Year == year); - - if (searchModel.WorkshopId > 0) - { - adminMonthlyOverviewsQuery = adminMonthlyOverviewsQuery.Where(x => x.WorkshopId == searchModel.WorkshopId); - } + workshopIds = workshopsWithContractingParty.Select(x => x.Workshop.id).ToList(); + } + + // دریافت همه AdminMonthlyOverview برای این کارگاه‌ها/ماه/سال + var adminMonthlyOverviewsQuery = _companyContext.AdminMonthlyOverviews + .Where(x => workshopIds.Contains(x.WorkshopId) && x.Month == month && x.Year == year); + + if (searchModel.WorkshopId > 0) + { + adminMonthlyOverviewsQuery = adminMonthlyOverviewsQuery.Where(x => x.WorkshopId == searchModel.WorkshopId); + } - if (searchModel.EmployerId > 0) - { - var searchWorkshopId = workshopsWithContractingParty.Where(x => x.Workshop.WorkshopEmployers.Any(e => e.EmployerId == searchModel.EmployerId)).Select(x => x.Workshop.id).ToList(); - adminMonthlyOverviewsQuery = adminMonthlyOverviewsQuery.Where(x => searchWorkshopId.Contains(x.WorkshopId)); - } - - var employeeCheckoutCounts = _companyContext.LeftWorkList.Where(x => - x.StartWorkDate <= targetStartDate && x.LeftWorkDate.AddDays(-1) >= targetStartDate && workshopIds.Contains(x.WorkshopId)) - .GroupBy(x => x.WorkshopId).Select(x => new { EmployeeCounts = x.Count(), WorkshopId = x.Key }).ToList(); - - var employeeContractCounts = _companyContext.LeftWorkList.Where(x => - x.StartWorkDate <= nextFirstMonth && x.LeftWorkDate.AddDays(-1) >= nextFirstMonth && workshopIds.Contains(x.WorkshopId)) - .GroupBy(x => x.WorkshopId).Select(x => new { EmployeeCounts = x.Count(), WorkshopId = x.Key }).ToList(); - - var adminMonthlyOverviewsList = await adminMonthlyOverviewsQuery.ToListAsync(); - - var now = DateTime.Today; - //پرسنل ادمین اجرایی - var operatorAdminAccounts = _accountContext.AccountLeftWorks - .Where(x => workshopIds.Contains(x.WorkshopId) && x.StartWorkGr <= now && x.LeftWorkGr >= now && - x.RoleId == 5).Select(x => new { x.WorkshopId, x.AccountId }) - .Join(_accountContext.Accounts, - x => x.AccountId, - account => account.id, (x, account) => new - { - x.WorkshopId, - account.Fullname - }).ToList(); - - - - - - - var adminMonthlyOverviewList = adminMonthlyOverviewsList.Select(x => - { - var employeeCheckoutCount = employeeCheckoutCounts.FirstOrDefault(e => e.WorkshopId == x.WorkshopId); - var employeeContractCount = employeeContractCounts.FirstOrDefault(e => e.WorkshopId == x.WorkshopId); - var workshopWithContractingParty = - workshopsWithContractingParty.FirstOrDefault(w => w.Workshop.id == x.WorkshopId); - - var operatorAccount = operatorAdminAccounts.FirstOrDefault(o => o.WorkshopId == x.WorkshopId); - - var workshop = workshopWithContractingParty?.Workshop; - var contractingParty = workshopWithContractingParty?.ContractingParty; - var employer = workshop?.WorkshopEmployers.FirstOrDefault()?.Employer; - return new AdminMonthlyOverviewListViewModel - { - WorkshopId = x.WorkshopId, - Status = x.Status, - Id = x.id, - WorkshopName = workshop?.WorkshopFullName ?? "", - WorkshopArchiveCode = workshop?.ArchiveCode ?? "", - WorkshopArchiveCodeInt = workshop?.ArchiveCode.ExtractIntNumbers() ?? 0, - Address = workshop?.Address ?? "", - City = workshop?.City ?? "", - Province = workshop?.State ?? "", - EmployerName = employer?.FullName ?? "", - EmployerPhoneNumber = employer?.Phone ?? "", - AdminFullName = operatorAccount?.Fullname ?? "", - CheckoutEmployeeCount = employeeCheckoutCount?.EmployeeCounts ?? 0, - ContractEmployeeCount = employeeContractCount?.EmployeeCounts ?? 0, - AgentPhoneNumber = "", - IsBlock = contractingParty?.IsBlock == "true" - }; - }).OrderBy(x => x.IsBlock).ThenBy(x => x.WorkshopArchiveCodeInt).ToList(); - - - return adminMonthlyOverviewList; - } - - public async Task GetCounter(int year, int month, long accountId) - { - var searchModel = new AdminMonthlyOverviewSearchModel() - { - AdminAccountId = accountId, - Month = month, - Year = year - }; - var list = await GetWorkshopStatus(searchModel); - - var allCount = list.Count; - var archivedCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.Archived); - var createDocCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.CreateDocuments); - var visitCompleteCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.VisitCompleted); - var visitInProgressCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.VisitInProgress); - var visitPendingCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.VisitPending); - - return new AdminMonthlyOverViewCounterVm - { - All = allCount, - Archived = archivedCount, - VisitPending = visitPendingCount, - VisitInProgress = visitInProgressCount, - VisitCompleted = visitCompleteCount, - CreateDocument = createDocCount - - }; - - } - - private async Task UpdateAdminMonthlyOverviewStatus(int year, int month, List workshopIds, DateTime targetStartDate,DateTime targetEndDate, DateTime nextStartMonth,DateTime nextEndMonth) - { - var vipGroup = _companyContext.CustomizeWorkshopEmployeeSettings.Where(x => x.CustomizeWorkshopGroupSettingId == 117) - .Select(x => x.EmployeeId) - .Except([5976]).ToList(); - - var workingCheckoutEmployeeIds = _companyContext.LeftWorkList.AsNoTracking() - .Join( - _companyContext.Contracts.AsNoTracking(), - leftWork => new { leftWork.EmployeeId, WorkshopId = leftWork.WorkshopId }, - contract => new { contract.EmployeeId, WorkshopId = contract.WorkshopIds }, - (leftWork, contract) => new { leftWork, contract } - ) - .Where(x => - workshopIds.Contains(x.leftWork.WorkshopId) && - x.leftWork.StartWorkDate <= targetEndDate && - x.leftWork.LeftWorkDate.AddDays(-1) >= targetStartDate && - x.contract.ContarctStart <= targetEndDate && - x.contract.ContractEnd >= targetStartDate && - !vipGroup.Contains(x.leftWork.EmployeeId) && - !_companyContext.EmployeeClientTemps - .Any(temp => temp.EmployeeId == x.leftWork.EmployeeId && temp.WorkshopId == x.leftWork.WorkshopId) - ) - .Select(x => new { x.leftWork.WorkshopId, x.leftWork.EmployeeId }); - - var workingContractEmployeeIds = _companyContext.LeftWorkList.AsNoTracking() - .Where(x => workshopIds.Contains(x.WorkshopId) && x.StartWorkDate <= nextEndMonth && x.LeftWorkDate.AddDays(-1) >= nextStartMonth && - !vipGroup.Contains(x.EmployeeId) && - !_companyContext.EmployeeClientTemps - .Any(temp => temp.EmployeeId == x.EmployeeId && temp.WorkshopId == x.WorkshopId) - ).Select(x => new { x.WorkshopId, x.EmployeeId }); - - var contractSet = (await _companyContext.Contracts.AsNoTracking() - .Where(x => x.ContarctStart <= nextEndMonth && x.ContractEnd >= nextStartMonth && workshopIds.Contains(x.WorkshopIds)) - .Select(x => new { x.WorkshopIds, x.EmployeeId }) - .ToListAsync()) - .Select(x => (x.WorkshopIds, x.EmployeeId)) - .ToHashSet(); - - var checkoutSet = (await _companyContext.CheckoutSet.AsNoTracking() - .Where(x => x.ContractStart <= targetEndDate && x.ContractEnd >= targetStartDate && workshopIds.Contains(x.WorkshopId)) - .Select(x => new { x.WorkshopId, x.EmployeeId }) - .ToListAsync()) - .Select(x => (x.WorkshopId, x.EmployeeId)) - .ToHashSet(); - - var workingCheckoutGrouping = workingCheckoutEmployeeIds.GroupBy(x => x.WorkshopId).ToList(); - - var workingContractGrouping = workingContractEmployeeIds.GroupBy(x => x.WorkshopId).Select(x => new - { - WorkshopId = x.Key, - Data = x.ToList() - }).ToList(); - - var workshopsWithFullContracts = workingContractGrouping - .Where(g => g.Data.All(emp => contractSet.Contains((emp.WorkshopId, emp.EmployeeId)))) - .Select(g => g.WorkshopId) - .ToList(); - - var list = workingContractEmployeeIds.ToList().Where(x=>!contractSet.Any(a=>a.EmployeeId== x.EmployeeId&&a.WorkshopIds == x.WorkshopId)).ToList(); - - var workshopsWithFullCheckout = workingCheckoutGrouping - .Where(g => g.All(emp => checkoutSet.Contains((emp.WorkshopId, emp.EmployeeId)))) - .Select(g => g.Key) - .ToList(); - - - var fullyCoveredWorkshops = workshopsWithFullContracts.Intersect(workshopsWithFullCheckout).ToList(); - - //var notFullyCoveredWorkshops = groupedCheckout - // .Where(g => g.Any(emp => - // !contractSet.Contains((emp.WorkshopId, emp.EmployeeId)) || - // !checkoutSet.Contains((emp.WorkshopId, emp.EmployeeId)))) - // .Select(g => g.Key) - // .ToList(); - - var notFullyCoveredWorkshops = workshopIds.Except(fullyCoveredWorkshops); - - var adminMonthlyOverviews = _companyContext.AdminMonthlyOverviews - .Where(x => x.Month == month && x.Year == year); - - var adminMonthlyOverviewsWithFullContracts = await adminMonthlyOverviews - .Where(x => fullyCoveredWorkshops.Contains(x.WorkshopId) && x.Status == AdminMonthlyOverviewStatus.CreateDocuments) - .ToListAsync(); - - var adminMonthlyOverviewsWithNotFullContracts = await adminMonthlyOverviews - .Where(x => notFullyCoveredWorkshops.Contains(x.WorkshopId) && x.Status != AdminMonthlyOverviewStatus.CreateDocuments) - .ToListAsync(); - - foreach (var adminMonthlyOverview in adminMonthlyOverviewsWithFullContracts) - adminMonthlyOverview.SetStatus(AdminMonthlyOverviewStatus.VisitPending); - - foreach (var adminMonthlyOverview in adminMonthlyOverviewsWithNotFullContracts) - adminMonthlyOverview.SetStatus(AdminMonthlyOverviewStatus.CreateDocuments); - - await _companyContext.SaveChangesAsync(); - } - - private async Task CreateRangeAdminMonthlyOverview(List workshopIds, int month, int year) - { - foreach (var workshopId in workshopIds) - { - var adminMonthlyOverview = - new AdminMonthlyOverview(workshopId, month, year, AdminMonthlyOverviewStatus.CreateDocuments); - await _companyContext.AddAsync(adminMonthlyOverview); - } - - await _companyContext.SaveChangesAsync(); - } + if (searchModel.EmployerId > 0) + { + var searchWorkshopId = workshopsWithContractingParty.Where(x => x.Workshop.WorkshopEmployers.Any(e => e.EmployerId == searchModel.EmployerId)).Select(x => x.Workshop.id).ToList(); + adminMonthlyOverviewsQuery = adminMonthlyOverviewsQuery.Where(x => searchWorkshopId.Contains(x.WorkshopId)); + } + + var employeeCheckoutCounts = _companyContext.LeftWorkList.Where(x => + x.StartWorkDate <= targetStartDate && x.LeftWorkDate.AddDays(-1) >= targetStartDate && workshopIds.Contains(x.WorkshopId)) + .GroupBy(x => x.WorkshopId).Select(x => new { EmployeeCounts = x.Count(), WorkshopId = x.Key }).ToList(); + + var employeeContractCounts = _companyContext.LeftWorkList.Where(x => + x.StartWorkDate <= nextFirstMonth && x.LeftWorkDate.AddDays(-1) >= nextFirstMonth && workshopIds.Contains(x.WorkshopId)) + .GroupBy(x => x.WorkshopId).Select(x => new { EmployeeCounts = x.Count(), WorkshopId = x.Key }).ToList(); + + var adminMonthlyOverviewsList = await adminMonthlyOverviewsQuery.ToListAsync(); + + var now = DateTime.Today; + //پرسنل ادمین اجرایی + var operatorAdminAccounts = _accountContext.AccountLeftWorks + .Where(x => workshopIds.Contains(x.WorkshopId) && x.StartWorkGr <= now && x.LeftWorkGr >= now && + x.RoleId == 5).Select(x => new { x.WorkshopId, x.AccountId }) + .Join(_accountContext.Accounts, + x => x.AccountId, + account => account.id, (x, account) => new + { + x.WorkshopId, + account.Fullname + }).ToList(); + + + + + + + var adminMonthlyOverviewList = adminMonthlyOverviewsList.Select(x => + { + var employeeCheckoutCount = employeeCheckoutCounts.FirstOrDefault(e => e.WorkshopId == x.WorkshopId); + var employeeContractCount = employeeContractCounts.FirstOrDefault(e => e.WorkshopId == x.WorkshopId); + var workshopWithContractingParty = + workshopsWithContractingParty.FirstOrDefault(w => w.Workshop.id == x.WorkshopId); + + var operatorAccount = operatorAdminAccounts.FirstOrDefault(o => o.WorkshopId == x.WorkshopId); + + var workshop = workshopWithContractingParty?.Workshop; + var contractingParty = workshopWithContractingParty?.ContractingParty; + var employer = workshop?.WorkshopEmployers.FirstOrDefault()?.Employer; + return new AdminMonthlyOverviewListViewModel + { + WorkshopId = x.WorkshopId, + Status = x.Status, + Id = x.id, + WorkshopName = workshop?.WorkshopFullName ?? "", + WorkshopArchiveCode = workshop?.ArchiveCode ?? "", + WorkshopArchiveCodeInt = workshop?.ArchiveCode.ExtractIntNumbers() ?? 0, + Address = workshop?.Address ?? "", + City = workshop?.City ?? "", + Province = workshop?.State ?? "", + EmployerName = employer?.FullName ?? "", + EmployerPhoneNumber = employer?.Phone ?? "", + AdminFullName = operatorAccount?.Fullname ?? "", + CheckoutEmployeeCount = employeeCheckoutCount?.EmployeeCounts ?? 0, + ContractEmployeeCount = employeeContractCount?.EmployeeCounts ?? 0, + AgentPhoneNumber = "", + IsBlock = contractingParty?.IsBlock == "true" + }; + }).OrderBy(x => x.IsBlock).ThenBy(x => x.WorkshopArchiveCodeInt).ToList(); + + + return adminMonthlyOverviewList; + } + + public async Task GetCounter(int year, int month, long accountId) + { + var searchModel = new AdminMonthlyOverviewSearchModel() + { + AdminAccountId = accountId, + Month = month, + Year = year + }; + var list = await GetWorkshopStatus(searchModel); + + var allCount = list.Count; + var archivedCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.Archived); + var createDocCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.CreateDocuments); + var visitCompleteCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.VisitCompleted); + var visitInProgressCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.VisitInProgress); + var visitPendingCount = list.Count(x => x.Status == AdminMonthlyOverviewStatus.VisitPending); + + return new AdminMonthlyOverViewCounterVm + { + All = allCount, + Archived = archivedCount, + VisitPending = visitPendingCount, + VisitInProgress = visitInProgressCount, + VisitCompleted = visitCompleteCount, + CreateDocument = createDocCount + + }; + + } + + private async Task UpdateAdminMonthlyOverviewStatus(int year, int month, List workshopIds, DateTime targetStartDate, DateTime targetEndDate, DateTime nextStartMonth, DateTime nextEndMonth) + { + var vipGroup = _companyContext.CustomizeWorkshopEmployeeSettings.Where(x => x.CustomizeWorkshopGroupSettingId == 117) + .Select(x => x.EmployeeId) + .Except([5976]).ToHashSet(); + + + var workingCheckoutEmployeeIds = GetWorkingCheckoutEmployeeIds(workshopIds, targetStartDate, targetEndDate, vipGroup); + + var workingContractEmployeeIds = _companyContext.LeftWorkList.AsNoTracking(). + GroupJoin(_companyContext.EmployeeComputeOptionsSet.Where(o => workshopIds.Contains(o.WorkshopId)), + x => new { x.EmployeeId, x.WorkshopId }, + option => new { option.EmployeeId, option.WorkshopId }, + (x, options) => new { LeftWork = x, options }) + .SelectMany( + x => x.options.DefaultIfEmpty(), + (x, option) => new { x.LeftWork, option }) + .Where(x => workshopIds.Contains(x.LeftWork.WorkshopId) && x.LeftWork.StartWorkDate <= nextEndMonth && x.LeftWork.LeftWorkDate.AddDays(-1) >= nextStartMonth && + !vipGroup.Contains(x.LeftWork.EmployeeId) && + !_companyContext.EmployeeClientTemps + .Any(temp => temp.EmployeeId == x.LeftWork.EmployeeId && temp.WorkshopId == x.LeftWork.WorkshopId) && + x.option != null ? + x.option.CreateCheckout + : x.LeftWork.Workshop.CreateCheckout) + .Select(x => new { x.LeftWork.WorkshopId, x.LeftWork.EmployeeId }); + + var contractSet = (await _companyContext.Contracts.AsNoTracking() + .Where(x => x.ContarctStart <= nextEndMonth && x.ContractEnd >= nextStartMonth && workshopIds.Contains(x.WorkshopIds)) + .Select(x => new { x.WorkshopIds, x.EmployeeId }) + .ToListAsync()) + .Select(x => (x.WorkshopIds, x.EmployeeId)) + .ToHashSet(); + + var checkoutSet = (await _companyContext.CheckoutSet.AsNoTracking() + .Where(x => x.ContractStart <= targetEndDate && x.ContractEnd >= targetStartDate && workshopIds.Contains(x.WorkshopId)) + .Select(x => new { x.WorkshopId, x.EmployeeId }) + .ToListAsync()) + .Select(x => (x.WorkshopId, x.EmployeeId)) + .ToHashSet(); + + var workingCheckoutGrouping = workingCheckoutEmployeeIds.GroupBy(x => x.WorkshopId).ToList(); + + var workingContractGrouping = workingContractEmployeeIds.GroupBy(x => x.WorkshopId).Select(x => new + { + WorkshopId = x.Key, + Data = x.ToList() + }).ToList(); + + var workshopsWithFullContracts = workingContractGrouping + .Where(g => g.Data.All(emp => contractSet.Contains((emp.WorkshopId, emp.EmployeeId)))) + .Select(g => g.WorkshopId) + .ToList(); + + var list = workingContractEmployeeIds.ToList().Where(x => !contractSet.Any(a => a.EmployeeId == x.EmployeeId && a.WorkshopIds == x.WorkshopId)).ToList(); + + var workshopsWithFullCheckout = workingCheckoutGrouping + .Where(g => g.All(emp => checkoutSet.Contains((emp.WorkshopId, emp.EmployeeId)))) + .Select(g => g.Key) + .ToList(); + + + var fullyCoveredWorkshops = workshopsWithFullContracts.Intersect(workshopsWithFullCheckout).ToList(); + + //var notFullyCoveredWorkshops = groupedCheckout + // .Where(g => g.Any(emp => + // !contractSet.Contains((emp.WorkshopId, emp.EmployeeId)) || + // !checkoutSet.Contains((emp.WorkshopId, emp.EmployeeId)))) + // .Select(g => g.Key) + // .ToList(); + + var notFullyCoveredWorkshops = workshopIds.Except(fullyCoveredWorkshops); + + var adminMonthlyOverviews = _companyContext.AdminMonthlyOverviews + .Where(x => x.Month == month && x.Year == year); + + var adminMonthlyOverviewsWithFullContracts = await adminMonthlyOverviews + .Where(x => fullyCoveredWorkshops.Contains(x.WorkshopId) && x.Status == AdminMonthlyOverviewStatus.CreateDocuments) + .ToListAsync(); + + var adminMonthlyOverviewsWithNotFullContracts = await adminMonthlyOverviews + .Where(x => notFullyCoveredWorkshops.Contains(x.WorkshopId) && x.Status != AdminMonthlyOverviewStatus.CreateDocuments) + .ToListAsync(); + + foreach (var adminMonthlyOverview in adminMonthlyOverviewsWithFullContracts) + adminMonthlyOverview.SetStatus(AdminMonthlyOverviewStatus.VisitPending); + + foreach (var adminMonthlyOverview in adminMonthlyOverviewsWithNotFullContracts) + adminMonthlyOverview.SetStatus(AdminMonthlyOverviewStatus.CreateDocuments); + + await _companyContext.SaveChangesAsync(); + } + + + private async Task CreateRangeAdminMonthlyOverview(List workshopIds, int month, int year) + { + foreach (var workshopId in workshopIds) + { + var adminMonthlyOverview = + new AdminMonthlyOverview(workshopId, month, year, AdminMonthlyOverviewStatus.CreateDocuments); + await _companyContext.AddAsync(adminMonthlyOverview); + } + + await _companyContext.SaveChangesAsync(); + } + private List<(long WorkshopId,long EmployeeId)> GetWorkingCheckoutEmployeeIds(List workshopIds, DateTime targetStartDate, DateTime targetEndDate, + HashSet vipGroup) + { + //var workingCheckoutEmployeeIds = _companyContext.LeftWorkList.AsNoTracking() + // .Join( + // _companyContext.Contracts.AsNoTracking(), + // leftWork => new { leftWork.EmployeeId, WorkshopId = leftWork.WorkshopId }, + // contract => new { contract.EmployeeId, WorkshopId = contract.WorkshopIds }, + // (leftWork, contract) => new { leftWork, contract } + // ).GroupJoin(_companyContext.EmployeeComputeOptionsSet.Where(o => workshopIds.Contains(o.WorkshopId)), + // x => new { x.leftWork.EmployeeId, x.leftWork.WorkshopId }, + // option => new { option.EmployeeId, option.WorkshopId }, + // (x, options) => new { x.leftWork, x.contract, options }) + // .SelectMany( + // x => x.options.DefaultIfEmpty(), + // (x, option) => new { x.leftWork, x.contract, option }) + // .Where(x => + // workshopIds.Contains(x.leftWork.WorkshopId) && + // x.leftWork.StartWorkDate <= targetEndDate && + // x.leftWork.LeftWorkDate.AddDays(-1) >= targetStartDate && + // x.contract.ContarctStart <= targetEndDate && + // x.contract.ContractEnd >= targetStartDate && + // !vipGroup.Contains(x.leftWork.EmployeeId) && + // !_companyContext.EmployeeClientTemps + // .Any(temp => temp.EmployeeId == x.leftWork.EmployeeId && temp.WorkshopId == x.leftWork.WorkshopId) && + // x.option != null + // ? x.option.CreateCheckout + // : x.leftWork.Workshop.CreateCheckout + // ) + // .Select(x => new { x.leftWork.WorkshopId, x.leftWork.EmployeeId }); + + + var chcekoutLeftWorks = _companyContext.LeftWorkList + .AsNoTracking() + .Where(x => + workshopIds.Contains(x.WorkshopId) && + x.StartWorkDate <= targetEndDate && + x.LeftWorkDate.AddDays(-1) >= targetStartDate && + !vipGroup.Contains(x.EmployeeId)) + .Select(x => new + { + x.EmployeeId, + x.WorkshopId, + x.StartWorkDate, + x.LeftWorkDate, + x.Workshop.CreateCheckout + }) + .ToList(); + + var checkoutContracts = _companyContext.Contracts + .AsNoTracking() + .Where(x => + workshopIds.Contains(x.WorkshopIds) && + x.ContarctStart <= targetEndDate && + x.ContractEnd >= targetStartDate) + .Select(x => new + { + x.EmployeeId, + WorkshopId = x.WorkshopIds, + x.ContarctStart, + x.ContractEnd + }) + .ToList(); + + var computeOptionsDict = _companyContext.EmployeeComputeOptionsSet + .AsNoTracking() + .Where(o => workshopIds.Contains(o.WorkshopId)) + .ToDictionary( + o => (o.EmployeeId, o.WorkshopId), + o => o.CreateCheckout + ); + + var clientTemps = _companyContext.EmployeeClientTemps + .AsNoTracking().AsEnumerable() + .Select(x => (x.EmployeeId, x.WorkshopId)) + .ToHashSet(); + + var workingCheckoutEmployeeIds = chcekoutLeftWorks + .Join( + checkoutContracts, + left => new { left.EmployeeId, left.WorkshopId }, + contract => new { contract.EmployeeId, contract.WorkshopId }, + (left, contract) => new { left, contract }) + .Where(x => + !clientTemps.Contains((x.left.EmployeeId, x.left.WorkshopId)) && + (computeOptionsDict.TryGetValue((x.left.EmployeeId, x.left.WorkshopId), out var createCheckout) + ? createCheckout + : x.left.CreateCheckout)) + .Select(x => ( + x.left.WorkshopId, + x.left.EmployeeId + )).ToList(); + return workingCheckoutEmployeeIds; + } } \ No newline at end of file