From 1e733f3f20632a2c242088044c78ba69f056c02f Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 30 Dec 2025 11:10:40 +0330 Subject: [PATCH 1/2] add: implement ChangeDeployStatusProject command and handler for updating project deployment status --- .../AutoUpdateDeployStatusCommand.cs | 2 +- .../ChangeDeployeStatusProjectComand.cs | 39 +++++++++++++++++++ .../ProjectDeployBoardListQueryHandler.cs | 2 +- .../ProjectAgg/Entities/ProjectPhase.cs | 4 +- .../_Common/IRepository.cs | 2 +- .../Persistence/_Common/RepositoryBase.cs | 4 +- .../ProgramManager/ProjectController.cs | 8 ++++ 7 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeDeployStatusProject/ChangeDeployeStatusProjectComand.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AutoUpdateDeployStatus/AutoUpdateDeployStatusCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AutoUpdateDeployStatus/AutoUpdateDeployStatusCommand.cs index 5164a0c0..66fce572 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AutoUpdateDeployStatus/AutoUpdateDeployStatusCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AutoUpdateDeployStatus/AutoUpdateDeployStatusCommand.cs @@ -25,7 +25,7 @@ public class AutoUpdateDeployStatusCommandHandler : IBaseCommandHandler ts.Task) .ThenInclude(t => t.Phase) - .Where(ts => ts.Task.Phase.DeployStatus == ProjectDeployStatus.NoTCompleted) + .Where(ts => ts.Task.Phase.DeployStatus == ProjectDeployStatus.NotCompleted) .ToListAsync(cancellationToken); if (sections.Count == 0) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeDeployStatusProject/ChangeDeployeStatusProjectComand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeDeployStatusProject/ChangeDeployeStatusProjectComand.cs new file mode 100644 index 00000000..68c336cd --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeDeployStatusProject/ChangeDeployeStatusProjectComand.cs @@ -0,0 +1,39 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeDeployStatusProject; + +public record ChangeDeployStatusProjectCommand(Guid PhaseId, ProjectDeployStatus Status):IBaseCommand; + +public class ChangeDeployStatusProjectCommandHandler : IBaseCommandHandler +{ + private readonly IProjectRepository _projectRepository; + private readonly IProjectPhaseRepository _projectPhaseRepository; + private readonly IUnitOfWork _unitOfWork; + + public ChangeDeployStatusProjectCommandHandler(IProjectRepository projectRepository, IUnitOfWork unitOfWork, IProjectPhaseRepository projectPhaseRepository) + { + _projectRepository = projectRepository; + _unitOfWork = unitOfWork; + _projectPhaseRepository = projectPhaseRepository; + } + + public async Task Handle(ChangeDeployStatusProjectCommand request, CancellationToken cancellationToken) + { + var project = await _projectPhaseRepository.GetByIdAsync(request.PhaseId, cancellationToken); + if (project == null) + return OperationResult.NotFound("بخش مورد نظر یافت نشد"); + + if (project.DeployStatus == ProjectDeployStatus.NotCompleted) + { + return OperationResult.Failure("وضعیت استقرار نمی‌تواند از حالت 'تایید نشده' تغییر کند."); + } + project.UpdateDeployStatus(request.Status); + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardList/ProjectDeployBoardListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardList/ProjectDeployBoardListQueryHandler.cs index 3cbac6e0..7ee495b4 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardList/ProjectDeployBoardListQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardList/ProjectDeployBoardListQueryHandler.cs @@ -50,7 +50,7 @@ public class ProjectDeployBoardListQueryHandler:IBaseQueryHandler x.Status == TaskSectionStatus.Completed || x.Status == TaskSectionStatus.PendingForCompletion - || x.Task.Phase.DeployStatus != ProjectDeployStatus.NoTCompleted) + || x.Task.Phase.DeployStatus != ProjectDeployStatus.NotCompleted) .GroupBy(x=>x.Task.PhaseId).ToListAsync(cancellationToken: cancellationToken); var list = query.Select(g => new ProjectDeployBoardListItem diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs index 8d7583bc..ec80aaa9 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs @@ -23,7 +23,7 @@ public class ProjectPhase : ProjectHierarchyNode ProjectId = projectId; _tasks = new List(); _phaseSections = new List(); - DeployStatus = ProjectDeployStatus.NoTCompleted; + DeployStatus = ProjectDeployStatus.NotCompleted; AddDomainEvent(new PhaseCreatedEvent(Id, projectId, name)); } @@ -216,7 +216,7 @@ public class ProjectPhase : ProjectHierarchyNode public enum ProjectDeployStatus { - NoTCompleted, + NotCompleted, PendingDevDeploy, DevDeployed, PendingDeploy, diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IRepository.cs index cd8a9dcc..053ba51b 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IRepository.cs @@ -5,7 +5,7 @@ namespace GozareshgirProgramManager.Domain._Common; public interface IRepository where T:class { T Get(TKey id); - Task GetByIdAsync(TKey id); + Task GetByIdAsync(TKey id, CancellationToken cancellationToken = default); List Get(); IQueryable GetQueryable(); void Create(T entity); diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/RepositoryBase.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/RepositoryBase.cs index def0cf17..3a016ae8 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/RepositoryBase.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/RepositoryBase.cs @@ -43,9 +43,9 @@ public class RepositoryBase : IRepository where T : class return _context.Find(id); } - public async Task GetByIdAsync(TKey id) + public async Task GetByIdAsync(TKey id, CancellationToken cancellationToken = default) { - return await _context.Set().FindAsync(id); + return await _context.Set().FindAsync([id], cancellationToken); } public List Get() diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs index a0fe2e7c..e9c5e60f 100644 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs @@ -3,6 +3,7 @@ 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.AutoUpdateDeployStatus; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeDeployStatusProject; using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection; using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; using GozareshgirProgramManager.Application.Modules.Projects.Commands.DeleteProject; @@ -138,4 +139,11 @@ public class ProjectController : ProgramManagerBaseController var res = await _mediator.Send(query); return res; } + + [HttpPost("deploy-board/change-status")] + public async Task> ChangeDeployStatus(ChangeDeployStatusProjectCommand command) + { + var res = await _mediator.Send(command); + return res; + } } \ No newline at end of file From fb5b98bf25fdfed1efe53f1ce65a4836c84cebb1 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 30 Dec 2025 11:54:56 +0330 Subject: [PATCH 2/2] add: update UpdateDeployStatus method to archive project phase upon deployment --- .../ProjectAgg/Entities/ProjectPhase.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs index ec80aaa9..3534c50f 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs @@ -211,6 +211,10 @@ public class ProjectPhase : ProjectHierarchyNode public void UpdateDeployStatus(ProjectDeployStatus status) { DeployStatus = status; + if (status == ProjectDeployStatus.Deployed) + { + IsArchived = true; + } } }