From d740c36dc683303cc2e241cbf1c7630b81e8280e Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 23 Dec 2025 17:33:09 +0330 Subject: [PATCH 1/4] add: update ProjectBoardDetailResponse to use TotalTimeMinute and SpentTimeMinute --- .../ProjectBoardDetailQueryHandler.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardDetail/ProjectBoardDetailQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardDetail/ProjectBoardDetailQueryHandler.cs index 60de81c1..58a48878 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardDetail/ProjectBoardDetailQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardDetail/ProjectBoardDetailQueryHandler.cs @@ -8,14 +8,13 @@ namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.Project public record ProjectBoardDetailQuery(Guid SectionId) : IBaseQuery; -public record ProjectBoardDetailResponse(List Users, string TotalTime,string RemainingTime ); +public record ProjectBoardDetailResponse(List Users, string TotalTimeMinute,string RemainingTimeMinute ); public record ProjectBoardDetailUserResponse { public List Histories { get; init; } public string UserFullName { get; init; } - public string TotalTime { get; init; } - public string SpentTime { get; init; } + public string SpentTimeMinute { get; init; } public long UserId { get; init; } } @@ -24,7 +23,7 @@ public record ProjectBoardDetailUserHistoryResponse public string Date { get; init; } public string startTime { get; init; } public string EndTime { get; init; } - public string TotalTime { get; init; } + public string TotalTimeMinute { get; init; } } public class ProjectBoardDetailQueryHandler : IBaseQueryHandler @@ -68,18 +67,18 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandlerh.GetTimeSpent().Ticks)).TotalHours.ToString(CultureInfo.InvariantCulture), + SpentTimeMinute = ((int)TimeSpan.FromTicks(x.Sum(h=>h.GetTimeSpent().Ticks)).TotalMinutes).ToString(CultureInfo.InvariantCulture), Histories = x.Select(h => new ProjectBoardDetailUserHistoryResponse() { Date = h.StartDate.ToFarsi(), startTime = h.StartDate.ToString("HH:mm"), EndTime = h.EndDate?.ToString("HH:mm") ?? "-", - TotalTime = h.GetTimeSpent().ToString(@"hh\:mm") + TotalTimeMinute = h.GetTimeSpent().TotalMinutes.ToString("F0",CultureInfo.InvariantCulture) }).ToList() }; }).ToList(); - var response = new ProjectBoardDetailResponse(users, $"{(int)totalActivityTimeSpan.TotalHours}:{totalActivityTimeSpan.Minutes:D2}", - $"{(int)remainingTimeSpan.TotalHours}:{remainingTimeSpan.Minutes:D2}"); + var response = new ProjectBoardDetailResponse(users, $"{(int)finalTime.TotalMinutes}", + $"{(int)remainingTimeSpan.TotalMinutes:D2}"); return OperationResult.Success(response); } } \ No newline at end of file From a191968c15f6136dd91ad8ded987e1d5a1153432 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 23 Dec 2025 18:16:50 +0330 Subject: [PATCH 2/4] add: include Installments in InstitutionContractRepository query --- .../Repository/InstitutionContractRepository.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index c0871074..51d434ef 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -1754,6 +1754,7 @@ public class InstitutionContractRepository : RepositoryBase x.InitialWorkshops) .Include(x => x.WorkshopGroup) .ThenInclude(x => x.CurrentWorkshops) + .Include(x=>x.Installments) .FirstOrDefaultAsync(x => x.id == institutionContractId); } From 134466547e3149469b05bf767ad67e20b141181c Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 23 Dec 2025 18:54:10 +0330 Subject: [PATCH 3/4] add: enhance InstitutionContractRepository to include employer workshops and left work details --- .../InstitutionContractRepository.cs | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index 51d434ef..8e6e4c18 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -2155,6 +2155,10 @@ public class InstitutionContractRepository : RepositoryBase x.WorkshopGroup) .ThenInclude(institutionContractWorkshopGroup => institutionContractWorkshopGroup.CurrentWorkshops) .FirstOrDefaultAsync(x => x.id == extenstionTemp.PreviousId); + + var employerWorkshopIds = _context.Employers.Where(x=>x.ContractingPartyId == prevInstitutionContracts.ContractingPartyId).Include(x=>x.WorkshopEmployers) + .SelectMany(x=>x.WorkshopEmployers).Select(x=>x.WorkshopId).Distinct().ToList(); + if (prevInstitutionContracts == null) { throw new BadRequestException("قرارداد مالی قبلی یافت نشد"); @@ -2167,7 +2171,12 @@ public class InstitutionContractRepository : RepositoryBase x.WorkshopId.Value); - var workshops = await _context.Workshops.Where(x => workshopIds.Contains(x.id)).ToListAsync(); + + var workshopsNotInInstitution = employerWorkshopIds.Where(x=> !workshopIds.Contains(x)).ToList(); + + var workshops = await _context.Workshops.Where(x => workshopIds.Contains(x.id) || employerWorkshopIds.Contains(x.id)) + .ToListAsync(); + var workshopDetails = prevInstitutionContracts.WorkshopGroup.CurrentWorkshops .Select(x => { @@ -2209,6 +2218,32 @@ public class InstitutionContractRepository : RepositoryBase workshopsNotInInstitution.Contains(x.WorkshopId) && x.StartWorkDate <= DateTime.Now && + x.LeftWorkDate >= DateTime.Now) + .GroupBy(x => x.WorkshopId).ToListAsync(); + var notIncludeWorskhopsInContract = workshopsNotInInstitution.Select(x => + { + var workshop = workshops.FirstOrDefault(w => w.id == x); + var leftWorks = notIncludeWorskhopsLeftWork.FirstOrDefault(l=>l.Key ==x); + return new WorkshopTempViewModel() + { + WorkshopName = workshop?.WorkshopName ?? "فاقد کارگاه", + WorkshopServicesAmount = 0, + WorkshopServicesAmountStr = "0", + WorkshopId = x, + Id = 0, + ContractAndCheckout = false, + ContractAndCheckoutInPerson = false, + CustomizeCheckout = false, + CountPerson = leftWorks?.Count()??0, + Insurance = false, + InsuranceInPerson = false, + RollCall = false, + RollCallInPerson = false, + }; + }).ToList(); + workshopDetails = workshopDetails.Concat(notIncludeWorskhopsInContract).ToList(); var res = new InstitutionContractExtensionWorkshopsResponse() { TotalAmount = workshopDetails.Sum(x => x.WorkshopServicesAmount).ToMoney(), From 30b4f52896a98540ad1b39800e97e641d09d7eb4 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 23 Dec 2025 20:16:33 +0330 Subject: [PATCH 4/4] add: refactor RollCall application to support asynchronous operations and enhance transaction handling --- .../RollCall/IRollCallApplication.cs | 2 +- .../CustomizeWorkshopSettingsApplication.cs | 22 ++++++--- .../RollCallApplication.cs | 47 +++++++++++++------ .../Pages/Company/RollCall/Grouping.cshtml.cs | 4 +- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/CompanyManagment.App.Contracts/RollCall/IRollCallApplication.cs b/CompanyManagment.App.Contracts/RollCall/IRollCallApplication.cs index 6ada660b..6ce7bbfd 100644 --- a/CompanyManagment.App.Contracts/RollCall/IRollCallApplication.cs +++ b/CompanyManagment.App.Contracts/RollCall/IRollCallApplication.cs @@ -124,7 +124,7 @@ namespace CompanyManagment.App.Contracts.RollCall /// /// /// - OperationResult RecalculateValues(long workshopId, List command); + Task RecalculateValues(long workshopId, List command); } public class ReCalculateRollCallValues { diff --git a/CompanyManagment.Application/CustomizeWorkshopSettingsApplication.cs b/CompanyManagment.Application/CustomizeWorkshopSettingsApplication.cs index b4f19256..5c3f7e2f 100644 --- a/CompanyManagment.Application/CustomizeWorkshopSettingsApplication.cs +++ b/CompanyManagment.Application/CustomizeWorkshopSettingsApplication.cs @@ -25,6 +25,7 @@ using Microsoft.EntityFrameworkCore.Query; using Company.Domain.CheckoutAgg; using Company.Domain.CustomizeCheckoutAgg; using Company.Domain.CustomizeCheckoutTempAgg; +using Company.Domain.RollCallAgg; using CompanyManagment.EFCore.Repository; @@ -38,7 +39,8 @@ public class CustomizeWorkshopSettingsApplication(ICustomizeWorkshopSettingsRepo IRollCallApplication rollCallAppllication, ICheckoutRepository checkoutRepository, ICustomizeCheckoutRepository customizeCheckoutRepository, - ICustomizeCheckoutTempRepository customizeCheckoutTempRepository) + ICustomizeCheckoutTempRepository customizeCheckoutTempRepository, + IRollCallRepository rollCallRepository) : ICustomizeWorkshopSettingsApplication { private readonly ICustomizeWorkshopSettingsRepository _customizeWorkshopSettingsRepository = customizeWorkshopSettingsRepository; @@ -53,6 +55,7 @@ public class CustomizeWorkshopSettingsApplication(ICustomizeWorkshopSettingsRepo private readonly ICheckoutRepository _checkoutRepository = checkoutRepository; private readonly ICustomizeCheckoutRepository _customizeCheckoutRepository = customizeCheckoutRepository; private readonly ICustomizeCheckoutTempRepository _customizeCheckoutTempRepository = customizeCheckoutTempRepository; + private readonly IRollCallRepository _rollCallRepository = rollCallRepository; #region RollCallShifts @@ -822,14 +825,19 @@ public class CustomizeWorkshopSettingsApplication(ICustomizeWorkshopSettingsRepo var notSelectedEmployeeSettings = employeeSettings.Where(x => !selectedEmployeesIds.Contains(x.EmployeeId)); - var weeklyOffDays = command.OffDayOfWeeks?.Select(x => new WeeklyOffDay(x)).ToList() ?? []; - using var transaction = new TransactionScope(); + var weeklyOffDays = command.OffDayOfWeeks? + .Select(x => new WeeklyOffDay(x)).ToList() ?? []; + + using var rollCallTransaction = _rollCallRepository.BeginTransactionAsync() + .GetAwaiter().GetResult(); entity.EditSimpleAndOverwriteOnEmployee(command.Name, selectedEmployeesIds, groupSettingsShifts, command.WorkshopShiftStatus, command.IrregularShift, breakTime, isChanged, command.HolidayWork, rotatingShift, weeklyOffDays); if (reCalculateCommand.Count > 0) { - var result = _rollCallApplication.RecalculateValues(workshopSettings.WorkshopId, reCalculateCommand); + var result = _rollCallApplication + .RecalculateValues(workshopSettings.WorkshopId, reCalculateCommand) + .GetAwaiter().GetResult(); if (result.IsSuccedded == false) { @@ -844,7 +852,7 @@ public class CustomizeWorkshopSettingsApplication(ICustomizeWorkshopSettingsRepo _customizeWorkshopGroupSettingsRepository.SaveChanges(); - transaction.Complete(); + rollCallTransaction.Commit(); return op.Succcedded(); } public OperationResult EditSimpleRollCallEmployeeSetting(EditCustomizeEmployeeSettings command, @@ -1043,7 +1051,9 @@ public class CustomizeWorkshopSettingsApplication(ICustomizeWorkshopSettingsRepo _customizeWorkshopGroupSettingsRepository.SaveChanges(); if (reCalculateCommand.Count > 0) { - var result = _rollCallApplication.RecalculateValues(command.WorkshopId, reCalculateCommand); + var result = _rollCallApplication + .RecalculateValues(command.WorkshopId, reCalculateCommand) + .GetAwaiter().GetResult(); if (result.IsSuccedded == false) { diff --git a/CompanyManagment.Application/RollCallApplication.cs b/CompanyManagment.Application/RollCallApplication.cs index 1730c70d..e73e4c3e 100644 --- a/CompanyManagment.Application/RollCallApplication.cs +++ b/CompanyManagment.Application/RollCallApplication.cs @@ -788,7 +788,7 @@ public class RollCallApplication : IRollCallApplication return _rollCallRepository.CheckRepeat(employeeId, workshopId); } - public OperationResult RecalculateValues(long workshopId, List commands) + public async Task RecalculateValues(long workshopId, List commands) { var operationResult = new OperationResult(); try @@ -812,24 +812,43 @@ public class RollCallApplication : IRollCallApplication var oldestDate = commands.MinBy(x => x.FromDate).FromDate.ToGeorgianDateTime(); - var allRollCalls = _rollCallRepository + var allRollCalls = await _rollCallRepository .GetRollCallsUntilNowWithWorkshopIdEmployeeIds(workshopId, commands.Select(x => x.EmployeeId).ToList(), - oldestDate).GetAwaiter().GetResult(); + oldestDate); + + var rollCalls = + commands.SelectMany(command => + allRollCalls.Where(x => + x.EmployeeId == command.EmployeeId && + x.ShiftDate >= command.FromDate.ToGeorgianDateTime() + ) + ); - - foreach (var command in commands) + foreach (var rollCall in rollCalls) { - var rollCalls = allRollCalls - .Where(x => x.EmployeeId == command.EmployeeId && x.ShiftDate >= command.FromDate.ToGeorgianDateTime()).ToList(); + rollCall.ClearTimeDiff(); - foreach (var rollCall in rollCalls) - { - rollCall.ClearTimeDiff(); - _rollCallRepository.SaveChanges(); - rollCall.SetEndDateTime(rollCall.EndDate!.Value, _rollCallDomainService); - } + await _rollCallRepository.SaveChangesAsync(); + + rollCall.SetEndDateTime( + rollCall.EndDate!.Value, + _rollCallDomainService + ); } - _rollCallRepository.SaveChanges(); + + // foreach (var command in commands) + // { + // var rollCalls = allRollCalls + // .Where(x => x.EmployeeId == command.EmployeeId && x.ShiftDate >= command.FromDate.ToGeorgianDateTime()).ToList(); + // + // foreach (var rollCall in rollCalls) + // { + // rollCall.ClearTimeDiff(); + // await _rollCallRepository.SaveChangesAsync(); + // rollCall.SetEndDateTime(rollCall.EndDate!.Value, _rollCallDomainService); + // } + // } + await _rollCallRepository.SaveChangesAsync(); return operationResult.Succcedded(); } diff --git a/ServiceHost/Areas/Client/Pages/Company/RollCall/Grouping.cshtml.cs b/ServiceHost/Areas/Client/Pages/Company/RollCall/Grouping.cshtml.cs index 781d76b8..7d41262c 100644 --- a/ServiceHost/Areas/Client/Pages/Company/RollCall/Grouping.cshtml.cs +++ b/ServiceHost/Areas/Client/Pages/Company/RollCall/Grouping.cshtml.cs @@ -293,9 +293,9 @@ namespace ServiceHost.Areas.Client.Pages.Company.RollCall }); } - public IActionResult OnPostReCalculateValues(List command) + public async Task OnPostReCalculateValues(List command) { - var result = _rollCallApplication.RecalculateValues(_workshopId, command); + var result =await _rollCallApplication.RecalculateValues(_workshopId, command); return new JsonResult(new {