Files
Backend-Api/CompanyManagment.EFCore/Repository/AdminMonthlyOverviewRepository.cs
2025-05-25 21:40:07 +03:30

274 lines
12 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 [];
// دریافت اطلاعات ادمین
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 && c.IsActiveString == "true")
.Select(c => c.ContractingPartyId);
// دریافت کارگاه‌های مرتبط با اکانت
var accountWorkshopIds = _companyContext.WorkshopAccounts
.AsNoTracking()
.Where(w => w.AccountId == accountId)
.Select(w => w.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 => accountWorkshopIds.Contains(w.id))
.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);
if (searchModel.ActivationStatus != IsActive.None)
{
var isBlock = searchModel.ActivationStatus == IsActive.True ? "true" : "false";
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 adminMonthlyOverviewsList = await adminMonthlyOverviewsQuery.ToListAsync();
var employeeCounts = _companyContext.LeftWorkList.Where(x =>
x.StartWorkDate < targetDate && x.LeftWorkDate > targetDate && workshopIds.Contains(x.WorkshopId))
.GroupBy(x => x.WorkshopId).Select(x => new { EmployeeCounts = x.Count(), WorkshopId = x.Key }).ToList();
var adminMonthlyOverviewList = adminMonthlyOverviewsList.Select(x =>
{
var employeeCount = employeeCounts.FirstOrDefault(e => e.WorkshopId == x.WorkshopId);
var workshopWithContractingParty =
workshopsWithContractingParty.FirstOrDefault(w => w.Workshop.id == 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 ?? "",
Address = workshop?.Address ?? "",
City = workshop?.City ?? "",
Province = workshop?.State ?? "",
EmployerName = employer?.FullName ?? "",
EmployerPhoneNumber = employer?.Phone ?? "",
AdminFullName = adminAccount.Fullname,
EmployeeCount = employeeCount?.EmployeeCounts ?? 0,
AgentPhoneNumber = "",
IsBlock = contractingParty?.IsBlock == "true"
};
}).OrderBy(x => x.IsBlock).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)
{
var targetDate = $"{year:0000}/{month:00}/01".ToGeorgianDateTime();
_ = $"{year:0000}/{month:00}/01".ToGeorgianDateTime().AddMonthsFa(1, out var nextMonth);
var workingEmployeeIds = (await _companyContext.LeftWorkList.AsNoTracking()
.Where(x => workshopIds.Contains(x.WorkshopId) && x.StartWorkDate <= targetDate && x.LeftWorkDate >= targetDate)
.Select(x => new { x.WorkshopId, x.EmployeeId })
.ToListAsync()).Distinct();
var contractSet = (await _companyContext.Contracts.AsNoTracking()
.Where(x => x.ContarctStart <= nextMonth && x.ContractEnd >= nextMonth)
.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)
.Select(x => new { x.WorkshopId, x.EmployeeId })
.ToListAsync())
.Select(x => (x.WorkshopId, x.EmployeeId))
.ToHashSet();
var grouped = workingEmployeeIds.GroupBy(x => x.WorkshopId).ToList();
var workshopsWithFullContracts = grouped
.Where(g => g.All(emp => contractSet.Contains((emp.WorkshopId, emp.EmployeeId))))
.Select(g => g.Key)
.ToList();
var workshopsWithFullCheckout = grouped
.Where(g => g.All(emp => checkoutSet.Contains((emp.WorkshopId, emp.EmployeeId))))
.Select(g => g.Key)
.ToList();
var fullyCoveredWorkshops = workshopsWithFullContracts.Intersect(workshopsWithFullCheckout).ToList();
var notFullyCoveredWorkshops = grouped
.Where(g => g.Any(emp =>
!contractSet.Contains((emp.WorkshopId, emp.EmployeeId)) ||
!checkoutSet.Contains((emp.WorkshopId, emp.EmployeeId))))
.Select(g => g.Key)
.ToList();
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();
}
}