322 lines
15 KiB
C#
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();
|
|
}
|
|
} |