From 934019c6c686f90ff1af9f51f2ab89e398e3529a Mon Sep 17 00:00:00 2001 From: SamSys Date: Mon, 22 Dec 2025 16:34:42 +0330 Subject: [PATCH 01/11] InsuranceNotCreated tab backend changed --- 0_Framework/Application/StaticWorkshopAccounts.cs | 11 +++++++++++ .../Repository/InsuranceListRepository.cs | 13 +++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/0_Framework/Application/StaticWorkshopAccounts.cs b/0_Framework/Application/StaticWorkshopAccounts.cs index c42fa9bd..44491a69 100644 --- a/0_Framework/Application/StaticWorkshopAccounts.cs +++ b/0_Framework/Application/StaticWorkshopAccounts.cs @@ -39,4 +39,15 @@ public static class StaticWorkshopAccounts /// که کاربر همچنان به کارگاه دسترسی دارد /// public static DateTime ContinuesWorkingDate = new DateTime(2150, 1, 1); + + + /// + /// لیستی آی دی نقش هایی که مسئول بیمه کارگاه هستند + /// 7 : بیمه ارشد + /// 8 : بیمه ساده + /// + public static List InsuranceAccountsRoleIds = [7, 8]; + + + } \ No newline at end of file diff --git a/CompanyManagment.EFCore/Repository/InsuranceListRepository.cs b/CompanyManagment.EFCore/Repository/InsuranceListRepository.cs index da63d47b..727fe0a4 100644 --- a/CompanyManagment.EFCore/Repository/InsuranceListRepository.cs +++ b/CompanyManagment.EFCore/Repository/InsuranceListRepository.cs @@ -1820,19 +1820,24 @@ public class InsuranceListRepository : RepositoryBase, IIns return res; } - public async Task> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel) + public async Task> GetNotCreatedWorkshop(InsuranceListSearchModel searchModel) { if (string.IsNullOrEmpty(searchModel.Month) || string.IsNullOrEmpty(searchModel.Year)) { return []; } + + var workshopsHasInsuranceAccount = await _accountContext + .AccountLeftWorks + .Where(x => StaticWorkshopAccounts.InsuranceAccountsRoleIds.Contains(x.RoleId) && x.IsActive) + .Select(x => x.WorkshopId).Distinct().ToListAsync(); var acountId = _authHelper.CurrentAccountId(); - var accountWorkshopIds = _context.WorkshopAccounts.Where(x => x.AccountId == acountId) + var accountWorkshopIds = _context.WorkshopAccounts.Where(x => x.AccountId == acountId && workshopsHasInsuranceAccount.Contains(x.WorkshopId)) .Select(x => x.WorkshopId); var firstDayOfMonth = $"{searchModel.Year}/{searchModel.Month}/01".ToGeorgianDateTime(); var insuranceWorkshops = _context.Workshops - .Where(x => x.InsuranceCode != null && x.InsuranceCode.Length >= 10 && accountWorkshopIds.Contains(x.id) && + .Where(x => accountWorkshopIds.Contains(x.id) && x.IsActiveString == "true"); @@ -1855,7 +1860,7 @@ public class InsuranceListRepository : RepositoryBase, IIns WorkShopId = result.id, WorkShopCode = result.InsuranceWorkshopInfo != null ? result.InsuranceWorkshopInfo.InsuranceCode - : result.InsuranceCode, + : string.IsNullOrWhiteSpace(result.InsuranceCode) ? "کد کارگاهی ندارد" : result.InsuranceCode, WorkShopName = result.InsuranceWorkshopInfo != null ? result.InsuranceWorkshopInfo.WorkshopName : result.WorkshopFullName, From f27ce460fd6f7b9ab5940effe5e4558570d46049 Mon Sep 17 00:00:00 2001 From: mahan Date: Mon, 22 Dec 2025 17:33:37 +0330 Subject: [PATCH 02/11] feat: integrate RollCallService repository into InstitutionContractApplication and WorkshopApplication --- .../InstitutionContractApplication.cs | 51 ++++++++++++++----- .../WorkshopAppliction.cs | 4 +- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/CompanyManagment.Application/InstitutionContractApplication.cs b/CompanyManagment.Application/InstitutionContractApplication.cs index 2e3e354c..db207cbc 100644 --- a/CompanyManagment.Application/InstitutionContractApplication.cs +++ b/CompanyManagment.Application/InstitutionContractApplication.cs @@ -22,6 +22,7 @@ using Company.Domain.InstitutionContractAgg; using Company.Domain.LeftWorkAgg; using Company.Domain.PaymentTransactionAgg; using Company.Domain.RepresentativeAgg; +using Company.Domain.RollCallServiceAgg; using Company.Domain.TemporaryClientRegistrationAgg; using Company.Domain.WorkshopAgg; using CompanyManagment.App.Contracts.FinancialInvoice; @@ -59,6 +60,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication private readonly IFinancialInvoiceRepository _financialInvoiceRepository; private readonly IPaymentGateway _paymentGateway; private readonly IPaymentTransactionRepository _paymentTransactionRepository; + private readonly IRollCallServiceRepository _rollCallServiceRepository; public InstitutionContractApplication(IInstitutionContractRepository institutionContractRepository, @@ -70,7 +72,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication IFinancialStatmentRepository financialStatmentRepository, IContactInfoApplication contactInfoApplication, IAccountApplication accountApplication, ISmsService smsService, IUidService uidService, IFinancialInvoiceRepository financialInvoiceRepository, IHttpClientFactory httpClientFactory, - IPaymentTransactionRepository paymentTransactionRepository) + IPaymentTransactionRepository paymentTransactionRepository, IRollCallServiceRepository rollCallServiceRepository) { _institutionContractRepository = institutionContractRepository; _contractingPartyRepository = contractingPartyRepository; @@ -88,6 +90,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication _uidService = uidService; _financialInvoiceRepository = financialInvoiceRepository; _paymentTransactionRepository = paymentTransactionRepository; + _rollCallServiceRepository = rollCallServiceRepository; _paymentGateway = new SepehrPaymentGateway(httpClientFactory); } @@ -1555,28 +1558,48 @@ public class InstitutionContractApplication : IInstitutionContractApplication .Where(x => x.WorkshopCreated && x.WorkshopId is > 0).ToList(); var currentWorkshops = institutionContract.WorkshopGroup.CurrentWorkshops.ToList(); + var accountId = _contractingPartyRepository + .GetAccountByPersonalContractingParty(institutionContract.ContractingPartyId).Id; foreach (var createdWorkshop in initialCreatedWorkshops) { if (currentWorkshops.Any(x => x.WorkshopId == createdWorkshop.WorkshopId)) { - continue; + //rollcall serviecs + if (createdWorkshop.Services.RollCall) + { + var ActiveService = _rollCallServiceRepository.GetActiveServiceByWorkshopId(createdWorkshop.WorkshopId!.Value); + var startTime = institutionContract.ContractStartGr; + var endTime = institutionContract.ContractEndGr; + if (ActiveService != null) + { + if (ActiveService.EndService> startTime) + { + startTime = ActiveService.EndService; + } + + } + var rollCallService = new RollCallService("BasedOnIC", + startTime, endTime, createdWorkshop.WorkshopId.Value,accountId,createdWorkshop.PersonnelCount, + 0,"12"); + await _rollCallServiceRepository.CreateAsync(rollCallService); + } + } + else + { + var currentWorkshop = new InstitutionContractWorkshopCurrent(createdWorkshop.WorkshopName, + createdWorkshop.Services.RollCall, createdWorkshop.Services.RollCallInPerson, + createdWorkshop.Services.CustomizeCheckout, createdWorkshop.Services.Contract, + createdWorkshop.Services.ContractInPerson, createdWorkshop.Services.Insurance, + createdWorkshop.Services.InsuranceInPerson,createdWorkshop.PersonnelCount, createdWorkshop.Price, + createdWorkshop.InstitutionContractWorkshopGroupId,createdWorkshop.WorkshopGroup, + createdWorkshop.WorkshopId!.Value, createdWorkshop.id); + institutionContract.WorkshopGroup.AddCurrentWorkshop(currentWorkshop); } - - var currentWorkshop = new InstitutionContractWorkshopCurrent(createdWorkshop.WorkshopName, - createdWorkshop.Services.RollCall, createdWorkshop.Services.RollCallInPerson, - createdWorkshop.Services.CustomizeCheckout, createdWorkshop.Services.Contract, - createdWorkshop.Services.ContractInPerson, createdWorkshop.Services.Insurance, - createdWorkshop.Services.InsuranceInPerson,createdWorkshop.PersonnelCount, createdWorkshop.Price, - createdWorkshop.InstitutionContractWorkshopGroupId,createdWorkshop.WorkshopGroup, - createdWorkshop.WorkshopId!.Value, createdWorkshop.id); - institutionContract.WorkshopGroup.AddCurrentWorkshop(currentWorkshop); - - - } if (institutionContract.WorkshopGroup.InitialWorkshops.All(x => x.WorkshopCreated && x.WorkshopId is > 0)) { + institutionContract.Verified(); } else diff --git a/CompanyManagment.Application/WorkshopAppliction.cs b/CompanyManagment.Application/WorkshopAppliction.cs index e3d69ce8..a6efd5de 100644 --- a/CompanyManagment.Application/WorkshopAppliction.cs +++ b/CompanyManagment.Application/WorkshopAppliction.cs @@ -1092,7 +1092,9 @@ public class WorkshopAppliction : IWorkshopApplication Amount = 1000, MaxPersonValid = 500, Duration = "12", - HasCustomizeCheckoutService = command.HasCustomizeCheckoutService + HasCustomizeCheckoutService = command.HasCustomizeCheckoutService, + StartService = institutionContract.ContractStartGr, + }; _rollCallServiceApplication.Create(commandSave); } From 8750604d962ff0e65b3876ce926b35d32e14236c Mon Sep 17 00:00:00 2001 From: mahan Date: Mon, 22 Dec 2025 17:43:32 +0330 Subject: [PATCH 03/11] feat: add financial transaction handling during institution contract verification --- .../InstitutionContractApplication.cs | 16 +++++++++++++++- .../Controllers/institutionContractController.cs | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CompanyManagment.Application/InstitutionContractApplication.cs b/CompanyManagment.Application/InstitutionContractApplication.cs index 2e3e354c..40b76b97 100644 --- a/CompanyManagment.Application/InstitutionContractApplication.cs +++ b/CompanyManagment.Application/InstitutionContractApplication.cs @@ -1611,9 +1611,23 @@ public class InstitutionContractApplication : IInstitutionContractApplication var transaction = await _institutionContractRepository.BeginTransactionAsync(); await SetPendingWorkflow(institutionContractId,InstitutionContractSigningType.Physical); + var financialStatement = await _financialStatmentRepository + .GetByContractingPartyId(institutionContract.ContractingPartyId); + + DateTime today = DateTime.Today; + var description = institutionContract.IsInstallment + ? "قسط اول سرویس" + : "پرداخت کل سرویس"; + var debtorAmount = institutionContract.IsInstallment + ? institutionContract.Installments.First().Amount + : institutionContract.TotalAmount; + + var financialTransaction = new FinancialTransaction(0, today, today.ToFarsi(), + description, "debt", "بابت خدمات", debtorAmount, 0, 0); + financialStatement.AddFinancialTransaction(financialTransaction); - await transaction.CommitAsync(); await _institutionContractRepository.SaveChangesAsync(); + await transaction.CommitAsync(); return op.Succcedded(); } diff --git a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs index e343674a..4f8c9651 100644 --- a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs +++ b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs @@ -809,7 +809,7 @@ public class institutionContractController : AdminBaseController } [HttpPost("mannual-verify/{id}")] - public async Task> VerifyInstitutionContractMannualy(long id) + public async Task> VerifyInstitutionContractManually(long id) { var res= await _institutionContractApplication.VerifyInstitutionContractManually(id); return res; From 19f78a230cbc1e29cfcb5d54dcb0d75a870ba6f1 Mon Sep 17 00:00:00 2001 From: SamSys Date: Mon, 22 Dec 2025 17:46:02 +0330 Subject: [PATCH 04/11] change --- .../InstitutionPlan/InstitutionPlanSearchModel.cs | 4 ++-- .../Repository/PlanPercentageRepository.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CompanyManagment.App.Contracts/InstitutionPlan/InstitutionPlanSearchModel.cs b/CompanyManagment.App.Contracts/InstitutionPlan/InstitutionPlanSearchModel.cs index 34e5d347..f6055430 100644 --- a/CompanyManagment.App.Contracts/InstitutionPlan/InstitutionPlanSearchModel.cs +++ b/CompanyManagment.App.Contracts/InstitutionPlan/InstitutionPlanSearchModel.cs @@ -5,7 +5,7 @@ namespace CompanyManagment.App.Contracts.InstitutionPlan; public class InstitutionPlanSearchModel : PaginationRequest { /// - /// تعدلد پرسنل برای جستجو + /// تعداد پرسنل برای جستجو /// - public int CountPeron { get; set; } + public int CountPerson { get; set; } } \ No newline at end of file diff --git a/CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs b/CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs index b5b6db6b..57d41be0 100644 --- a/CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs +++ b/CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs @@ -340,8 +340,8 @@ public class PlanPercentageRepository : RepositoryBase, IP .Select(x => x.ItemValue).FirstOrDefault(); var plans = _context.InstitutionPlans.AsQueryable(); - if (searchModel.CountPeron > 0) - plans = plans.Where(x => x.CountPerson == searchModel.CountPeron); + if (searchModel.CountPerson > 0) + plans = plans.Where(x => x.CountPerson == searchModel.CountPerson); var planQueryFilter =await plans.ApplyPagination(searchModel.PageIndex, searchModel.PageSize).ToListAsync(); var planResult = planQueryFilter.Select(plan => From acec101c4c374e3dc6dc99353154ecdcbc833d1c Mon Sep 17 00:00:00 2001 From: Mahan Chamani <109232147+mahanch@users.noreply.github.com> Date: Mon, 22 Dec 2025 18:24:02 +0330 Subject: [PATCH 05/11] Update deployment password in workflow file --- .github/workflows/dotnet-developPublish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-developPublish.yml b/.github/workflows/dotnet-developPublish.yml index aace164d..934a413f 100644 --- a/.github/workflows/dotnet-developPublish.yml +++ b/.github/workflows/dotnet-developPublish.yml @@ -37,7 +37,7 @@ jobs: & "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" ` -verb:sync ` -source:contentPath="$publishFolder" ` - -dest:contentPath="dadmehrg",computerName="https://171.22.24.15:8172/msdeploy.axd?site=dadmehrg",userName="Administrator",password="R2rNpdnetP3j>q5b18",authType="Basic" ` + -dest:contentPath="dadmehrg",computerName="https://171.22.24.15:8172/msdeploy.axd?site=dadmehrg",userName="Administrator",password="R",authType="Basic" ` -allowUntrusted ` -enableRule:AppOffline From 6a446d597248d0c47eddad5a0a24a0d852b8cf3a Mon Sep 17 00:00:00 2001 From: mahan Date: Mon, 22 Dec 2025 19:13:34 +0330 Subject: [PATCH 06/11] add: implement AutoStopOverTimeTaskSections command and related functionality --- .../AutoStopOverTimeTaskSectionsCommand.cs | 49 +++++++++++++++++++ .../ProjectAgg/Entities/TaskSection.cs | 35 +++++++++++++ .../Entities/TaskSectionActivity.cs | 16 ++++++ .../Repositories/ITaskSectionRepository.cs | 2 + .../Repositories/TaskSectionRepository.cs | 10 ++++ .../ProgramManager/ProjectController.cs | 4 ++ 6 files changed, 116 insertions(+) create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AutoStopOverTimeTaskSections/AutoStopOverTimeTaskSectionsCommand.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AutoStopOverTimeTaskSections/AutoStopOverTimeTaskSectionsCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AutoStopOverTimeTaskSections/AutoStopOverTimeTaskSectionsCommand.cs new file mode 100644 index 00000000..892d4844 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AutoStopOverTimeTaskSections/AutoStopOverTimeTaskSectionsCommand.cs @@ -0,0 +1,49 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoStopOverTimeTaskSections; + +public record AutoStopOverTimeTaskSectionsCommand : IBaseCommand; + +public class AutoStopOverTimeTaskSectionsCommandHandler : IBaseCommandHandler +{ + private readonly ITaskSectionRepository _taskSectionRepository; + private readonly IUnitOfWork _unitOfWork; + + public AutoStopOverTimeTaskSectionsCommandHandler(ITaskSectionRepository taskSectionRepository, + IUnitOfWork unitOfWork) + { + _taskSectionRepository = taskSectionRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(AutoStopOverTimeTaskSectionsCommand request, + CancellationToken cancellationToken) + { + try + { + // دریافت تمام تسک‌های در حال انجام + var taskSections = await _taskSectionRepository.GetActiveSectionsIncludeAllAsync(cancellationToken); + + + foreach (var taskSection in taskSections) + { + // استفاده از متد Domain برای بررسی و متوقف کردن خودکار + taskSection.AutoStopIfOverTime(); + } + + // ذخیره تغییرات در دیتابیس + await _unitOfWork.SaveChangesAsync(cancellationToken); + + return OperationResult.Success(); + } + catch (Exception ex) + { + return OperationResult.Failure($"خطا در ناتمام کردن تسک‌های overtime: {ex.Message}"); + } + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs index 7fd3f3e8..7209dd00 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs @@ -217,4 +217,39 @@ public class TaskSection : EntityBase var finalEstimate = FinalEstimatedHours; return totalSpent < finalEstimate; } + + /// + /// اگر زمان کار شده بیش از تایم تعیین شده باشد، تسک را متوقف می‌کند + /// و EndDate را به طوری تنظیم می‌کند که کل زمان برابر با FinalEstimatedHours شود + /// + public void AutoStopIfOverTime() + { + if (Status != TaskSectionStatus.InProgress) + return; + + var activeActivity = _activities.FirstOrDefault(a => a.IsActive); + if (activeActivity == null) + return; + + // محاسبه کل زمان صرف شده تا کنون (بدون فعالیت فعال) + var totalTimeSpentExcludingActive = _activities.Where(a => !a.IsActive).Sum(a => a.GetTimeSpent().Ticks); + var totalTimeSpentTimeSpan = TimeSpan.FromTicks(totalTimeSpentExcludingActive); + var finalEstimate = FinalEstimatedHours; + + // اگر زمان صرف شده (بدون فعالیت فعال) + فعالیت فعال > تایم تعیین شده + var activeTimeSpent = activeActivity.GetTimeSpent(); + if (totalTimeSpentTimeSpan + activeTimeSpent > finalEstimate) + { + // محاسبه مدت زمانی که این فعالیت باید برای رسیدن به FinalEstimatedHours داشته باشد + var remainingTime = finalEstimate - totalTimeSpentTimeSpan; + + // EndDate = StartDate + remainingTime + var adjustedEndDate = activeActivity.StartDate.Add(remainingTime); + + // متوقف کردن فعالیت با EndDate دقیق شده + activeActivity.StopWorkWithSpecificTime(adjustedEndDate, "متوقف خودکار - بیش از تایم تعیین شده"); + + UpdateStatus(TaskSectionStatus.Incomplete); + } + } } \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs index 85e60d0d..04b3a7e3 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs @@ -40,6 +40,22 @@ public class TaskSectionActivity : EntityBase IsActive = false; } + /// + /// متوقف کردن فعالیت با مشخص کردن EndDate دقیق + /// + public void StopWorkWithSpecificTime(DateTime endDate, string? endNotes = null) + { + if (!IsActive) + throw new InvalidOperationException("این فعالیت قبلاً متوقف شده است."); + + if (endDate < StartDate) + throw new InvalidOperationException("تاریخ پایان نمی‌تواند قبل از تاریخ شروع باشد."); + + EndDate = endDate; + EndNotes = endNotes; + IsActive = false; + } + public TimeSpan GetTimeSpent() { if (IsActive) diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs index d9c11d75..b4a4c5dd 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs @@ -1,3 +1,4 @@ +using System.Collections; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; @@ -11,4 +12,5 @@ public interface ITaskSectionRepository: IRepository Task GetByIdWithFullDataAsync(Guid id, CancellationToken cancellationToken = default); Task> GetAssignedToUserAsync(long userId); + Task> GetActiveSectionsIncludeAllAsync(CancellationToken cancellationToken); } \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs index 41551be5..89fb05fd 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence._Common; using GozareshgirProgramManager.Infrastructure.Persistence.Context; @@ -35,4 +36,13 @@ public class TaskSectionRepository:RepositoryBase,ITaskSection .Where(x => x.CurrentAssignedUserId == userId) .ToListAsync(); } + + public Task> GetActiveSectionsIncludeAllAsync(CancellationToken cancellationToken) + { + return _context.TaskSections + .Where(x => x.Status == TaskSectionStatus.InProgress) + .Include(x => x.Activities) + .Include(x => x.AdditionalTimes) + .ToListAsync(cancellationToken); + } } \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs index dc46d47a..225a1e9b 100644 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs @@ -1,6 +1,7 @@ using System.Runtime.InteropServices; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoStopOverTimeTaskSections; using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection; using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; using GozareshgirProgramManager.Application.Modules.Projects.Commands.DeleteProject; @@ -98,6 +99,9 @@ public class ProjectController : ProgramManagerBaseController [HttpGet("board")] public async Task>>> GetProjectBoard([FromQuery] ProjectBoardListQuery query) { + // اجرای Command برای متوقف کردن تسک‌های overtime قبل از نمایش + await _mediator.Send(new AutoStopOverTimeTaskSectionsCommand()); + var res = await _mediator.Send(query); return res; } From 1bfe41418ba4cdb99707feb8bba85cdf806b0a4d Mon Sep 17 00:00:00 2001 From: mahan Date: Mon, 22 Dec 2025 19:51:21 +0330 Subject: [PATCH 07/11] add: enhance ProjectBoardDetailResponse to include RemainingTime and user time details --- .../ProjectBoardDetailQueryHandler.cs | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 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 467ed43e..60de81c1 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 @@ -1,3 +1,4 @@ +using System.Globalization; using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain._Common; @@ -7,21 +8,23 @@ namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.Project public record ProjectBoardDetailQuery(Guid SectionId) : IBaseQuery; -public record ProjectBoardDetailResponse(List Users, string TotalTime); +public record ProjectBoardDetailResponse(List Users, string TotalTime,string RemainingTime ); public record ProjectBoardDetailUserResponse { - public List Histories { get; set; } = new(); - public string UserFullName { get; set; } - public long UserId { get; set; } + public List Histories { get; init; } + public string UserFullName { get; init; } + public string TotalTime { get; init; } + public string SpentTime { get; init; } + public long UserId { get; init; } } -public class ProjectBoardDetailUserHistoryResponse +public record ProjectBoardDetailUserHistoryResponse { - public string Date { get; set; } - public string startTime { get; set; } - public string EndTime { get; set; } - public string TotalTime { get; set; } + public string Date { get; init; } + public string startTime { get; init; } + public string EndTime { get; init; } + public string TotalTime { get; init; } } public class ProjectBoardDetailQueryHandler : IBaseQueryHandler @@ -38,6 +41,7 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler x.Activities) + .Include(x=>x.AdditionalTimes) .FirstOrDefaultAsync(x => x.Id == request.SectionId, cancellationToken: cancellationToken); if (section == null) @@ -49,16 +53,22 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler userIds.Contains(x.Id)) .ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken); - var totalTimeSpan = section.Activities + var totalActivityTimeSpan = section.Activities .Select(x => x.GetTimeSpent()) .Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next)); + var finalTime = section.FinalEstimatedHours; + + var remainingTimeSpan = finalTime >= totalActivityTimeSpan + ? TimeSpan.FromTicks(finalTime.Ticks - totalActivityTimeSpan.Ticks) + : TimeSpan.Zero; var users = section.Activities.GroupBy(x => x.UserId).Select(x => { return new ProjectBoardDetailUserResponse() { UserId = x.Key, UserFullName = usersDict[x.Key], + TotalTime = TimeSpan.FromTicks(x.Sum(h=>h.GetTimeSpent().Ticks)).TotalHours.ToString(CultureInfo.InvariantCulture), Histories = x.Select(h => new ProjectBoardDetailUserHistoryResponse() { Date = h.StartDate.ToFarsi(), @@ -68,7 +78,8 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler.Success(response); } } \ No newline at end of file From 72e3859d2c98424b1370f722ea67ced3c0de7ae1 Mon Sep 17 00:00:00 2001 From: SamSys Date: Tue, 23 Dec 2025 04:17:52 +0330 Subject: [PATCH 08/11] next ui upload from wbe completed --- .../Pages/Company/AndroidApk/Index.cshtml | 8 ++--- .../Pages/Company/AndroidApk/Index.cshtml.cs | 32 +++++++++++++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml index 3a0adbd2..01468b20 100644 --- a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml +++ b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml @@ -74,8 +74,8 @@
-
-
+
+
-
+
-
+
diff --git a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs index 042099da..7d6eedfd 100644 --- a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs +++ b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs @@ -332,19 +332,39 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk var validAccountId = _authHelper.CurrentAccountId(); if (validAccountId == 2 || validAccountId == 322) { - var batPath = @"C:\next-ui\deploy-next-ui.bat"; + //var batPath = @"C:\next-ui\deploy-next-ui.bat"; + + //var psi = new ProcessStartInfo + //{ + // FileName = batPath, + // UseShellExecute = true, // خیلی مهم + // Verb = "runas", // اجرای Administrator + // CreateNoWindow = true, + // WindowStyle = ProcessWindowStyle.Hidden + //}; + + //Process.Start(psi); var psi = new ProcessStartInfo { - FileName = batPath, - UseShellExecute = true, // خیلی مهم - Verb = "runas", // اجرای Administrator - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden + FileName = "cmd.exe", + Arguments = "/c schtasks /run /tn \"DeployNextUI\"", + UseShellExecute = false, + CreateNoWindow = true }; Process.Start(psi); + //var psi = new ProcessStartInfo + //{ + // FileName = @"C:\next-ui\deploy-next-ui.bat", + // UseShellExecute = false, + // CreateNoWindow = false + //}; + + //Process.Start(psi); + + TempData["Message"] = "فرآیند Deploy شروع شد. لاگ را بررسی کنید."; return RedirectToPage(); } From 1a9174391652a3966fffddf5400d60c3930256be Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 23 Dec 2025 10:50:11 +0330 Subject: [PATCH 09/11] add: update CalculateDiscount method to include contractStart parameter --- .../IInstitutionContractRepository.cs | 2 +- .../Repository/InstitutionContractRepository.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs index 124bc1bb..e10f15ed 100644 --- a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs +++ b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs @@ -56,7 +56,7 @@ public interface IInstitutionContractRepository : IRepository GetVerificationDetails(Guid id); Task GetByPublicIdAsync(Guid id); - InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request); + InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request,string contractStart = null); InstitutionContractDiscountResponse ResetDiscountCreate(InstitutionContractResetDiscountForCreateRequest request); diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index 6ae60e32..c0871074 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -1895,7 +1895,7 @@ public class InstitutionContractRepository : RepositoryBase x.PublicId == id); } - public InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request) + public InstitutionContractDiscountResponse CalculateDiscount(InstitutionContractSetDiscountRequest request,string contractStart=null) { var baseAmount = request.TotalAmount; var discountAmount = (baseAmount * request.DiscountPercentage) / 100; @@ -2356,7 +2356,7 @@ public class InstitutionContractRepository : RepositoryBase Date: Tue, 23 Dec 2025 13:46:59 +0330 Subject: [PATCH 10/11] GetList PlanPercentage CountAsync --- .../Repository/PlanPercentageRepository.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs b/CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs index 57d41be0..50ade919 100644 --- a/CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs +++ b/CompanyManagment.EFCore/Repository/PlanPercentageRepository.cs @@ -343,6 +343,8 @@ public class PlanPercentageRepository : RepositoryBase, IP if (searchModel.CountPerson > 0) plans = plans.Where(x => x.CountPerson == searchModel.CountPerson); + var count = await plans.CountAsync(); + var planQueryFilter =await plans.ApplyPagination(searchModel.PageIndex, searchModel.PageSize).ToListAsync(); var planResult = planQueryFilter.Select(plan => new InstitutionPlanViewModel @@ -403,7 +405,7 @@ public class PlanPercentageRepository : RepositoryBase, IP return new PagedResult() { - TotalCount = finalResult.Count, + TotalCount = count, List = finalResult }; From 76408c48cff2e06a784d0f51af687601b42ce826 Mon Sep 17 00:00:00 2001 From: SamSys Date: Tue, 23 Dec 2025 15:31:12 +0330 Subject: [PATCH 11/11] IsAmendment SetPendingWorkflow ... --- CompanyManagment.Application/InstitutionContractApplication.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CompanyManagment.Application/InstitutionContractApplication.cs b/CompanyManagment.Application/InstitutionContractApplication.cs index a052a062..0e2e4804 100644 --- a/CompanyManagment.Application/InstitutionContractApplication.cs +++ b/CompanyManagment.Application/InstitutionContractApplication.cs @@ -1593,7 +1593,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication createdWorkshop.Services.ContractInPerson, createdWorkshop.Services.Insurance, createdWorkshop.Services.InsuranceInPerson,createdWorkshop.PersonnelCount, createdWorkshop.Price, createdWorkshop.InstitutionContractWorkshopGroupId,createdWorkshop.WorkshopGroup, - createdWorkshop.WorkshopId!.Value, createdWorkshop.id); + createdWorkshop.WorkshopId!.Value, false,createdWorkshop.id); institutionContract.WorkshopGroup.AddCurrentWorkshop(currentWorkshop); } }