Files
Backend-Api/CompanyManagment.EFCore/Repository/AdminMonthlyOverviewRepository.cs
2025-05-26 21:34:21 +03:30

322 lines
15 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using _0_Framework.Application;
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
using _0_Framework.InfraStructure;
using AccountMangement.Infrastructure.EFCore;
using Company.Domain.AdminMonthlyOverviewAgg;
using CompanyManagment.App.Contracts.AdminMonthlyOverview;
using Microsoft.AspNetCore.Authentication;
using Microsoft.EntityFrameworkCore;
namespace CompanyManagment.EFCore.Repository;
public class AdminMonthlyOverviewRepository : RepositoryBase<long, AdminMonthlyOverview>, IAdminMonthlyOverviewRepository
{
private readonly CompanyContext _companyContext;
private readonly AccountContext _accountContext;
public AdminMonthlyOverviewRepository(CompanyContext companyContext, AccountContext accountContext) : base(companyContext)
{
_companyContext = companyContext;
_accountContext = accountContext;
}
public async Task<List<AdminMonthlyOverviewListViewModel>> GetWorkshopStatus(AdminMonthlyOverviewSearchModel searchModel)
{
var year = searchModel.Year;
var month = searchModel.Month;
var accountId = searchModel.AdminAccountId;
// اگر تبدیل تاریخ به میلادی موفق نبود، لیست خالی برگردان
if ($"{year:0000}/{month:00}/01".TryToGeorgianDateTime(out var targetDate) == false)
return [];
_ = $"{year:0000}/{month:00}/01".ToGeorgianDateTime().AddMonthsFa(1, out var nextMonth);
// دریافت اطلاعات ادمین
var adminAccount = await _accountContext.Accounts.FirstOrDefaultAsync(x => x.id == searchModel.AdminAccountId);
// اگر ادمین پیدا نشد، لیست خالی برگردان
if (adminAccount == null)
return [];
// دریافت طرف حساب های معتبر برای تاریخ مورد نظر
var contractingPartyIds = _companyContext.InstitutionContractSet.AsNoTracking()
.Where(c => c.ContractStartGr <= targetDate && c.ContractEndGr >= targetDate)
.Select(c => c.ContractingPartyId);
// دریافت کارگاه‌های مرتبط با اکانت
var workshopAccounts = _companyContext.WorkshopAccounts
.AsNoTracking()
.Where(w => w.AccountId == accountId)
.Select(w => w.WorkshopId).ToList();
var workshopsHasLeftWorkEmployees = _companyContext.LeftWorkList.Where(x =>
((x.StartWorkDate <= targetDate && x.LeftWorkDate.AddDays(-1) >= targetDate)
|| (x.StartWorkDate <= nextMonth && x.LeftWorkDate.AddDays(-1) >= nextMonth)) && 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();
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 notExistAdminMonthlyReviewsWorkshopIds = workshopIds
.Except(adminMonthlyOverviewWorkshopIds)
.ToList();
// ایجاد رکوردهای AdminMonthlyOverview که وجود ندارند
if (notExistAdminMonthlyReviewsWorkshopIds.Any())
await CreateRangeAdminMonthlyOverview(notExistAdminMonthlyReviewsWorkshopIds, month, year);
// به‌روزرسانی وضعیت‌ها
await UpdateAdminMonthlyOverviewStatus(year, month, workshopIds, targetDate, nextMonth);
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);
}
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 <= targetDate && x.LeftWorkDate.AddDays(-1) >= targetDate && 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 <= nextMonth && x.LeftWorkDate.AddDays(-1) >= nextMonth && 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<AdminMonthlyOverViewCounterVm> 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<long> workshopIds, DateTime targetDate, DateTime nextMonth)
{
var workingCheckoutEmployeeIds = _companyContext.LeftWorkList.AsNoTracking()
.Where(x => workshopIds.Contains(x.WorkshopId) && x.StartWorkDate <= targetDate && x.LeftWorkDate.AddDays(-1) >= targetDate)
.Select(x => new { x.WorkshopId, x.EmployeeId });
var workingContractEmployeeIds = _companyContext.LeftWorkList.AsNoTracking()
.Where(x => workshopIds.Contains(x.WorkshopId) && x.StartWorkDate <= nextMonth && x.LeftWorkDate.AddDays(-1) >= nextMonth)
.Select(x => new { x.WorkshopId, x.EmployeeId });
var contractSet = (await _companyContext.Contracts.AsNoTracking()
.Where(x => x.ContarctStart <= nextMonth && x.ContractEnd >= nextMonth && 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 <= targetDate && x.ContractEnd >= targetDate && 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 workshopsContractWithoutEmployees = workshopIds.Except(workingContractGrouping.Select(x => x.WorkshopId)).ToList();
var workshopsWithFullContracts = workingContractGrouping
.Where(g => g.Data.All(emp => contractSet.Contains((emp.WorkshopId, emp.EmployeeId))))
.Select(g => g.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<long> 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();
}
}