diff --git a/.github/workflows/dotnet-developPublish.yml b/.github/workflows/dotnet-developPublish.yml index 37566664..90302b17 100644 --- a/.github/workflows/dotnet-developPublish.yml +++ b/.github/workflows/dotnet-developPublish.yml @@ -36,6 +36,6 @@ 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 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/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs index 4d045c9a..c0b3b3f8 100644 --- a/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs +++ b/Company.Domain/InstitutionContractAgg/IInstitutionContractRepository.cs @@ -55,7 +55,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.Application/InstitutionContractApplication.cs b/CompanyManagment.Application/InstitutionContractApplication.cs index ad369caf..a052a062 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); } @@ -1556,28 +1559,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, false,createdWorkshop.id); - institutionContract.WorkshopGroup.AddCurrentWorkshop(currentWorkshop); - - - } if (institutionContract.WorkshopGroup.InitialWorkshops.All(x => x.WorkshopCreated && x.WorkshopId is > 0)) { + institutionContract.Verified(); } else @@ -1627,9 +1650,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/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); } diff --git a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs index 3050b957..656005d0 100644 --- a/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs +++ b/CompanyManagment.EFCore/Repository/InstitutionContractRepository.cs @@ -1898,7 +1898,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; @@ -2359,7 +2359,7 @@ public class InstitutionContractRepository : 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"); @@ -1851,36 +1856,36 @@ public class InsuranceListRepository : RepositoryBase, IIns .Include(x => x.LeftWorkInsurances) .Where(x => x.LeftWorkInsurances.Any(l => l.StartWorkDate <= firstDayOfMonth && (l.LeftWorkDate == null || l.LeftWorkDate >= firstDayOfMonth))); - - - var query = notCreatedWorkshop.Select(result => new InsuranceListViewModel - { - Year = searchModel.Year, - Month = searchModel.Month, - WorkShopId = result.id, - WorkShopCode = result.InsuranceWorkshopInfo != null - ? result.InsuranceWorkshopInfo.InsuranceCode - : result.InsuranceCode, - WorkShopName = result.InsuranceWorkshopInfo != null - ? result.InsuranceWorkshopInfo.WorkshopName - : result.WorkshopFullName, - TypeOfInsuranceSend = result.TypeOfInsuranceSend == "NormalList" ? "عادی" : - result.TypeOfInsuranceSend == "Govermentlist" ? "کمک دولت" : - result.TypeOfInsuranceSend == "Familylist" ? "خانوادگی" : "", - FixedSalary = result.FixedSalary, - StrFixedSalary = result.FixedSalary ? "دارد" : "ندارد", - EmployerName = result.InsuranceWorkshopInfo != null - ? result.InsuranceWorkshopInfo.EmployerName - : result.WorkshopFullName, - Branch = "", - City = "", - ArchiveCode = result.ArchiveCode, - }); - - - if (!string.IsNullOrEmpty(searchModel.Month) && searchModel.Month != "0") - query = query.Where(x => x.Month == searchModel.Month).OrderByDescending(x => x.WorkShopName) - .ThenByDescending(x => x.EmployerName).ThenByDescending(x => x.Year); + + + var query = notCreatedWorkshop.Select(result=>new InsuranceListViewModel + { + Year = searchModel.Year, + Month = searchModel.Month, + WorkShopId = result.id, + WorkShopCode = result.InsuranceWorkshopInfo != null + ? result.InsuranceWorkshopInfo.InsuranceCode + : string.IsNullOrWhiteSpace(result.InsuranceCode) ? "کد کارگاهی ندارد" : result.InsuranceCode, + WorkShopName = result.InsuranceWorkshopInfo != null + ? result.InsuranceWorkshopInfo.WorkshopName + : result.WorkshopFullName, + TypeOfInsuranceSend = result.TypeOfInsuranceSend == "NormalList" ? "عادی" : + result.TypeOfInsuranceSend == "Govermentlist" ? "کمک دولت" : + result.TypeOfInsuranceSend == "Familylist" ? "خانوادگی" : "", + FixedSalary = result.FixedSalary, + StrFixedSalary = result.FixedSalary ? "دارد" : "ندارد", + EmployerName = result.InsuranceWorkshopInfo != null + ? result.InsuranceWorkshopInfo.EmployerName + : result.WorkshopFullName, + Branch = "", + City = "", + ArchiveCode = result.ArchiveCode, + }); + + + if (!string.IsNullOrEmpty(searchModel.Month) && searchModel.Month != "0") + query = query.Where(x => x.Month == searchModel.Month).OrderByDescending(x => x.WorkShopName) + .ThenByDescending(x => x.EmployerName).ThenByDescending(x => x.Year); if (!string.IsNullOrEmpty(searchModel.Year) && searchModel.Year != "0") query = query.Where(x => x.Year == searchModel.Year).OrderByDescending(x => x.EmployerName) 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 }; 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/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 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 06514f9a..548018f6 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; } diff --git a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs index e3ac4b19..64586ae5 100644 --- a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs +++ b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs @@ -850,7 +850,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; 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 79603ca3..f06dadf6 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(); }