From bd12ff05067858359dec01d02de89bd022617a62 Mon Sep 17 00:00:00 2001 From: mahan Date: Mon, 19 Jan 2026 15:19:58 +0330 Subject: [PATCH 01/14] add TaskSectionTimeRequest to programmanager --- .../CreateTimeRequestCommand.cs | 43 +++++++++++++++++ .../CreateTimeRequestValidator.cs | 20 ++++++++ .../_Common/Models/OperationResult.cs | 2 +- .../Entities/TaskSectionTimeRequest.cs | 27 +++++++++++ .../Enums/TaskSectionTimeRequestType.cs | 8 ++++ .../ITaskSectionTimeRequestRepository.cs | 9 ++++ .../Exceptions/UnAuthorizedException.cs | 2 +- .../ProgramManager/TimeRequestController.cs | 47 +++++++++++++++++++ 8 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestValidator.cs create mode 100644 ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionTimeRequest.cs create mode 100644 ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionTimeRequestType.cs create mode 100644 ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionTimeRequestRepository.cs create mode 100644 ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs new file mode 100644 index 00000000..794a1442 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs @@ -0,0 +1,43 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.CreateTimeRequest; + +public record CreateTimeRequestCommand(int Hours, int Minutes, string Description, + TaskSectionTimeRequestType RequestType,Guid TaskSectionId) : IBaseCommand; + +public class CreateTimeRequestCommandHandler : IBaseCommandHandler +{ + private readonly IAuthHelper _authHelper; + private readonly ITaskSectionTimeRequestRepository _timeRequestRepository; + private readonly IUnitOfWork _unitOfWork; + + public CreateTimeRequestCommandHandler + (ITaskSectionTimeRequestRepository timeRequestRepository, IAuthHelper authHelper, IUnitOfWork unitOfWork) + { + _timeRequestRepository = timeRequestRepository; + _authHelper = authHelper; + _unitOfWork = unitOfWork; + } + + public async Task Handle(CreateTimeRequestCommand request, CancellationToken cancellationToken) + { + var currentUser = _authHelper.GetCurrentUserId(); + if (!currentUser.HasValue) + { + return OperationResult.Unauthorized(); + } + + var requestTimeSpan = TimeSpan.FromHours(request.Hours) + TimeSpan.FromMinutes(request.Minutes); + + var entity = new TaskSectionTimeRequest(currentUser.Value, request.Description, requestTimeSpan, + TaskSectionTimeRequestType.RejectedTime,); + await _timeRequestRepository.CreateAsync(entity); + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestValidator.cs new file mode 100644 index 00000000..03d65b77 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestValidator.cs @@ -0,0 +1,20 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.CreateTimeRequest; + +public class CreateTimeRequestValidator : AbstractValidator +{ + public CreateTimeRequestValidator() + { + RuleFor(c => c.Hours) + .InclusiveBetween(0, 100).WithMessage("ساعت درخواست شده باید کمتر از 100 ساعت باشد"); + + RuleFor(c => c.Minutes) + .InclusiveBetween(0, 60) + .WithMessage("دقیقه وارد شده باید بین 0 تا 60 باشد"); + + RuleFor(x => x.RequestType) + .IsInEnum() + .NotNull(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/OperationResult.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/OperationResult.cs index 324e9895..e92e0df6 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/OperationResult.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/OperationResult.cs @@ -31,7 +31,7 @@ public class OperationResult // Helper methods for specific error types public static OperationResult NotFound(string errorMessage) => new(false, errorMessage, errorType: ErrorType.NotFound); - public static OperationResult Unauthorized(string errorMessage) => new(false, errorMessage, errorType: ErrorType.Unauthorized); + public static OperationResult Unauthorized(string errorMessage="احراز هویت شما منقضی شده است. لطفا دوباره وارد شوید") => new(false, errorMessage, errorType: ErrorType.Unauthorized); public static OperationResult ValidationError(string errorMessage) => new(false, errorMessage, errorType: ErrorType.Validation); public static OperationResult ValidationError(List errors) => new(false, errors: errors, errorType: ErrorType.Validation); public static OperationResult InternalServerError(string errorMessage) => new(false, errorMessage, errorType: ErrorType.InternalServerError); diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionTimeRequest.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionTimeRequest.cs new file mode 100644 index 00000000..7ea28037 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionTimeRequest.cs @@ -0,0 +1,27 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +public class TaskSectionTimeRequest:EntityBase +{ + public TaskSectionTimeRequest(long userId, string description, + TimeSpan requestedTime, TaskSectionTimeRequestType requestType, + Guid taskSectionId) + { + UserId = userId; + Description = description; + RequestedTime = requestedTime; + RequestType = requestType; + TaskSectionId = taskSectionId; + } + + public TaskSection TaskSection { get; set; } + public Guid TaskSectionId { get; set; } + public long UserId { get; private set; } + public string Description { get; private set; } + public TimeSpan RequestedTime { get; private set; } + public TaskSectionTimeRequestType RequestType { get; private set; } + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionTimeRequestType.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionTimeRequestType.cs new file mode 100644 index 00000000..9c8007f7 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionTimeRequestType.cs @@ -0,0 +1,8 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +public enum TaskSectionTimeRequestType +{ + InitialTime, + AdditionalTime, + RejectedTime, +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionTimeRequestRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionTimeRequestRepository.cs new file mode 100644 index 00000000..9247bb9e --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionTimeRequestRepository.cs @@ -0,0 +1,9 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +public interface ITaskSectionTimeRequestRepository:IRepository +{ + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/UnAuthorizedException.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/UnAuthorizedException.cs index 67f0befb..f470b20c 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/UnAuthorizedException.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/UnAuthorizedException.cs @@ -2,7 +2,7 @@ public class UnAuthorizedException:Exception { - public UnAuthorizedException(string message) : base(message) + public UnAuthorizedException(string message="احراز هویت شما منقضی شده است. لطفا دوباره وارد شوید") : base(message) { } } \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs new file mode 100644 index 00000000..3e577b13 --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs @@ -0,0 +1,47 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.CreateTimeRequest; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class TimeRequestController:ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + public TimeRequestController(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("Rejected")] + public async Task> CreateRejectedTimeRequest(CreateRejectedTimeRequest request) + { + var command = new CreateTimeRequestCommand(request.Hours, request.Minutes, request.Description, + TaskSectionTimeRequestType.RejectedTime); + var res = await _mediator.Send(command); + return res; + } + + [HttpPost("Initial")] + public async Task> CreateInitialTimeRequest(CreateRejectedTimeRequest request) + { + var command = new CreateTimeRequestCommand(request.Hours, request.Minutes, request.Description, + TaskSectionTimeRequestType.InitialTime); + var res = await _mediator.Send(command); + return res; + } + + [HttpPost("Additional")] + public async Task> CreateAdditionalTimeRequest(CreateRejectedTimeRequest request) + { + var command = new CreateTimeRequestCommand(request.Hours, request.Minutes, request.Description, + TaskSectionTimeRequestType.AdditionalTime); + var res = await _mediator.Send(command); + return res; + } +} + +public record CreateRejectedTimeRequest(int Hours, int Minutes, string Description); \ No newline at end of file From 4bde4ade2da836a9568dec3f290c72367bdf1a59 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 20 Jan 2026 11:01:58 +0330 Subject: [PATCH 02/14] add time request status --- .../SalaryAidAgg/ISalaryAidRepository.cs | 3 +-- .../CreateTimeRequest/CreateTimeRequestCommand.cs | 2 +- .../ProjectAgg/Entities/TaskSectionTimeRequest.cs | 4 +++- .../Enums/TaskSectionTimeRequestStatus.cs | 8 ++++++++ .../ProgramManager/TimeRequestController.cs | 15 ++++++++------- 5 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionTimeRequestStatus.cs diff --git a/Company.Domain/SalaryAidAgg/ISalaryAidRepository.cs b/Company.Domain/SalaryAidAgg/ISalaryAidRepository.cs index 4acc1cec..c1a7cf87 100644 --- a/Company.Domain/SalaryAidAgg/ISalaryAidRepository.cs +++ b/Company.Domain/SalaryAidAgg/ISalaryAidRepository.cs @@ -15,12 +15,11 @@ public interface ISalaryAidRepository:IRepository void RemoveRange(IEnumerable salaryAids); #region Pooya - /// /// گروهبندی بر اساس ماه هنگام جستجو با انتخاب کارمند /// - SalaryAidsGroupedViewModel GetSearchListAsGrouped(SalaryAidSearchViewModel searchModel); + SalaryAidsGroupedViewModel GetSearchListAsGrouped(SalaryAidSearchViewModel searchModel); #endregion } \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs index 794a1442..465df578 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs @@ -35,7 +35,7 @@ public class CreateTimeRequestCommandHandler : IBaseCommandHandler { + public TaskSectionTimeRequest(long userId, string description, TimeSpan requestedTime, TaskSectionTimeRequestType requestType, Guid taskSectionId) @@ -14,6 +15,7 @@ public class TaskSectionTimeRequest:EntityBase RequestedTime = requestedTime; RequestType = requestType; TaskSectionId = taskSectionId; + RequestStatus = TaskSectionTimeRequestStatus.Pending; } public TaskSection TaskSection { get; set; } @@ -22,6 +24,6 @@ public class TaskSectionTimeRequest:EntityBase public string Description { get; private set; } public TimeSpan RequestedTime { get; private set; } public TaskSectionTimeRequestType RequestType { get; private set; } - + public TaskSectionTimeRequestStatus RequestStatus { get; private set; } } \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionTimeRequestStatus.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionTimeRequestStatus.cs new file mode 100644 index 00000000..6300b35e --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionTimeRequestStatus.cs @@ -0,0 +1,8 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +public enum TaskSectionTimeRequestStatus +{ + Pending, + Accepted, + Rejected +} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs index 3e577b13..0c959e6a 100644 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs @@ -1,3 +1,4 @@ +using System.Runtime.InteropServices; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.CreateTimeRequest; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; @@ -17,31 +18,31 @@ public class TimeRequestController:ProgramManagerBaseController } [HttpPost("Rejected")] - public async Task> CreateRejectedTimeRequest(CreateRejectedTimeRequest request) + public async Task> CreateRejectedTimeRequest(CreateTimeRequest request) { var command = new CreateTimeRequestCommand(request.Hours, request.Minutes, request.Description, - TaskSectionTimeRequestType.RejectedTime); + TaskSectionTimeRequestType.RejectedTime,request.TaskSectionId); var res = await _mediator.Send(command); return res; } [HttpPost("Initial")] - public async Task> CreateInitialTimeRequest(CreateRejectedTimeRequest request) + public async Task> CreateInitialTimeRequest(CreateTimeRequest request) { var command = new CreateTimeRequestCommand(request.Hours, request.Minutes, request.Description, - TaskSectionTimeRequestType.InitialTime); + TaskSectionTimeRequestType.InitialTime,request.TaskSectionId); var res = await _mediator.Send(command); return res; } [HttpPost("Additional")] - public async Task> CreateAdditionalTimeRequest(CreateRejectedTimeRequest request) + public async Task> CreateAdditionalTimeRequest(CreateTimeRequest request) { var command = new CreateTimeRequestCommand(request.Hours, request.Minutes, request.Description, - TaskSectionTimeRequestType.AdditionalTime); + TaskSectionTimeRequestType.AdditionalTime,request.TaskSectionId); var res = await _mediator.Send(command); return res; } } -public record CreateRejectedTimeRequest(int Hours, int Minutes, string Description); \ No newline at end of file +public record CreateTimeRequest(int Hours, int Minutes, string Description,Guid TaskSectionId); \ No newline at end of file From d4694e7e1c1f6d94cda70393f875448e56389702 Mon Sep 17 00:00:00 2001 From: mahan Date: Tue, 20 Jan 2026 14:22:09 +0330 Subject: [PATCH 03/14] add Accept time request command --- .../SetTimeProject/SetTimeProjectCommand.cs | 2 ++ .../SetTimeProjectCommandHandler.cs | 2 +- .../AcceptTimeRequestCommand.cs | 29 +++++++++++++++++++ .../CreateTimeRequestValidator.cs | 2 +- .../ProjectAgg/Entities/TaskSection.cs | 5 ++-- .../Entities/TaskSectionAdditionalTime.cs | 12 ++++++-- 6 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs index b7ed7859..a27d2c20 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application.Modules.Projects.DTOs; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; @@ -15,4 +16,5 @@ public class SetTimeSectionTime public string Description { get; set; } public int Hours { get; set; } public int Minutes { get; set; } + public TaskSectionAdditionalTimeType Type { get; set; } } \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs index a9ca3a61..9afa83d4 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs @@ -369,7 +369,7 @@ public class SetTimeProjectCommandHandler : IBaseCommandHandler +{ + public AcceptTimeRequestCommandValidator() + { + RuleFor(c => c.TimeRequestId) + .NotEmpty().WithMessage("شناسه درخواست نمیتواند خالی باشد"); + + RuleFor(c => c.SectionId) + .NotEmpty().WithMessage("شناسه بخش فرعی نمیتواند خالی باشد"); + + RuleFor(c => c.TimeType) + .NotNull().WithMessage("نوع زمان درخواست شده نامعتبر است") + .IsInEnum(); + + RuleFor(c => c.Hour) + .InclusiveBetween(0, 100).WithMessage("ساعت وارد شده میتواند بین 0 تا 100 باشد"); + RuleFor(c => c.Minute) + .InclusiveBetween(0, 60).WithMessage("دقیقه وارد شده میتواند بین 0 تا 60 باشد"); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestValidator.cs index 03d65b77..82484ad0 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestValidator.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestValidator.cs @@ -10,7 +10,7 @@ public class CreateTimeRequestValidator : AbstractValidator c.Minutes) - .InclusiveBetween(0, 60) + .InclusiveBetween(0, 59) .WithMessage("دقیقه وارد شده باید بین 0 تا 60 باشد"); RuleFor(x => x.RequestType) diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs index 83b86c23..3bb41ee6 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs @@ -61,12 +61,13 @@ public class TaskSection : EntityBase // برای backward compatibility public TimeSpan EstimatedHours => FinalEstimatedHours; - public void AddAdditionalTime(TimeSpan additionalHours, string? reason = null, long? addedByUserId = null) + public void AddAdditionalTime(TimeSpan additionalHours, TaskSectionAdditionalTimeType type, string? reason = null, + long? addedByUserId = null) { if (additionalHours <= TimeSpan.Zero) throw new BadRequestException("تایم اضافی باید بزرگتر از صفر باشد", nameof(additionalHours)); - var additionalTime = new TaskSectionAdditionalTime(additionalHours, reason, addedByUserId); + var additionalTime = new TaskSectionAdditionalTime(additionalHours,type, reason, addedByUserId); _additionalTimes.Add(additionalTime); } diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs index 657f76cc..d8f54456 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs @@ -9,12 +9,13 @@ public class TaskSectionAdditionalTime : EntityBase { private TaskSectionAdditionalTime() { } - public TaskSectionAdditionalTime(TimeSpan hours, string? reason = null, long? addedByUserId = null) + public TaskSectionAdditionalTime(TimeSpan hours, TaskSectionAdditionalTimeType type, string? reason = null,long? addedByUserId = null) { Hours = hours; Reason = reason; AddedByUserId = addedByUserId; - AddedAt = DateTime.UtcNow; + AddedAt = DateTime.Now; + Type = type; } public TimeSpan Hours { get; private set; } @@ -22,8 +23,15 @@ public class TaskSectionAdditionalTime : EntityBase public long? AddedByUserId { get; private set; } public DateTime AddedAt { get; private set; } + public TaskSectionAdditionalTimeType Type { get; set; } public void UpdateReason(string? reason) { Reason = reason; } } + +public enum TaskSectionAdditionalTimeType +{ + Effective, + Ineffective, +} From 88f54b631001837dee79abf5de967c2f65b1ac2d Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 21 Jan 2026 10:28:38 +0330 Subject: [PATCH 04/14] add acceptTimeRequestCommandHandler- NotFinished --- .../AcceptTimeRequestCommand.cs | 40 ++++++++++++------- .../AcceptTimeRequestCommandValidator.cs | 24 +++++++++++ 2 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommandValidator.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs index 6ab14477..c9b7d130 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs @@ -1,29 +1,41 @@ -using FluentValidation; using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; namespace GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.AcceptTimeRequest; public record AcceptTimeRequestCommand(Guid TimeRequestId, Guid SectionId,TaskSectionAdditionalTimeType TimeType,int Hour,int Minute):IBaseCommand; -public class AcceptTimeRequestCommandValidator : AbstractValidator +public class AcceptTimeRequestCommandHandler:IBaseCommandHandler { - public AcceptTimeRequestCommandValidator() + private readonly ITaskSectionTimeRequestRepository _timeRequestRepository; + private readonly ITaskSectionRepository _taskSectionRepository; + public AcceptTimeRequestCommandHandler(ITaskSectionTimeRequestRepository timeRequestRepository, ITaskSectionRepository taskSectionRepository) { - RuleFor(c => c.TimeRequestId) - .NotEmpty().WithMessage("شناسه درخواست نمیتواند خالی باشد"); + _timeRequestRepository = timeRequestRepository; + _taskSectionRepository = taskSectionRepository; + } - RuleFor(c => c.SectionId) - .NotEmpty().WithMessage("شناسه بخش فرعی نمیتواند خالی باشد"); + public async Task Handle(AcceptTimeRequestCommand request, CancellationToken cancellationToken) + { + var timeRequest = await _timeRequestRepository.GetByIdAsync(request.TimeRequestId, cancellationToken); + if (timeRequest == null) + { + return OperationResult.NotFound("درخواست زمان شما یافت نشد"); + } - RuleFor(c => c.TimeType) - .NotNull().WithMessage("نوع زمان درخواست شده نامعتبر است") - .IsInEnum(); + var taskSection = await _taskSectionRepository.GetByIdAsync(request.SectionId, cancellationToken); - RuleFor(c => c.Hour) - .InclusiveBetween(0, 100).WithMessage("ساعت وارد شده میتواند بین 0 تا 100 باشد"); - RuleFor(c => c.Minute) - .InclusiveBetween(0, 60).WithMessage("دقیقه وارد شده میتواند بین 0 تا 60 باشد"); + if (taskSection == null) + { + return OperationResult.NotFound("بخش فرعی وارد شده نامعتبر است"); + } + + if (timeRequest.RequestType.) + { + + } } } \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommandValidator.cs new file mode 100644 index 00000000..7d199891 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommandValidator.cs @@ -0,0 +1,24 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.AcceptTimeRequest; + +public class AcceptTimeRequestCommandValidator : AbstractValidator +{ + public AcceptTimeRequestCommandValidator() + { + RuleFor(c => c.TimeRequestId) + .NotEmpty().WithMessage("شناسه درخواست نمیتواند خالی باشد"); + + RuleFor(c => c.SectionId) + .NotEmpty().WithMessage("شناسه بخش فرعی نمیتواند خالی باشد"); + + RuleFor(c => c.TimeType) + .NotNull().WithMessage("نوع زمان درخواست شده نامعتبر است") + .IsInEnum(); + + RuleFor(c => c.Hour) + .InclusiveBetween(0, 100).WithMessage("ساعت وارد شده میتواند بین 0 تا 100 باشد"); + RuleFor(c => c.Minute) + .InclusiveBetween(0, 60).WithMessage("دقیقه وارد شده میتواند بین 0 تا 60 باشد"); + } +} \ No newline at end of file From 0e5a0a16ac2b554ab0547c98eface9550f348887 Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 21 Jan 2026 14:12:06 +0330 Subject: [PATCH 05/14] add task section revision and folderize the project domain --- .../AssignProjectCommandHandler.cs | 3 +++ .../AutoUpdateDeployStatusCommand.cs | 1 + .../ChangeDeployeStatusProjectComand.cs | 1 + .../ChangeTaskPriorityCommand.cs | 8 ++++--- .../CreateProjectCommandHandler.cs | 3 +++ ...reateProjectWithHierarchyCommandHandler.cs | 1 + .../SetTimeProject/SetTimeProjectCommand.cs | 1 + .../SetTimeProjectCommandHandler.cs | 3 +++ .../Extensions/ProjectMappingExtensions.cs | 4 ++++ .../GetProjectsListQueryHandler.cs | 4 ++++ .../ProjectDeployBoardListQueryHandler.cs | 1 + .../Queries/GetMessages/GetMessagesQuery.cs | 3 ++- .../AcceptTimeRequestCommand.cs | 10 +++++---- .../CreateTimeRequestCommand.cs | 1 + .../Interfaces/IProgramManagerDbContext.cs | 4 ++++ .../Entities/{ => Phase}/PhaseSection.cs | 2 +- .../Entities/{ => Phase}/ProjectPhase.cs | 7 +++--- .../Entities/{ => Project}/Project.cs | 4 ++-- .../Entities/{ => Project}/ProjectSection.cs | 2 +- .../Entities/{ => Task}/ProjectTask.cs | 22 +++++++++---------- .../{ => Task/TaskSection}/TaskSection.cs | 6 ++--- .../TaskSection}/TaskSectionActivity.cs | 3 +-- .../TaskSection}/TaskSectionAdditionalTime.cs | 2 +- .../Task/TaskSection/TaskSectionRevision.cs | 14 ++++++++++++ .../TaskSection}/TaskSectionTimeRequest.cs | 2 +- .../Repositories/IPhaseSectionRepository.cs | 2 ++ .../Repositories/IProjectPhaseRepository.cs | 1 + .../Repositories/IProjectRepository.cs | 1 + .../Repositories/IProjectSectionRepository.cs | 1 + .../Repositories/IProjectTaskRepository.cs | 1 + .../ITaskSectionActivityRepository.cs | 1 + .../Repositories/ITaskSectionRepository.cs | 1 + .../ITaskSectionTimeRequestRepository.cs | 1 + .../SkillAgg/Entities/Skill.cs | 1 + .../Context/ProgramManagerDbContext.cs | 4 ++++ .../Mappings/AdditionalTimeMapping.cs | 1 + .../Mappings/PhaseSectionMapping.cs | 1 + .../Persistence/Mappings/ProjectMapping.cs | 1 + .../Mappings/ProjectPhaseMapping.cs | 1 + .../Mappings/ProjectSectionMapping.cs | 1 + .../Mappings/ProjectTaskMapping.cs | 1 + .../Mappings/TaskSectionActivityMapping.cs | 1 + .../TaskSectionAdditionalTimeMapping.cs | 1 + .../Mappings/TaskSectionMapping.cs | 1 + .../Repositories/PhaseSectionRepository.cs | 1 + .../Repositories/ProjectPhaseRepository.cs | 1 + .../Repositories/ProjectRepository.cs | 1 + .../Repositories/ProjectSectionRepository.cs | 1 + .../Repositories/ProjectTaskRepository.cs | 1 + .../TaskSectionActivityRepository.cs | 1 + .../Repositories/TaskSectionRepository.cs | 1 + .../WorkFlowApplication.cs | 11 +++++----- 52 files changed, 114 insertions(+), 39 deletions(-) rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Phase}/PhaseSection.cs (93%) rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Phase}/ProjectPhase.cs (95%) rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Project}/Project.cs (97%) rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Project}/ProjectSection.cs (92%) rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Task}/ProjectTask.cs (89%) rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Task/TaskSection}/TaskSection.cs (98%) rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Task/TaskSection}/TaskSectionActivity.cs (95%) rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Task/TaskSection}/TaskSectionAdditionalTime.cs (92%) create mode 100644 ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs rename ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/{ => Task/TaskSection}/TaskSectionTimeRequest.cs (92%) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandHandler.cs index 7dddf33e..4dc48a24 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandHandler.cs @@ -2,6 +2,9 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Domain.SkillAgg.Repositories; 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 66fce572..b12dbd47 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 @@ -2,6 +2,7 @@ using System.Linq; using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; 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 index 06c75b4a..fc3f46d4 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeDeployStatusProject/ChangeDeployeStatusProjectComand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeDeployStatusProject/ChangeDeployeStatusProjectComand.cs @@ -2,6 +2,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeDeployStatusProject; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeTaskPriority/ChangeTaskPriorityCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeTaskPriority/ChangeTaskPriorityCommand.cs index d6ea7e1e..d7640e4c 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeTaskPriority/ChangeTaskPriorityCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeTaskPriority/ChangeTaskPriorityCommand.cs @@ -1,6 +1,8 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; @@ -69,7 +71,7 @@ public class ChangeTaskPriorityCommandHandler : IBaseCommandHandler(); + var tasks = phase.Tasks?.ToList() ?? new List(); foreach (var t in tasks) { if (t.Priority != priority) @@ -89,10 +91,10 @@ public class ChangeTaskPriorityCommandHandler : IBaseCommandHandler(); + var phases = project.Phases?.ToList() ?? new List(); foreach (var phase in phases) { - var tasks = phase.Tasks?.ToList() ?? new List(); + var tasks = phase.Tasks?.ToList() ?? new List(); foreach (var t in tasks) { if (t.Priority != priority) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandHandler.cs index 1ba61509..82b4668a 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandHandler.cs @@ -3,6 +3,9 @@ using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain._Common.Exceptions; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandHandler.cs index 0a899924..9493a83a 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandHandler.cs @@ -2,6 +2,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using MediatR; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs index a27d2c20..5ec6445e 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs @@ -1,6 +1,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application.Modules.Projects.DTOs; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs index 9afa83d4..d303c8a2 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs @@ -4,6 +4,9 @@ using GozareshgirProgramManager.Application.Modules.Projects.DTOs; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain._Common.Exceptions; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Domain.SkillAgg.Repositories; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Extensions/ProjectMappingExtensions.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Extensions/ProjectMappingExtensions.cs index 2c689cad..02c1e65d 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Extensions/ProjectMappingExtensions.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Extensions/ProjectMappingExtensions.cs @@ -1,5 +1,9 @@ using GozareshgirProgramManager.Application.Modules.Projects.DTOs; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; namespace GozareshgirProgramManager.Application.Modules.Projects.Extensions; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs index a982caf3..d852a9e2 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs @@ -4,6 +4,10 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; using System.Linq; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; 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 d8f6e39d..016e4de6 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 @@ -3,6 +3,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskChat/Queries/GetMessages/GetMessagesQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskChat/Queries/GetMessages/GetMessagesQuery.cs index 13778341..057bf123 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskChat/Queries/GetMessages/GetMessagesQuery.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskChat/Queries/GetMessages/GetMessagesQuery.cs @@ -1,6 +1,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application.Modules.TaskChat.DTOs; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.TaskChatAgg.Enums; using MediatR; using Microsoft.EntityFrameworkCore; @@ -28,7 +29,7 @@ public class GetMessagesQueryHandler : IBaseQueryHandler CreateAdditionalTimeNotes( - IEnumerable additionalTimes, + IEnumerable additionalTimes, Dictionary users, Guid taskId) { diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs index c9b7d130..fd162ae6 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs @@ -1,6 +1,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; namespace GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.AcceptTimeRequest; @@ -33,9 +34,10 @@ public class AcceptTimeRequestCommandHandler:IBaseCommandHandler /// بخش فاز - برای ذخیره تخصیص کاربر و مهارت در سطح Phase diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Phase/ProjectPhase.cs similarity index 95% rename from ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs rename to ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Phase/ProjectPhase.cs index 60b98df9..f8f2d45b 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Phase/ProjectPhase.cs @@ -1,8 +1,9 @@ -using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Events; -namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; /// /// فاز پروژه - سطح میانی در سلسله مراتب @@ -28,7 +29,7 @@ public class ProjectPhase : ProjectHierarchyNode } public Guid ProjectId { get; private set; } - public Project Project { get; private set; } = null!; + public Project.Project Project { get; private set; } = null!; public IReadOnlyList Tasks => _tasks.AsReadOnly(); public IReadOnlyList PhaseSections => _phaseSections.AsReadOnly(); diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project/Project.cs similarity index 97% rename from ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project.cs rename to ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project/Project.cs index 8e8e2b31..f1ed9816 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project/Project.cs @@ -1,8 +1,8 @@ -using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Events; -namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; /// /// پروژه - بالاترین سطح در سلسله مراتب و Aggregate Root diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectSection.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project/ProjectSection.cs similarity index 92% rename from ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectSection.cs rename to ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project/ProjectSection.cs index d41c5eb0..b6d10943 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectSection.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project/ProjectSection.cs @@ -1,7 +1,7 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.SkillAgg.Entities; -namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; /// /// ProjectSection: shortcut container for UserId + SkillId at Project level diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectTask.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/ProjectTask.cs similarity index 89% rename from ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectTask.cs rename to ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/ProjectTask.cs index 8c11e2a0..6323869a 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectTask.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/ProjectTask.cs @@ -1,32 +1,32 @@ -using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Events; -namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; /// /// تسک - پایین‌ترین سطح در سلسله مراتب که شامل بخش‌ها می‌شود /// public class ProjectTask : ProjectHierarchyNode { - private readonly List _sections; + private readonly List _sections; private ProjectTask() { - _sections = new List(); + _sections = new List(); } public ProjectTask(string name, Guid phaseId, string? description = null) : base(name, description) { PhaseId = phaseId; - _sections = new List(); + _sections = new List(); Priority = ProjectTaskPriority.Low; AddDomainEvent(new TaskCreatedEvent(Id, phaseId, name)); } public Guid PhaseId { get; private set; } public ProjectPhase Phase { get; private set; } = null!; - public IReadOnlyList Sections => _sections.AsReadOnly(); + public IReadOnlyList Sections => _sections.AsReadOnly(); // Task-specific properties public Enums.TaskStatus Status { get; private set; } = Enums.TaskStatus.NotStarted; @@ -40,7 +40,7 @@ public class ProjectTask : ProjectHierarchyNode #region Section Management - public void AddSection(TaskSection section, bool cascadeToChildren = false) + public void AddSection(TaskSection.TaskSection section, bool cascadeToChildren = false) { var existingSection = _sections.FirstOrDefault(s => s.SkillId == section.SkillId); if (existingSection != null) @@ -84,7 +84,7 @@ public class ProjectTask : ProjectHierarchyNode return; } - var section = new TaskSection(Id, skillId, assignedUserId); + var section = new TaskSection.TaskSection(Id, skillId, assignedUserId); _sections.Add(section); AddDomainEvent(new TaskSectionAddedEvent(Id, section.Id, skillId)); } @@ -204,12 +204,12 @@ public class ProjectTask : ProjectHierarchyNode #region Query Helpers - public IEnumerable GetSectionsBySkill(Guid skillId) + public IEnumerable GetSectionsBySkill(Guid skillId) { return _sections.Where(s => s.SkillId == skillId); } - public TaskSection? GetSectionBySkill(Guid skillId) + public TaskSection.TaskSection? GetSectionBySkill(Guid skillId) { return _sections.FirstOrDefault(s => s.SkillId == skillId); } @@ -219,7 +219,7 @@ public class ProjectTask : ProjectHierarchyNode return _sections.Any(s => s.SkillId == skillId); } - public IEnumerable GetAssignedSections(long userId) + public IEnumerable GetAssignedSections(long userId) { return _sections.Where(s => s.CurrentAssignedUserId == userId); } diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSection.cs similarity index 98% rename from ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs rename to ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSection.cs index 3bb41ee6..3c1543ba 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSection.cs @@ -1,12 +1,10 @@ -using System.Linq; -using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain._Common.Exceptions; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Events; -using GozareshgirProgramManager.Domain.ProjectAgg.Models; using GozareshgirProgramManager.Domain.SkillAgg.Entities; -namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; /// /// بخش تسک - برای ذخیره کار واقعی که کاربر روی یک مهارت خاص انجام می‌دهد diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionActivity.cs similarity index 95% rename from ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs rename to ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionActivity.cs index 04b3a7e3..a1cea634 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionActivity.cs @@ -1,7 +1,6 @@ -using System.Diagnostics.CodeAnalysis; using GozareshgirProgramManager.Domain._Common; -namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; /// /// فعالیت کاری روی یک بخش diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionAdditionalTime.cs similarity index 92% rename from ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs rename to ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionAdditionalTime.cs index d8f54456..4a98c45c 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionAdditionalTime.cs @@ -1,6 +1,6 @@ using GozareshgirProgramManager.Domain._Common; -namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; /// /// زمان اضافی اضافه شده بعد از تخمین اولیه diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs new file mode 100644 index 00000000..6dfa7c12 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs @@ -0,0 +1,14 @@ +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; + +public class TaskSectionRevision:EntityBase +{ + public Guid TaskSectionId { get; private set; } + + public TaskSectionRevisionStatus Status { get; private set; } + public string Message { get; private set; } + + public Guid CreatedByUserId { get; private set; } + public DateTime CreatedAt { get; private set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionTimeRequest.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionTimeRequest.cs similarity index 92% rename from ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionTimeRequest.cs rename to ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionTimeRequest.cs index a4423fec..00358963 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionTimeRequest.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionTimeRequest.cs @@ -1,7 +1,7 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; -namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; public class TaskSectionTimeRequest:EntityBase { diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IPhaseSectionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IPhaseSectionRepository.cs index db8fb7e1..1ec69b1a 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IPhaseSectionRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IPhaseSectionRepository.cs @@ -1,5 +1,7 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; + namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; public interface IPhaseSectionRepository : IRepository { diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectPhaseRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectPhaseRepository.cs index 8a29e014..059a8fc7 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectPhaseRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectPhaseRepository.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectRepository.cs index 5514e492..013ce727 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectRepository.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectSectionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectSectionRepository.cs index 2838c8d6..6f87295b 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectSectionRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectSectionRepository.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectTaskRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectTaskRepository.cs index 9894a764..5aada92c 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectTaskRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectTaskRepository.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionActivityRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionActivityRepository.cs index 55eff1be..0c0a1179 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionActivityRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionActivityRepository.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs index 50e1a2b0..b194f804 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs @@ -1,6 +1,7 @@ using System.Collections; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionTimeRequestRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionTimeRequestRepository.cs index 9247bb9e..913221ac 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionTimeRequestRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionTimeRequestRepository.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Entities/Skill.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Entities/Skill.cs index 662f9544..0254b23e 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Entities/Skill.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Entities/Skill.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; namespace GozareshgirProgramManager.Domain.SkillAgg.Entities; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs index 01979e6f..d2cce1ae 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs @@ -5,6 +5,10 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Domain.CustomerAgg; using GozareshgirProgramManager.Domain.FileManagementAgg.Entities; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.RoleAgg.Entities; using GozareshgirProgramManager.Domain.RoleUserAgg; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/AdditionalTimeMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/AdditionalTimeMapping.cs index 6c73bc87..9dc11054 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/AdditionalTimeMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/AdditionalTimeMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Infrastructure.Persistence._Common; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/PhaseSectionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/PhaseSectionMapping.cs index 1b4a829f..18dc0a21 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/PhaseSectionMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/PhaseSectionMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectMapping.cs index 69a79750..ad127eff 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs index 01a43077..b499f798 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectSectionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectSectionMapping.cs index 454ab86d..fb50461b 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectSectionMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectSectionMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectTaskMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectTaskMapping.cs index 705af3d6..3bb5b916 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectTaskMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectTaskMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Infrastructure.Persistence._Common; using Microsoft.EntityFrameworkCore; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionActivityMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionActivityMapping.cs index 84f4227e..73356cbc 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionActivityMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionActivityMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs index e6789d94..6629b740 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Infrastructure.Persistence._Common; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionMapping.cs index 836580f0..ed6acc81 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionMapping.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Infrastructure.Persistence._Common; using Microsoft.EntityFrameworkCore; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/PhaseSectionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/PhaseSectionRepository.cs index c582dffd..b3cb95dd 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/PhaseSectionRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/PhaseSectionRepository.cs @@ -1,6 +1,7 @@ using GozareshgirProgramManager.Infrastructure.Persistence._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using GozareshgirProgramManager.Infrastructure.Persistence.Context; namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectPhaseRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectPhaseRepository.cs index f00d4512..65f93b9b 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectPhaseRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectPhaseRepository.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence._Common; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectRepository.cs index 21afca93..08a47ba4 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectRepository.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence._Common; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectSectionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectSectionRepository.cs index d2b115db..d1c9626e 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectSectionRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectSectionRepository.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence._Common; using GozareshgirProgramManager.Infrastructure.Persistence.Context; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectTaskRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectTaskRepository.cs index cbaa79fe..a56d8fbe 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectTaskRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectTaskRepository.cs @@ -1,4 +1,5 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence._Common; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionActivityRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionActivityRepository.cs index 4ae98bf7..c3ccfc05 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionActivityRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionActivityRepository.cs @@ -1,6 +1,7 @@ using GozareshgirProgramManager.Application.Modules.Projects.DTOs; using GozareshgirProgramManager.Application.Modules.Projects.Extensions; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence._Common; using GozareshgirProgramManager.Infrastructure.Persistence.Context; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs index ce590dc7..d43a74c2 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.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence._Common; diff --git a/WorkFlow/Application/WorkFlow.Application/WorkFlowApplication.cs b/WorkFlow/Application/WorkFlow.Application/WorkFlowApplication.cs index d644bb5f..f884e41f 100644 --- a/WorkFlow/Application/WorkFlow.Application/WorkFlowApplication.cs +++ b/WorkFlow/Application/WorkFlow.Application/WorkFlowApplication.cs @@ -87,9 +87,7 @@ public class WorkFlowApplication : IWorkFlowApplication { return (await GetRollCallWorkFlowsCutByBgService(workshopId)).Count; } - - - + public async Task GetAllWorkFlowCount(long workshopId, long accountId) { var count = 0; @@ -434,7 +432,7 @@ public class WorkFlowApplication : IWorkFlowApplication var lastCheckouts = _checkoutACL.GetLastCheckoutsByWorkshopIdForWorkFlow(workshopId, twoMonthsAgo, now); List rollCalls = _rollCallACL.GetUndefinedRollCalls(workshopId, twoMonthsAgo, now.AddDays(-1).Date); var activeEmployees = _rollCallACL.GetActiveWorkshopRollCallEmployees(workshopId, twoMonthsAgo, now); - return rollCalls.Select(x => new DailyRollCallWorkFlowViewModel() + var res= rollCalls.Select(x => new DailyRollCallWorkFlowViewModel() { DateTime = x.DateTime, DateTimeFa = x.DateTimeFa, @@ -447,6 +445,8 @@ public class WorkFlowApplication : IWorkFlowApplication .ToList(), DayOfWeekFa = x.DateTime.DayOfWeek.DayOfWeeKToPersian() }).Where(y => y.RollCallWorkFlowPerDayViewModels != null && y.RollCallWorkFlowPerDayViewModels.Any()).OrderBy(x => x.DateTime).ToList(); + + return res; } /// @@ -757,7 +757,7 @@ public class WorkFlowApplication : IWorkFlowApplication var entites = _rollCallConfirmedWithoutLunchBreakRepository.GetByWorkshopId(workshopId, twoMonthsAgo, now).ToList(); - return employeeWithoutBreakTimeAndNotSliced.Where(x => !entites.Any(y => y.RollCallId == x.RollCallId)) + var res = employeeWithoutBreakTimeAndNotSliced.Where(x => !entites.Any(y => y.RollCallId == x.RollCallId)) .GroupBy(x => x.RollCallDate.Date).OrderBy(x => x.Key).Select(x => new DailyRollCallConfirmedWithoutLunchBreakViewModel { DateGr = x.Key.Date, @@ -770,6 +770,7 @@ public class WorkFlowApplication : IWorkFlowApplication RollCallId = y.RollCallId, }).ToList() }).ToList(); + return res; } From 4c143d6bbc369b246f76ffda4c6c67160e4e1d9a Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 21 Jan 2026 18:05:14 +0330 Subject: [PATCH 06/14] add task section revision command --- ...zareshgirProgramManager.Application.csproj | 4 + .../CreateTaskSectionRevisionCommand.cs | 134 ++++++++++++++++++ .../FileManagementAgg/Enums/FileCategory.cs | 3 +- .../Task/TaskSection/TaskSectionRevision.cs | 43 +++++- .../ITaskSectionRevisionRepository.cs | 9 ++ .../DependencyInjection.cs | 5 + .../TaskChatMessageRepository.cs | 0 .../TaskSectionRevisionRepository.cs | 16 +++ .../TaskSectionTimeRequestRepository.cs | 16 +++ .../UploadedFileRepository.cs | 0 .../TaskSectionRevisionController.cs | 23 +++ 11 files changed, 248 insertions(+), 5 deletions(-) create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs create mode 100644 ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRevisionRepository.cs rename ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/{TaskChat => }/TaskChatMessageRepository.cs (100%) create mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRevisionRepository.cs create mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionTimeRequestRepository.cs rename ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/{FileManagement => }/UploadedFileRepository.cs (100%) create mode 100644 ServiceHost/Areas/Admin/Controllers/ProgramManager/TaskSectionRevisionController.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj index d28d7b48..cc16cc3a 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj @@ -25,4 +25,8 @@ + + + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs new file mode 100644 index 00000000..d524694e --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs @@ -0,0 +1,134 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.TaskChat.DTOs; +using GozareshgirProgramManager.Application.Services.FileManagement; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.FileManagementAgg.Entities; +using GozareshgirProgramManager.Domain.FileManagementAgg.Enums; +using GozareshgirProgramManager.Domain.FileManagementAgg.Repositories; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using Microsoft.AspNetCore.Http; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateTaskSectionRevision; + +public record CreateTaskSectionRevisionCommand(string Message, List Files, Guid SectionId) : IBaseCommand; + +public class CreateTaskSectionRevisionCommandHandler : IBaseCommandHandler +{ + private readonly ITaskSectionRevisionRepository _revisionRepository; + private readonly IFileStorageService _fileStorageService; + private readonly IAuthHelper _authHelper; + private readonly IUnitOfWork _unitOfWork; + private readonly IUploadedFileRepository _fileRepository; + private readonly IThumbnailGeneratorService _thumbnailService; + + public CreateTaskSectionRevisionCommandHandler(ITaskSectionRevisionRepository revisionRepository, + IFileStorageService fileStorageService, IAuthHelper authHelper, IUnitOfWork unitOfWork, IUploadedFileRepository fileRepository, IThumbnailGeneratorService thumbnailService) + { + _revisionRepository = revisionRepository; + _fileStorageService = fileStorageService; + _authHelper = authHelper; + _unitOfWork = unitOfWork; + _fileRepository = fileRepository; + _thumbnailService = thumbnailService; + } + + public async Task Handle(CreateTaskSectionRevisionCommand request, + CancellationToken cancellationToken) + { + var currentId = _authHelper.GetCurrentUserId(); + + var entity = new TaskSectionRevision(request.SectionId, request.Message, currentId!.Value); + + foreach (var file in request.Files) + { + if (file.Length == 0) + { + return OperationResult.ValidationError("فایل خالی است"); + } + + const long maxFileSize = 100 * 1024 * 1024; + if (file.Length > maxFileSize) + { + return OperationResult.ValidationError("حجم فایل بیش از حد مجاز است (حداکثر 100MB)"); + } + + var fileType = DetectFileType(file.ContentType, Path.GetExtension(file.FileName)); + + var uploadedFile = new UploadedFile( + originalFileName: file.FileName, + fileSizeBytes: file.Length, + mimeType: file.ContentType, + fileType: fileType, + category: FileCategory.TaskSectionRevision, + uploadedByUserId: currentId!.Value, + storageProvider: StorageProvider.LocalFileSystem + ); + + await _fileRepository.AddAsync(uploadedFile); + await _fileRepository.SaveChangesAsync(); + + try + { + await using var stream = file.OpenReadStream(); + var uploadResult = await _fileStorageService.UploadAsync( + stream, + uploadedFile.UniqueFileName, + "TaskSectionRevision" + ); + + uploadedFile.CompleteUpload(uploadResult.StoragePath, uploadResult.StorageUrl); + + if (fileType == FileType.Image) + { + var dimensions = await _thumbnailService.GetImageDimensionsAsync(uploadResult.StoragePath); + if (dimensions.HasValue) + { + uploadedFile.SetImageDimensions(dimensions.Value.Width, dimensions.Value.Height); + } + + var thumbnail = await _thumbnailService + .GenerateImageThumbnailAsync(uploadResult.StoragePath, category: "TaskSectionRevision"); + if (thumbnail.HasValue) + { + uploadedFile.SetThumbnail(thumbnail.Value.ThumbnailUrl); + } + } + + await _fileRepository.UpdateAsync(uploadedFile); + await _fileRepository.SaveChangesAsync(); + + var taskRevisionFile = new TaskRevisionFile(uploadedFile.Id); + entity.AddFile(taskRevisionFile); + } + catch (Exception ex) + { + await _fileRepository.DeleteAsync(uploadedFile); + await _fileRepository.SaveChangesAsync(); + + return OperationResult.ValidationError($"خطا در آپلود فایل: {ex.Message}"); + } + } + + await _revisionRepository.CreateAsync(entity); + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + private FileType DetectFileType(string mimeType, string extension) + { + if (mimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) + return FileType.Image; + + if (mimeType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) + return FileType.Video; + + if (mimeType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) + return FileType.Audio; + + if (new[] { ".zip", ".rar", ".7z", ".tar", ".gz" }.Contains(extension.ToLower())) + return FileType.Archive; + + return FileType.Document; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/FileManagementAgg/Enums/FileCategory.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/FileManagementAgg/Enums/FileCategory.cs index 25e7c3f6..e24d441b 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/FileManagementAgg/Enums/FileCategory.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/FileManagementAgg/Enums/FileCategory.cs @@ -10,6 +10,7 @@ public enum FileCategory ProjectDocument = 3, // مستندات پروژه UserProfilePhoto = 4, // عکس پروفایل کاربر Report = 5, // گزارش - Other = 6 // سایر + Other = 6, // سایر + TaskSectionRevision } diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs index 6dfa7c12..07407e12 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs @@ -1,14 +1,49 @@ using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.FileManagementAgg.Entities; namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; -public class TaskSectionRevision:EntityBase +public class TaskSectionRevision : EntityBase { + public TaskSectionRevision(Guid taskSectionId, + string message, long createdByUserId) + { + TaskSectionId = taskSectionId; + Status = RevisionReviewStatus.Pending; + Message = message; + CreatedByUserId = createdByUserId; + } + public Guid TaskSectionId { get; private set; } - public TaskSectionRevisionStatus Status { get; private set; } + public RevisionReviewStatus Status { get; private set; } + + public string Message { get; private set; } - public Guid CreatedByUserId { get; private set; } - public DateTime CreatedAt { get; private set; } + public long CreatedByUserId { get; private set; } + + public IReadOnlyCollection Files => _files; + private readonly List _files = new(); + + public void AddFile(TaskRevisionFile file) + { + _files.Add(file); + } + +} +public class TaskRevisionFile: EntityBase +{ + public TaskRevisionFile(Guid fileId) + { + FileId = fileId; + } + + public Guid FileId { get; private set; } +} + +public enum RevisionReviewStatus : short +{ + Pending = 1, + Reviewed = 2 } \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRevisionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRevisionRepository.cs new file mode 100644 index 00000000..34397d31 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRevisionRepository.cs @@ -0,0 +1,9 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +public interface ITaskSectionRevisionRepository:IRepository +{ + +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs index 20618330..7679b07b 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs @@ -100,7 +100,12 @@ public static class DependencyInjection services.AddScoped(); services.AddScoped(); + + //TaskSection Time Request + services.AddScoped(); + //TaskSection Revision + services.AddScoped(); #region ServicesInjection diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskChat/TaskChatMessageRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskChatMessageRepository.cs similarity index 100% rename from ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskChat/TaskChatMessageRepository.cs rename to ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskChatMessageRepository.cs diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRevisionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRevisionRepository.cs new file mode 100644 index 00000000..53290925 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRevisionRepository.cs @@ -0,0 +1,16 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class TaskSectionRevisionRepository:RepositoryBase,ITaskSectionRevisionRepository +{ + private readonly ProgramManagerDbContext _programManagerDbContext; + public TaskSectionRevisionRepository(ProgramManagerDbContext programManagerDbContext) : base(programManagerDbContext) + { + _programManagerDbContext = programManagerDbContext; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionTimeRequestRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionTimeRequestRepository.cs new file mode 100644 index 00000000..48d6b181 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionTimeRequestRepository.cs @@ -0,0 +1,16 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class TaskSectionTimeRequestRepository:RepositoryBase,ITaskSectionTimeRequestRepository +{ + private readonly ProgramManagerDbContext _context; + public TaskSectionTimeRequestRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/FileManagement/UploadedFileRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UploadedFileRepository.cs similarity index 100% rename from ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/FileManagement/UploadedFileRepository.cs rename to ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UploadedFileRepository.cs diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/TaskSectionRevisionController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TaskSectionRevisionController.cs new file mode 100644 index 00000000..04648882 --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TaskSectionRevisionController.cs @@ -0,0 +1,23 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateTaskSectionRevision; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class TaskSectionRevisionController:ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + public TaskSectionRevisionController(IMediator mediator) + { + _mediator = mediator; + } + + public async Task> CreateTaskRevision([FromForm]CreateTaskSectionRevisionCommand command) + { + var res =await _mediator.Send(command); + return Ok(res); + } +} \ No newline at end of file From a7c97b22b4a69cc9e5fa01b47dc03e164d9d0d7f Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 21 Jan 2026 18:22:27 +0330 Subject: [PATCH 07/14] add DependencyInjection for task section revision and tasksection time request --- .../DependencyInjection.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs index 7679b07b..32773d41 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs @@ -1,7 +1,3 @@ - - - -using FluentValidation; using GozareshgirProgramManager.Application._Common.Behaviors; using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application.Services.FileManagement; @@ -11,10 +7,7 @@ using GozareshgirProgramManager.Domain.CustomerAgg.Repositories; using GozareshgirProgramManager.Domain.FileManagementAgg.Repositories; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Domain.RoleAgg.Repositories; -using GozareshgirProgramManager.Domain.RoleAgg.Repositories; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; -using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; -using GozareshgirProgramManager.Domain.SkillAgg.Repositories; using GozareshgirProgramManager.Domain.SkillAgg.Repositories; using GozareshgirProgramManager.Domain.TaskChatAgg.Repositories; using GozareshgirProgramManager.Domain.UserAgg.Repositories; From 36ccd9635244275a771539d67a313205d338ca4a Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 21 Jan 2026 19:17:52 +0330 Subject: [PATCH 08/14] add time section time request mapping --- .../Mappings/TaskSectionRevisionMapping.cs | 25 +++++++++++++++ .../Mappings/TimeSectionTimeRequestMapping.cs | 31 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs create mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TimeSectionTimeRequestMapping.cs diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs new file mode 100644 index 00000000..a763ddd8 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs @@ -0,0 +1,25 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class TaskSectionRevisionMapping:IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x => x.Id); + + builder.Property(x => x.Id) + .ValueGeneratedNever(); + + builder.Property(x => x.Status).HasConversion(); + + builder.Property(x => x.Message).HasMaxLength(500); + + builder.OwnsMany(x=>x.Files, file => + { + + }) + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TimeSectionTimeRequestMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TimeSectionTimeRequestMapping.cs new file mode 100644 index 00000000..a06a6355 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TimeSectionTimeRequestMapping.cs @@ -0,0 +1,31 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class TimeSectionTimeRequestMapping:IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x => x.Id); + + builder.Property(x => x.Id) + .ValueGeneratedNever(); + + builder.Property(x => x.RequestStatus). + HasConversion().HasMaxLength(50); + + builder.Property(x=>x.RequestType). + HasConversion().HasMaxLength(50); + + builder.Property(x => x.RequestedTime) + .HasTimeSpanConversion(); + + builder.Property(x => x.TaskSection) + .HasConversion() + .HasMaxLength(50); + + } +} \ No newline at end of file From 025c59e6954ffc5fcc290ea6d4cd1f3f9daef979 Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 21 Jan 2026 19:21:26 +0330 Subject: [PATCH 09/14] Complete TaskSectionRevisionMapping.cs --- .../Mappings/TaskSectionRevisionMapping.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs index a763ddd8..1408c86b 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs @@ -1,3 +1,4 @@ +using GozareshgirProgramManager.Domain.FileManagementAgg.Entities; using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -16,10 +17,17 @@ public class TaskSectionRevisionMapping:IEntityTypeConfiguration x.Status).HasConversion(); builder.Property(x => x.Message).HasMaxLength(500); - - builder.OwnsMany(x=>x.Files, file => + + builder.OwnsMany(x => x.Files, file => { - - }) + file.HasKey(x => x.Id); + file.Property(x => x.Id).ValueGeneratedNever(); + + file.HasOne() + .WithMany() + .HasForeignKey(x => x.FileId) + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); + }); } } \ No newline at end of file From a3fd3e6920db1e9a715894f0818da32bdb95bbd6 Mon Sep 17 00:00:00 2001 From: mahan Date: Thu, 22 Jan 2026 10:17:04 +0330 Subject: [PATCH 10/14] add mapping --- .../Persistence/Context/ProgramManagerDbContext.cs | 6 ++++++ ...meRequestMapping.cs => TaskSectionTimeRequestMapping.cs} | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) rename ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/{TimeSectionTimeRequestMapping.cs => TaskSectionTimeRequestMapping.cs} (84%) diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs index d2cce1ae..48e91fae 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs @@ -53,6 +53,12 @@ public class ProgramManagerDbContext : DbContext, IProgramManagerDbContext // Task Chat public DbSet TaskChatMessages { get; set; } = null!; + //Task Section Time Request + public DbSet TaskSectionTimeRequests { get; set; } + + // Task Section Revision + public DbSet TaskSectionRevisions { get; set; } + protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfigurationsFromAssembly(typeof(ProgramManagerDbContext).Assembly); diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TimeSectionTimeRequestMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionTimeRequestMapping.cs similarity index 84% rename from ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TimeSectionTimeRequestMapping.cs rename to ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionTimeRequestMapping.cs index a06a6355..79f292c2 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TimeSectionTimeRequestMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionTimeRequestMapping.cs @@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; -public class TimeSectionTimeRequestMapping:IEntityTypeConfiguration +public class TaskSectionTimeRequestMapping:IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { @@ -27,5 +27,8 @@ public class TimeSectionTimeRequestMapping:IEntityTypeConfiguration() .HasMaxLength(50); + builder.HasOne(x=>x.TaskSection) + .WithMany().HasForeignKey(x=>x.TaskSectionId); + } } \ No newline at end of file From 7e563a0f015879b974abe7c986e6a3f60580e88e Mon Sep 17 00:00:00 2001 From: mahan Date: Sat, 24 Jan 2026 11:12:25 +0330 Subject: [PATCH 11/14] add Task Revision query and revision and request mapping --- ...zareshgirProgramManager.Application.csproj | 3 +- .../CreateTaskSectionRevisionCommand.cs | 134 -- .../CreateTaskSectionRevisionCommand.cs | 136 ++ .../TaskRevisionsByTaskSectionIdQuery.cs | 74 + .../TaskRevisionsByTaskSectionIdResponse.cs | 42 + .../CreateTimeRequestCommand.cs | 12 +- .../Interfaces/IProgramManagerDbContext.cs | 6 + ...uest and Task section revision.Designer.cs | 1198 +++++++++++++++++ ... time Request and Task section revision.cs | 121 ++ .../Migrations/AppDbContextModelSnapshot.cs | 269 +++- .../TaskSectionAdditionalTimeMapping.cs | 3 + .../Mappings/TaskSectionRevisionMapping.cs | 3 +- .../Mappings/TaskSectionTimeRequestMapping.cs | 5 +- .../TaskSectionRevisionController.cs | 14 +- 14 files changed, 1804 insertions(+), 216 deletions(-) delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs create mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20260122100032_Add time Request and Task section revision.Designer.cs create mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20260122100032_Add time Request and Task section revision.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj index cc16cc3a..e153fe58 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj @@ -26,7 +26,8 @@ - + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs deleted file mode 100644 index d524694e..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs +++ /dev/null @@ -1,134 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Application.Modules.TaskChat.DTOs; -using GozareshgirProgramManager.Application.Services.FileManagement; -using GozareshgirProgramManager.Domain._Common; -using GozareshgirProgramManager.Domain.FileManagementAgg.Entities; -using GozareshgirProgramManager.Domain.FileManagementAgg.Enums; -using GozareshgirProgramManager.Domain.FileManagementAgg.Repositories; -using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; -using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; -using Microsoft.AspNetCore.Http; - -namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateTaskSectionRevision; - -public record CreateTaskSectionRevisionCommand(string Message, List Files, Guid SectionId) : IBaseCommand; - -public class CreateTaskSectionRevisionCommandHandler : IBaseCommandHandler -{ - private readonly ITaskSectionRevisionRepository _revisionRepository; - private readonly IFileStorageService _fileStorageService; - private readonly IAuthHelper _authHelper; - private readonly IUnitOfWork _unitOfWork; - private readonly IUploadedFileRepository _fileRepository; - private readonly IThumbnailGeneratorService _thumbnailService; - - public CreateTaskSectionRevisionCommandHandler(ITaskSectionRevisionRepository revisionRepository, - IFileStorageService fileStorageService, IAuthHelper authHelper, IUnitOfWork unitOfWork, IUploadedFileRepository fileRepository, IThumbnailGeneratorService thumbnailService) - { - _revisionRepository = revisionRepository; - _fileStorageService = fileStorageService; - _authHelper = authHelper; - _unitOfWork = unitOfWork; - _fileRepository = fileRepository; - _thumbnailService = thumbnailService; - } - - public async Task Handle(CreateTaskSectionRevisionCommand request, - CancellationToken cancellationToken) - { - var currentId = _authHelper.GetCurrentUserId(); - - var entity = new TaskSectionRevision(request.SectionId, request.Message, currentId!.Value); - - foreach (var file in request.Files) - { - if (file.Length == 0) - { - return OperationResult.ValidationError("فایل خالی است"); - } - - const long maxFileSize = 100 * 1024 * 1024; - if (file.Length > maxFileSize) - { - return OperationResult.ValidationError("حجم فایل بیش از حد مجاز است (حداکثر 100MB)"); - } - - var fileType = DetectFileType(file.ContentType, Path.GetExtension(file.FileName)); - - var uploadedFile = new UploadedFile( - originalFileName: file.FileName, - fileSizeBytes: file.Length, - mimeType: file.ContentType, - fileType: fileType, - category: FileCategory.TaskSectionRevision, - uploadedByUserId: currentId!.Value, - storageProvider: StorageProvider.LocalFileSystem - ); - - await _fileRepository.AddAsync(uploadedFile); - await _fileRepository.SaveChangesAsync(); - - try - { - await using var stream = file.OpenReadStream(); - var uploadResult = await _fileStorageService.UploadAsync( - stream, - uploadedFile.UniqueFileName, - "TaskSectionRevision" - ); - - uploadedFile.CompleteUpload(uploadResult.StoragePath, uploadResult.StorageUrl); - - if (fileType == FileType.Image) - { - var dimensions = await _thumbnailService.GetImageDimensionsAsync(uploadResult.StoragePath); - if (dimensions.HasValue) - { - uploadedFile.SetImageDimensions(dimensions.Value.Width, dimensions.Value.Height); - } - - var thumbnail = await _thumbnailService - .GenerateImageThumbnailAsync(uploadResult.StoragePath, category: "TaskSectionRevision"); - if (thumbnail.HasValue) - { - uploadedFile.SetThumbnail(thumbnail.Value.ThumbnailUrl); - } - } - - await _fileRepository.UpdateAsync(uploadedFile); - await _fileRepository.SaveChangesAsync(); - - var taskRevisionFile = new TaskRevisionFile(uploadedFile.Id); - entity.AddFile(taskRevisionFile); - } - catch (Exception ex) - { - await _fileRepository.DeleteAsync(uploadedFile); - await _fileRepository.SaveChangesAsync(); - - return OperationResult.ValidationError($"خطا در آپلود فایل: {ex.Message}"); - } - } - - await _revisionRepository.CreateAsync(entity); - await _unitOfWork.SaveChangesAsync(cancellationToken); - return OperationResult.Success(); - } - private FileType DetectFileType(string mimeType, string extension) - { - if (mimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) - return FileType.Image; - - if (mimeType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) - return FileType.Video; - - if (mimeType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) - return FileType.Audio; - - if (new[] { ".zip", ".rar", ".7z", ".tar", ".gz" }.Contains(extension.ToLower())) - return FileType.Archive; - - return FileType.Document; - } -} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs new file mode 100644 index 00000000..c5ad2249 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionCommand.cs @@ -0,0 +1,136 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.TaskChat.DTOs; +using GozareshgirProgramManager.Application.Services.FileManagement; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.FileManagementAgg.Entities; +using GozareshgirProgramManager.Domain.FileManagementAgg.Enums; +using GozareshgirProgramManager.Domain.FileManagementAgg.Repositories; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using Microsoft.AspNetCore.Http; + +namespace GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Commands.CreateTaskSectionRevision; + +public record CreateTaskSectionRevisionCommand(string Message, List Files, Guid SectionId) : IBaseCommand; + +public class CreateTaskSectionRevisionCommandHandler : IBaseCommandHandler +{ + private readonly ITaskSectionRevisionRepository _revisionRepository; + private readonly IFileStorageService _fileStorageService; + private readonly IAuthHelper _authHelper; + private readonly IUnitOfWork _unitOfWork; + private readonly IUploadedFileRepository _fileRepository; + private readonly IThumbnailGeneratorService _thumbnailService; + + public CreateTaskSectionRevisionCommandHandler(ITaskSectionRevisionRepository revisionRepository, + IFileStorageService fileStorageService, IAuthHelper authHelper, IUnitOfWork unitOfWork, IUploadedFileRepository fileRepository, IThumbnailGeneratorService thumbnailService) + { + _revisionRepository = revisionRepository; + _fileStorageService = fileStorageService; + _authHelper = authHelper; + _unitOfWork = unitOfWork; + _fileRepository = fileRepository; + _thumbnailService = thumbnailService; + } + + public async Task Handle(CreateTaskSectionRevisionCommand request, + CancellationToken cancellationToken) + { + var currentId = _authHelper.GetCurrentUserId(); + + var entity = new Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionRevision(request.SectionId, request.Message, currentId!.Value); + if (request.Files is { Count: > 0 }) + { + foreach (var file in request.Files) + { + if (file.Length == 0) + { + return OperationResult.ValidationError("فایل خالی است"); + } + + const long maxFileSize = 100 * 1024 * 1024; + if (file.Length > maxFileSize) + { + return OperationResult.ValidationError("حجم فایل بیش از حد مجاز است (حداکثر 100MB)"); + } + + var fileType = DetectFileType(file.ContentType, Path.GetExtension(file.FileName)); + + var uploadedFile = new UploadedFile( + originalFileName: file.FileName, + fileSizeBytes: file.Length, + mimeType: file.ContentType, + fileType: fileType, + category: FileCategory.TaskSectionRevision, + uploadedByUserId: currentId!.Value, + storageProvider: StorageProvider.LocalFileSystem + ); + + await _fileRepository.AddAsync(uploadedFile); + await _fileRepository.SaveChangesAsync(); + + try + { + await using var stream = file.OpenReadStream(); + var uploadResult = await _fileStorageService.UploadAsync( + stream, + uploadedFile.UniqueFileName, + "TaskSectionRevision" + ); + + uploadedFile.CompleteUpload(uploadResult.StoragePath, uploadResult.StorageUrl); + + if (fileType == FileType.Image) + { + var dimensions = await _thumbnailService.GetImageDimensionsAsync(uploadResult.StoragePath); + if (dimensions.HasValue) + { + uploadedFile.SetImageDimensions(dimensions.Value.Width, dimensions.Value.Height); + } + + var thumbnail = await _thumbnailService + .GenerateImageThumbnailAsync(uploadResult.StoragePath, category: "TaskSectionRevision"); + if (thumbnail.HasValue) + { + uploadedFile.SetThumbnail(thumbnail.Value.ThumbnailUrl); + } + } + + await _fileRepository.UpdateAsync(uploadedFile); + await _fileRepository.SaveChangesAsync(); + + var taskRevisionFile = new TaskRevisionFile(uploadedFile.Id); + entity.AddFile(taskRevisionFile); + } + catch (Exception ex) + { + await _fileRepository.DeleteAsync(uploadedFile); + await _fileRepository.SaveChangesAsync(); + + return OperationResult.ValidationError($"خطا در آپلود فایل: {ex.Message}"); + } + } + } + + await _revisionRepository.CreateAsync(entity); + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + private FileType DetectFileType(string mimeType, string extension) + { + if (mimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) + return FileType.Image; + + if (mimeType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) + return FileType.Video; + + if (mimeType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) + return FileType.Audio; + + if (new[] { ".zip", ".rar", ".7z", ".tar", ".gz" }.Contains(extension.ToLower())) + return FileType.Archive; + + return FileType.Document; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs new file mode 100644 index 00000000..9ee7ae0f --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs @@ -0,0 +1,74 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Queries.TaskRevisionsByTaskSectionId; + +public record TaskRevisionsByTaskSectionIdQuery(Guid TaskSectionId) + : IBaseQuery; + +public class TaskRevisionsByTaskSectionIdQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _dbContext; + + public TaskRevisionsByTaskSectionIdQueryHandler(IProgramManagerDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task> Handle( + TaskRevisionsByTaskSectionIdQuery request, CancellationToken cancellationToken) + { + var taskEntity = await _dbContext.TaskSections + .Include(x=>x.Task) + .ThenInclude(x => x.Phase) + .ThenInclude(x => x.Project) + .FirstOrDefaultAsync(x => x.Id == request.TaskSectionId, + cancellationToken: cancellationToken); + if (taskEntity == null) + { + return OperationResult.NotFound("بخش فرعی یافت نشد"); + } + + var taskRevisions = await _dbContext.TaskSectionRevisions + .Include(x => x.Files).Where(x => x.TaskSectionId == request.TaskSectionId) + .ToListAsync(cancellationToken); + if (taskRevisions.Count == 0) + { + return OperationResult.NotFound("اصلاحی یافت نشد"); + } + + var fileIds = taskRevisions.SelectMany(x => x.Files) + .Select(x => x.FileId).Distinct().ToList(); + + var uploadedFiles = _dbContext.UploadedFiles + .Where(x => fileIds.Contains(x.Id)).ToList(); + + var resItems = taskRevisions.Select(x => + { + var itemFileIds = x.Files.Select(f => f.FileId).Distinct().ToList(); + + var files = uploadedFiles.Where(f => itemFileIds.Contains(f.Id)) + .Select(file => new TaskRevisionsByTaskSectionIdItemFile() + { + Id = file.Id, + FileName = file.OriginalFileName, + FileUrl = file.StorageUrl ?? "", + FileSizeBytes = file.FileSizeBytes, + FileType = file.FileType.ToString(), + ThumbnailUrl = file.ThumbnailUrl, + ImageWidth = file.ImageWidth, + ImageHeight = file.ImageHeight, + DurationSeconds = file.DurationSeconds + }).ToList(); + + return new TaskRevisionsByTaskSectionIdItem(x.Message, files); + }).ToList(); + + var res = new TaskRevisionsByTaskSectionIdResponse(resItems, taskEntity.Task.Phase.Project.Name, + taskEntity.Task.Phase.Name, taskEntity.Task.Name); + + return OperationResult.Success(res); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs new file mode 100644 index 00000000..cc0fdcd2 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs @@ -0,0 +1,42 @@ +namespace GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Queries.TaskRevisionsByTaskSectionId; + +public record TaskRevisionsByTaskSectionIdResponse( + List Items, + string ProjectName, + string PhaseName, + string TaskName); + + +public record TaskRevisionsByTaskSectionIdItem(string Message, List Files); + +public class TaskRevisionsByTaskSectionIdItemFile +{ + public Guid Id { get; set; } + public string FileName { get; set; } = string.Empty; + public string FileUrl { get; set; } = string.Empty; + public long FileSizeBytes { get; set; } + public string FileType { get; set; } = string.Empty; + public string? ThumbnailUrl { get; set; } + public int? ImageWidth { get; set; } + public int? ImageHeight { get; set; } + public int? DurationSeconds { get; set; } + + public string FileSizeFormatted + { + get + { + const long kb = 1024; + const long mb = kb * 1024; + const long gb = mb * 1024; + + if (FileSizeBytes >= gb) + return $"{FileSizeBytes / (double)gb:F2} GB"; + if (FileSizeBytes >= mb) + return $"{FileSizeBytes / (double)mb:F2} MB"; + if (FileSizeBytes >= kb) + return $"{FileSizeBytes / (double)kb:F2} KB"; + + return $"{FileSizeBytes} Bytes"; + } + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs index 629acf16..fa0bf44a 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/CreateTimeRequest/CreateTimeRequestCommand.cs @@ -15,14 +15,16 @@ public class CreateTimeRequestCommandHandler : IBaseCommandHandler Handle(CreateTimeRequestCommand request, CancellationToken cancellationToken) @@ -33,10 +35,16 @@ public class CreateTimeRequestCommandHandler : IBaseCommandHandlerx.Id == request.TaskSectionId)) + { + return OperationResult.NotFound("وظیفه فرعی مورد نظر یافت نشد"); + } + + var requestTimeSpan = TimeSpan.FromHours(request.Hours) + TimeSpan.FromMinutes(request.Minutes); var entity = new TaskSectionTimeRequest(currentUser.Value, request.Description, requestTimeSpan, - TaskSectionTimeRequestType.RejectedTime,request.TaskSectionId); + request.RequestType,request.TaskSectionId); await _timeRequestRepository.CreateAsync(entity); await _unitOfWork.SaveChangesAsync(cancellationToken); return OperationResult.Success(); diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IProgramManagerDbContext.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IProgramManagerDbContext.cs index 8246d281..1b77c175 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IProgramManagerDbContext.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IProgramManagerDbContext.cs @@ -35,6 +35,12 @@ public interface IProgramManagerDbContext DbSet TaskChatMessages { get; set; } DbSet UploadedFiles { get; set; } + //Task Section Time Request + DbSet TaskSectionTimeRequests { get; set; } + + // Task Section Revision + DbSet TaskSectionRevisions { get; set; } + DbSet Skills { get; set; } Task SaveChangesAsync(CancellationToken cancellationToken = default); } diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20260122100032_Add time Request and Task section revision.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20260122100032_Add time Request and Task section revision.Designer.cs new file mode 100644 index 00000000..5e92b274 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20260122100032_Add time Request and Task section revision.Designer.cs @@ -0,0 +1,1198 @@ +// +using System; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + [DbContext(typeof(ProgramManagerDbContext))] + [Migration("20260122100032_Add time Request and Task section revision")] + partial class AddtimeRequestandTasksectionrevision + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CheckoutAgg.Entities.Checkout", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CheckoutEndDate") + .HasColumnType("datetime2"); + + b.Property("CheckoutStartDate") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeductionFromSalary") + .HasColumnType("float"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("MandatoryHours") + .HasColumnType("int"); + + b.Property("Month") + .HasColumnType("int"); + + b.Property("MonthlySalaryDefined") + .HasColumnType("float"); + + b.Property("MonthlySalaryPay") + .HasColumnType("float"); + + b.Property("RemainingHours") + .HasColumnType("int"); + + b.Property("TotalDaysWorked") + .HasColumnType("int"); + + b.Property("TotalHoursWorked") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Checkouts", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.FileManagementAgg.Entities.UploadedFile", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeletedByUserId") + .HasColumnType("bigint"); + + b.Property("DeletedDate") + .HasColumnType("datetime2"); + + b.Property("DurationSeconds") + .HasColumnType("int"); + + b.Property("FileExtension") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("FileSizeBytes") + .HasColumnType("bigint"); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ImageHeight") + .HasColumnType("int"); + + b.Property("ImageWidth") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("IsVirusScanPassed") + .HasColumnType("bit"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OriginalFileName") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("ReferenceEntityId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ReferenceEntityType") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StoragePath") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("StorageProvider") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StorageUrl") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ThumbnailUrl") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("UniqueFileName") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UploadDate") + .HasColumnType("datetime2"); + + b.Property("UploadedByUserId") + .HasColumnType("bigint"); + + b.Property("VirusScanDate") + .HasColumnType("datetime2"); + + b.Property("VirusScanResult") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("Status"); + + b.HasIndex("UniqueFileName") + .IsUnique(); + + b.HasIndex("UploadedByUserId"); + + b.HasIndex("ReferenceEntityType", "ReferenceEntityId"); + + b.ToTable("UploadedFiles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.PhaseSection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.HasIndex("SkillId"); + + b.ToTable("PhaseSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeployStatus") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("IsArchived") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.ProjectSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("SkillId"); + + b.ToTable("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("OriginalAssignedUserId") + .HasColumnType("bigint"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("TaskSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionRevision", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TaskSectionRevisions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionTimeRequest", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1200) + .HasColumnType("nvarchar(1200)"); + + b.Property("RequestStatus") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RequestType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RequestedTime") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("TaskSectionTimeRequests"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("PmRoles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.TaskChatAgg.Entities.TaskChatMessage", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeletedDate") + .HasColumnType("datetime2"); + + b.Property("EditedDate") + .HasColumnType("datetime2"); + + b.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("IsEdited") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("IsPinned") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("MessageType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("PinnedByUserId") + .HasColumnType("bigint"); + + b.Property("PinnedDate") + .HasColumnType("datetime2"); + + b.Property("ReplyToMessageId") + .HasColumnType("uniqueidentifier"); + + b.Property("SenderUserId") + .HasColumnType("bigint"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.Property("TextContent") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.HasKey("Id"); + + b.HasIndex("CreationDate"); + + b.HasIndex("FileId"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("ReplyToMessageId"); + + b.HasIndex("SenderUserId"); + + b.HasIndex("TaskId"); + + b.HasIndex("TaskId", "IsPinned"); + + b.ToTable("TaskChatMessages", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RevokedAt") + .HasColumnType("datetime2"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserAgent") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ExpiresAt"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("UserRefreshTokens", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.PhaseSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", "Phase") + .WithMany("PhaseSections") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany() + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Phase"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.Project", "Project") + .WithMany("Phases") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.ProjectSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.Project", "Project") + .WithMany("ProjectSections") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany() + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Project"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.ProjectTask", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", "Phase") + .WithMany("Tasks") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Phase"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.ProjectTask", "Task") + .WithMany("Sections") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Skill"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionActivity", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", "Section") + .WithMany("Activities") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Section"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("TaskSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionRevision", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskRevisionFile", "Files", b1 => + { + b1.Property("Id") + .HasColumnType("uniqueidentifier"); + + b1.Property("CreationDate") + .HasColumnType("datetime2"); + + b1.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b1.Property("TaskSectionRevisionId") + .HasColumnType("uniqueidentifier"); + + b1.HasKey("Id"); + + b1.HasIndex("FileId"); + + b1.HasIndex("TaskSectionRevisionId"); + + b1.ToTable("TaskRevisionFile"); + + b1.HasOne("GozareshgirProgramManager.Domain.FileManagementAgg.Entities.UploadedFile", null) + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b1.WithOwner() + .HasForeignKey("TaskSectionRevisionId"); + }); + + b.Navigation("Files"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionTimeRequest", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", "TaskSection") + .WithMany() + .HasForeignKey("TaskSectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskSection"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("PmRolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("IsActiveDay") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.TaskChatAgg.Entities.TaskChatMessage", b => + { + b.HasOne("GozareshgirProgramManager.Domain.TaskChatAgg.Entities.TaskChatMessage", "ReplyToMessage") + .WithMany() + .HasForeignKey("ReplyToMessageId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("ReplyToMessage"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User") + .WithMany("RefreshTokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", b => + { + b.Navigation("PhaseSections"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.Project", b => + { + b.Navigation("Phases"); + + b.Navigation("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Navigation("RefreshTokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20260122100032_Add time Request and Task section revision.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20260122100032_Add time Request and Task section revision.cs new file mode 100644 index 00000000..0a12abce --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20260122100032_Add time Request and Task section revision.cs @@ -0,0 +1,121 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class AddtimeRequestandTasksectionrevision : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Type", + table: "TaskSectionAdditionalTimes", + type: "nvarchar(50)", + maxLength: 50, + nullable: false, + defaultValue: ""); + + migrationBuilder.CreateTable( + name: "TaskSectionRevisions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TaskSectionId = table.Column(type: "uniqueidentifier", nullable: false), + Status = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Message = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + CreatedByUserId = table.Column(type: "bigint", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TaskSectionRevisions", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "TaskSectionTimeRequests", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TaskSectionId = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "bigint", nullable: false), + Description = table.Column(type: "nvarchar(1200)", maxLength: 1200, nullable: false), + RequestedTime = table.Column(type: "nvarchar(30)", maxLength: 30, nullable: false), + RequestType = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + RequestStatus = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TaskSectionTimeRequests", x => x.Id); + table.ForeignKey( + name: "FK_TaskSectionTimeRequests_TaskSections_TaskSectionId", + column: x => x.TaskSectionId, + principalTable: "TaskSections", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "TaskRevisionFile", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + FileId = table.Column(type: "uniqueidentifier", nullable: false), + TaskSectionRevisionId = table.Column(type: "uniqueidentifier", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TaskRevisionFile", x => x.Id); + table.ForeignKey( + name: "FK_TaskRevisionFile_TaskSectionRevisions_TaskSectionRevisionId", + column: x => x.TaskSectionRevisionId, + principalTable: "TaskSectionRevisions", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_TaskRevisionFile_UploadedFiles_FileId", + column: x => x.FileId, + principalTable: "UploadedFiles", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_TaskRevisionFile_FileId", + table: "TaskRevisionFile", + column: "FileId"); + + migrationBuilder.CreateIndex( + name: "IX_TaskRevisionFile_TaskSectionRevisionId", + table: "TaskRevisionFile", + column: "TaskSectionRevisionId"); + + migrationBuilder.CreateIndex( + name: "IX_TaskSectionTimeRequests_TaskSectionId", + table: "TaskSectionTimeRequests", + column: "TaskSectionId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "TaskRevisionFile"); + + migrationBuilder.DropTable( + name: "TaskSectionTimeRequests"); + + migrationBuilder.DropTable( + name: "TaskSectionRevisions"); + + migrationBuilder.DropColumn( + name: "Type", + table: "TaskSectionAdditionalTimes"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs index 2ac44b92..6bf8b72b 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs @@ -227,7 +227,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("UploadedFiles", (string)null); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.PhaseSection", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -254,49 +254,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("PhaseSections"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationDate") - .HasColumnType("datetime2"); - - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("nvarchar(1000)"); - - b.Property("EndDate") - .HasColumnType("datetime2"); - - b.Property("HasAssignmentOverride") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("PlannedEndDate") - .HasColumnType("datetime2"); - - b.Property("PlannedStartDate") - .HasColumnType("datetime2"); - - b.Property("StartDate") - .HasColumnType("datetime2"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.HasKey("Id"); - - b.ToTable("Projects", (string)null); - }); - - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", b => { b.Property("Id") .HasColumnType("uniqueidentifier"); @@ -348,7 +306,49 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("ProjectPhases", (string)null); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.ProjectSection", b => { b.Property("Id") .HasColumnType("uniqueidentifier"); @@ -374,7 +374,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("ProjectSections"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.ProjectTask", b => { b.Property("Id") .HasColumnType("uniqueidentifier"); @@ -433,7 +433,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("ProjectTasks", (string)null); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", b => { b.Property("Id") .HasColumnType("uniqueidentifier"); @@ -476,7 +476,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("TaskSections", (string)null); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionActivity", b => { b.Property("Id") .HasColumnType("uniqueidentifier"); @@ -514,7 +514,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("TaskSectionActivities", (string)null); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionAdditionalTime", b => { b.Property("Id") .HasColumnType("uniqueidentifier"); @@ -540,6 +540,11 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Property("TaskSectionId") .HasColumnType("uniqueidentifier"); + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + b.HasKey("Id"); b.HasIndex("TaskSectionId"); @@ -547,6 +552,76 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("TaskSectionAdditionalTimes", (string)null); }); + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionRevision", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("TaskSectionRevisions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionTimeRequest", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1200) + .HasColumnType("nvarchar(1200)"); + + b.Property("RequestStatus") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RequestType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RequestedTime") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("TaskSectionTimeRequests"); + }); + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => { b.Property("Id") @@ -792,9 +867,9 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.ToTable("UserRefreshTokens", (string)null); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.PhaseSection", b => { - b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", "Phase") .WithMany("PhaseSections") .HasForeignKey("PhaseId") .OnDelete(DeleteBehavior.Cascade) @@ -810,9 +885,9 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Navigation("Skill"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", b => { - b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", "Project") + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.Project", "Project") .WithMany("Phases") .HasForeignKey("ProjectId") .OnDelete(DeleteBehavior.Cascade) @@ -821,9 +896,9 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Navigation("Project"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.ProjectSection", b => { - b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", "Project") + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.Project", "Project") .WithMany("ProjectSections") .HasForeignKey("ProjectId") .OnDelete(DeleteBehavior.Cascade) @@ -839,9 +914,9 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Navigation("Skill"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.ProjectTask", b => { - b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", "Phase") .WithMany("Tasks") .HasForeignKey("PhaseId") .OnDelete(DeleteBehavior.Cascade) @@ -850,7 +925,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Navigation("Phase"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", b => { b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") .WithMany("Sections") @@ -858,7 +933,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", "Task") + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.ProjectTask", "Task") .WithMany("Sections") .HasForeignKey("TaskId") .OnDelete(DeleteBehavior.Cascade) @@ -869,9 +944,9 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Navigation("Task"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionActivity", b => { - b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", "Section") + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", "Section") .WithMany("Activities") .HasForeignKey("SectionId") .OnDelete(DeleteBehavior.Cascade) @@ -880,13 +955,61 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Navigation("Section"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionAdditionalTime", b => { - b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", null) .WithMany("AdditionalTimes") .HasForeignKey("TaskSectionId"); }); + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionRevision", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskRevisionFile", "Files", b1 => + { + b1.Property("Id") + .HasColumnType("uniqueidentifier"); + + b1.Property("CreationDate") + .HasColumnType("datetime2"); + + b1.Property("FileId") + .HasColumnType("uniqueidentifier"); + + b1.Property("TaskSectionRevisionId") + .HasColumnType("uniqueidentifier"); + + b1.HasKey("Id"); + + b1.HasIndex("FileId"); + + b1.HasIndex("TaskSectionRevisionId"); + + b1.ToTable("TaskRevisionFile"); + + b1.HasOne("GozareshgirProgramManager.Domain.FileManagementAgg.Entities.UploadedFile", null) + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b1.WithOwner() + .HasForeignKey("TaskSectionRevisionId"); + }); + + b.Navigation("Files"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSectionTimeRequest", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", "TaskSection") + .WithMany() + .HasForeignKey("TaskSectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskSection"); + }); + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => { b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => @@ -1031,26 +1154,26 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Navigation("User"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => - { - b.Navigation("Phases"); - - b.Navigation("ProjectSections"); - }); - - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Phase.ProjectPhase", b => { b.Navigation("PhaseSections"); b.Navigation("Tasks"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project.Project", b => + { + b.Navigation("Phases"); + + b.Navigation("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.ProjectTask", b => { b.Navigation("Sections"); }); - modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection.TaskSection", b => { b.Navigation("Activities"); diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs index 6629b740..30dc130c 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs @@ -34,6 +34,9 @@ public class TaskSectionAdditionalTimeMapping : IEntityTypeConfiguration at.CreationDate) .IsRequired(); + builder.Property(x=>x.Type) + .HasConversion() + .HasMaxLength(50); // Ignore domain events builder.Ignore(at => at.DomainEvents); } diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs index 1408c86b..25a796ad 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionRevisionMapping.cs @@ -14,7 +14,8 @@ public class TaskSectionRevisionMapping:IEntityTypeConfiguration x.Id) .ValueGeneratedNever(); - builder.Property(x => x.Status).HasConversion(); + builder.Property(x => x.Status).HasConversion() + .HasMaxLength(50); builder.Property(x => x.Message).HasMaxLength(500); diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionTimeRequestMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionTimeRequestMapping.cs index 79f292c2..6e3e6311 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionTimeRequestMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionTimeRequestMapping.cs @@ -23,9 +23,8 @@ public class TaskSectionTimeRequestMapping:IEntityTypeConfiguration x.RequestedTime) .HasTimeSpanConversion(); - builder.Property(x => x.TaskSection) - .HasConversion() - .HasMaxLength(50); + builder.Property(x=>x.Description) + .HasMaxLength(1200); builder.HasOne(x=>x.TaskSection) .WithMany().HasForeignKey(x=>x.TaskSectionId); diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/TaskSectionRevisionController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TaskSectionRevisionController.cs index 04648882..39752fb7 100644 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/TaskSectionRevisionController.cs +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TaskSectionRevisionController.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateTaskSectionRevision; +using GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Commands.CreateTaskSectionRevision; +using GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Queries.TaskRevisionsByTaskSectionId; using MediatR; using Microsoft.AspNetCore.Mvc; using ServiceHost.BaseControllers; @@ -14,10 +15,19 @@ public class TaskSectionRevisionController:ProgramManagerBaseController { _mediator = mediator; } - + + [HttpPost] public async Task> CreateTaskRevision([FromForm]CreateTaskSectionRevisionCommand command) { var res =await _mediator.Send(command); return Ok(res); } + + [HttpGet()] + public async Task>> GetRevisionsBySectionId( + TaskRevisionsByTaskSectionIdQuery query) + { + var res = await _mediator.Send(query); + return res; + } } \ No newline at end of file From 15f1c938f730a1aad5672d13c710f2cc64b292b7 Mon Sep 17 00:00:00 2001 From: mahan Date: Sat, 24 Jan 2026 14:02:18 +0330 Subject: [PATCH 12/14] add workflow controller --- .../TaskRevisionsByTaskSectionIdQuery.cs | 3 +- .../Queries/WorkflowList/WorkflowListQuery.cs | 62 +++++++++++++++++++ .../ProgramManager/WorkflowController.cs | 25 ++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowListQuery.cs create mode 100644 ServiceHost/Areas/Admin/Controllers/ProgramManager/WorkflowController.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs index 9ee7ae0f..f8ff4ec0 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs @@ -49,7 +49,8 @@ public class TaskRevisionsByTaskSectionIdQueryHandler : IBaseQueryHandler f.FileId).Distinct().ToList(); - var files = uploadedFiles.Where(f => itemFileIds.Contains(f.Id)) + var files = uploadedFiles + .Where(f => itemFileIds.Contains(f.Id)) .Select(file => new TaskRevisionsByTaskSectionIdItemFile() { Id = file.Id, diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowListQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowListQuery.cs new file mode 100644 index 00000000..0087763e --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowListQuery.cs @@ -0,0 +1,62 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList; + +public record WorkflowListResponse(ListItems); + +public class WorkflowListItem +{ + public string Title { get; set; } + public WorkflowType Type { get; set; } + public Guid EntityId { get; set; } +} + +public enum WorkflowType +{ + Rejected, + NotAssigned, + PendingForApproval, +} + +public record WorkflowListQuery():IBaseQuery; + +public class WorkflowListQueryHandler:IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + private readonly IAuthHelper _authHelper; + + public WorkflowListQueryHandler(IProgramManagerDbContext context, + IAuthHelper authHelper) + { + _context = context; + _authHelper = authHelper; + } + + public async Task> Handle(WorkflowListQuery request, CancellationToken cancellationToken) + { + var currentUserId =_authHelper.GetCurrentUserId(); + + var query = await (from revision in _context.TaskSectionRevisions + .Where(x=>x.Status == RevisionReviewStatus.Pending) + join taskSection in _context.TaskSections.Where(x => x.CurrentAssignedUserId == currentUserId) + on revision.TaskSectionId equals taskSection.Id + select new + { + taskSection, + revision + + }).ToListAsync(cancellationToken: cancellationToken); + + var workflowListItems = query.Select(x=>new WorkflowListItem() + { + EntityId = x.taskSection.Id, + Title = "برگشت از سمت مدیر", + Type = WorkflowType.Rejected + }).ToList(); + var res = new WorkflowListResponse(workflowListItems); + return OperationResult.Success(res); + } +} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/WorkflowController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/WorkflowController.cs new file mode 100644 index 00000000..0f2da3ef --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/WorkflowController.cs @@ -0,0 +1,25 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class WorkflowController:ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + public WorkflowController(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet] + public async Task>> Get(WorkflowListQuery query) + { + var res = await _mediator.Send(query); + return res; + } + +} \ No newline at end of file From 03657b684836bccb83f81f0a819548cb09c76260 Mon Sep 17 00:00:00 2001 From: mahan Date: Sat, 24 Jan 2026 17:29:08 +0330 Subject: [PATCH 13/14] add missing data for task revisions --- .../TaskRevisionsByTaskSectionIdQuery.cs | 29 +++++++++++++++---- .../TaskRevisionsByTaskSectionIdResponse.cs | 6 ++-- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs index f8ff4ec0..d4988f58 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdQuery.cs @@ -1,5 +1,6 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; using Microsoft.EntityFrameworkCore; namespace GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Queries.TaskRevisionsByTaskSectionId; @@ -20,17 +21,18 @@ public class TaskRevisionsByTaskSectionIdQueryHandler : IBaseQueryHandler> Handle( TaskRevisionsByTaskSectionIdQuery request, CancellationToken cancellationToken) { - var taskEntity = await _dbContext.TaskSections + var taskSectionEntity = await _dbContext.TaskSections .Include(x=>x.Task) .ThenInclude(x => x.Phase) .ThenInclude(x => x.Project) .FirstOrDefaultAsync(x => x.Id == request.TaskSectionId, cancellationToken: cancellationToken); - if (taskEntity == null) + + if (taskSectionEntity == null) { return OperationResult.NotFound("بخش فرعی یافت نشد"); } - + var taskRevisions = await _dbContext.TaskSectionRevisions .Include(x => x.Files).Where(x => x.TaskSectionId == request.TaskSectionId) .ToListAsync(cancellationToken); @@ -39,6 +41,18 @@ public class TaskRevisionsByTaskSectionIdQueryHandler : IBaseQueryHandler.NotFound("اصلاحی یافت نشد"); } + var skill = await _dbContext.Skills.FirstOrDefaultAsync(x => x.Id == taskSectionEntity.SkillId, + cancellationToken: cancellationToken); + + if (skill == null) + return OperationResult.NotFound("مهارت مورد نظر یافت نشد"); + + + var user =await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == taskSectionEntity.CurrentAssignedUserId, + cancellationToken: cancellationToken); + if (user == null) + return OperationResult.NotFound("کاربر مورد نظر یافت نشد"); + var fileIds = taskRevisions.SelectMany(x => x.Files) .Select(x => x.FileId).Distinct().ToList(); @@ -64,11 +78,14 @@ public class TaskRevisionsByTaskSectionIdQueryHandler : IBaseQueryHandler.Success(res); } diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs index cc0fdcd2..d8c6a0ff 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs @@ -4,10 +4,12 @@ public record TaskRevisionsByTaskSectionIdResponse( List Items, string ProjectName, string PhaseName, - string TaskName); + string TaskName, + string SkillName, + string UserName); -public record TaskRevisionsByTaskSectionIdItem(string Message, List Files); +public record TaskRevisionsByTaskSectionIdItem(string Message, List Files,string CreationDate); public class TaskRevisionsByTaskSectionIdItemFile { From 64693b2ca3d65d7c60e4f52bb23cce62d810430e Mon Sep 17 00:00:00 2001 From: mahan Date: Sun, 25 Jan 2026 12:34:27 +0330 Subject: [PATCH 14/14] add workflow result --- ...zareshgirProgramManager.Application.csproj | 5 -- .../CreateTaskSectionRevisionValidator.cs | 14 ++++++ .../SetStatusReviewedRevisionCommand.cs | 35 +++++++++++++ .../TaskRevisionsByTaskSectionIdResponse.cs | 34 ++----------- .../AcceptTimeRequestCommand.cs | 27 +++++++--- .../CreateTimeRequestDetailsQuery.cs | 49 ++++++++++++++++++ .../Queries/WorkflowList/IWorkflowProvider.cs | 11 ++++ .../Providers/NotAssignedWorkflowProvider.cs | 31 ++++++++++++ .../RejectedRevisionsWorkflowProvider.cs | 41 +++++++++++++++ .../WorkflowList/WorkflowCountQuery.cs | 50 +++++++++++++++++++ .../Queries/WorkflowList/WorkflowListQuery.cs | 34 ++++++------- .../_Common/Extensions/FileExtensions.cs | 23 +++++++++ .../_Common/Models/UploadedFileDto.cs | 34 +++++++++++++ .../Task/TaskSection/TaskSectionRevision.cs | 7 +++ .../TaskSection/TaskSectionTimeRequest.cs | 6 ++- .../ITaskSectionRevisionRepository.cs | 2 +- .../DependencyInjection.cs | 13 +++++ .../TaskSectionRevisionRepository.cs | 8 +++ .../ProgramManager/TimeRequestController.cs | 26 +++++++++- .../ProgramManager/WorkflowController.cs | 7 +++ ServiceHost/Properties/launchSettings.json | 6 +-- 21 files changed, 393 insertions(+), 70 deletions(-) create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionValidator.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/SetStatusReviewedRevision/SetStatusReviewedRevisionCommand.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Queries/CreateTimeRequestDetails/CreateTimeRequestDetailsQuery.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/IWorkflowProvider.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/Providers/NotAssignedWorkflowProvider.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/Providers/RejectedRevisionsWorkflowProvider.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowCountQuery.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/FileExtensions.cs create mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/UploadedFileDto.cs diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj index e153fe58..d28d7b48 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj @@ -25,9 +25,4 @@ - - - - - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionValidator.cs new file mode 100644 index 00000000..4bd7ebcb --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/CreateTaskSectionRevision/CreateTaskSectionRevisionValidator.cs @@ -0,0 +1,14 @@ +using FluentValidation; +using Microsoft.EntityFrameworkCore.ChangeTracking; + +namespace GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Commands.CreateTaskSectionRevision; + +public class CreateTaskSectionRevisionValidator:AbstractValidator +{ + public CreateTaskSectionRevisionValidator() + { + RuleFor(x=>x.Message) + .NotEmpty() + .WithMessage("توضیحات اجباری است"); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/SetStatusReviewedRevision/SetStatusReviewedRevisionCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/SetStatusReviewedRevision/SetStatusReviewedRevisionCommand.cs new file mode 100644 index 00000000..b30ec211 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Commands/SetStatusReviewedRevision/SetStatusReviewedRevisionCommand.cs @@ -0,0 +1,35 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Commands.SetStatusReviewedRevision; + +public record SetStatusReviewedRevisionCommand(Guid TaskSectionId):IBaseCommand; + +public class SetStatusReviewedRevisionCommandHandler : IBaseCommandHandler +{ + private readonly ITaskSectionRevisionRepository _revisionRepository; + private readonly IUnitOfWork _unitOfWork; + + public SetStatusReviewedRevisionCommandHandler(ITaskSectionRevisionRepository revisionRepository, IUnitOfWork unitOfWork) + { + _revisionRepository = revisionRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(SetStatusReviewedRevisionCommand request, CancellationToken cancellationToken) + { + var taskSectionRevisions = await _revisionRepository.GetByTaskSectionId(request.TaskSectionId); + if (taskSectionRevisions == null || taskSectionRevisions.Count == 0) + return OperationResult.NotFound("اصلاحی برای این بخش یافت نشد"); + + foreach (var revision in taskSectionRevisions) + { + revision.MarkReviewed(); + } + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs index d8c6a0ff..3fb128cd 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionRevision/Queries/TaskRevisionsByTaskSectionId/TaskRevisionsByTaskSectionIdResponse.cs @@ -1,3 +1,5 @@ +using GozareshgirProgramManager.Application._Common.Models; + namespace GozareshgirProgramManager.Application.Modules.TaskSectionRevision.Queries.TaskRevisionsByTaskSectionId; public record TaskRevisionsByTaskSectionIdResponse( @@ -11,34 +13,4 @@ public record TaskRevisionsByTaskSectionIdResponse( public record TaskRevisionsByTaskSectionIdItem(string Message, List Files,string CreationDate); -public class TaskRevisionsByTaskSectionIdItemFile -{ - public Guid Id { get; set; } - public string FileName { get; set; } = string.Empty; - public string FileUrl { get; set; } = string.Empty; - public long FileSizeBytes { get; set; } - public string FileType { get; set; } = string.Empty; - public string? ThumbnailUrl { get; set; } - public int? ImageWidth { get; set; } - public int? ImageHeight { get; set; } - public int? DurationSeconds { get; set; } - - public string FileSizeFormatted - { - get - { - const long kb = 1024; - const long mb = kb * 1024; - const long gb = mb * 1024; - - if (FileSizeBytes >= gb) - return $"{FileSizeBytes / (double)gb:F2} GB"; - if (FileSizeBytes >= mb) - return $"{FileSizeBytes / (double)mb:F2} MB"; - if (FileSizeBytes >= kb) - return $"{FileSizeBytes / (double)kb:F2} KB"; - - return $"{FileSizeBytes} Bytes"; - } - } -} \ No newline at end of file +public class TaskRevisionsByTaskSectionIdItemFile:UploadedFileDto; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs index fd162ae6..2fcd77f5 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/TaskSectionTimeRequests/Commands/AcceptTimeRequest/AcceptTimeRequestCommand.cs @@ -1,7 +1,8 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; namespace GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.AcceptTimeRequest; @@ -13,10 +14,12 @@ public class AcceptTimeRequestCommandHandler:IBaseCommandHandler Handle(AcceptTimeRequestCommand request, CancellationToken cancellationToken) @@ -33,11 +36,21 @@ public class AcceptTimeRequestCommandHandler:IBaseCommandHandler Revisions); + +public record CreateTimeRequestDetailsRevision(string Message, List Files); + +public record CreateTimeRequestDetailsQuery(Guid TaskSectionId) : IBaseQuery; + +public class + CreateTimeRequestDetailsQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public CreateTimeRequestDetailsQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateTimeRequestDetailsQuery request, + CancellationToken cancellationToken) + { + var revisions = await _context.TaskSectionRevisions.Where(x => + x.TaskSectionId == request.TaskSectionId && x.Status == RevisionReviewStatus.Pending).ToListAsync(cancellationToken: cancellationToken); + + var fileIds = revisions.SelectMany(x => x.Files) + .Select(x => x.Id).ToList(); + + var files =await _context.UploadedFiles + .Where(x => fileIds.Contains(x.Id)).ToListAsync(cancellationToken: cancellationToken); + + var resItem = revisions.Select(x => + { + var selectFileIds = x.Files.Select(f => f.FileId).ToList(); + var filesDto = files.Where(f => selectFileIds.Contains(f.Id)) + .Select(f => f.ToDto()).ToList(); + return new CreateTimeRequestDetailsRevision(x.Message, filesDto); + }).ToList(); + var res = new CreateTimeRequestDetailsResponse(resItem); + + return OperationResult.Success(res); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/IWorkflowProvider.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/IWorkflowProvider.cs new file mode 100644 index 00000000..1769e593 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/IWorkflowProvider.cs @@ -0,0 +1,11 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList; + +namespace GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList; + +public interface IWorkflowProvider +{ + WorkflowType Type { get; } + Task> GetItems(long currentUserId, IProgramManagerDbContext context, CancellationToken cancellationToken); + Task GetCount(long currentUserId, IProgramManagerDbContext context, CancellationToken cancellationToken); +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/Providers/NotAssignedWorkflowProvider.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/Providers/NotAssignedWorkflowProvider.cs new file mode 100644 index 00000000..155f1c2a --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/Providers/NotAssignedWorkflowProvider.cs @@ -0,0 +1,31 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList.Providers; + +public class NotAssignedWorkflowProvider : IWorkflowProvider +{ + public WorkflowType Type => WorkflowType.NotAssigned; + + public async Task> GetItems(long currentUserId, IProgramManagerDbContext context, CancellationToken cancellationToken) + { + // Assuming 0 means unassigned in CurrentAssignedUserId + var sections = await context.TaskSections + .Where(x => x.CurrentAssignedUserId == 0) + .ToListAsync(cancellationToken); + + return sections.Select(ts => new WorkflowListItem + { + EntityId = ts.Id, + Title = "تخصیص‌ نیافته", + Type = WorkflowType.NotAssigned + }).ToList(); + } + + public async Task GetCount(long currentUserId, IProgramManagerDbContext context, CancellationToken cancellationToken) + { + return await context.TaskSections + .Where(x => x.CurrentAssignedUserId == 0) + .CountAsync(cancellationToken); + } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/Providers/RejectedRevisionsWorkflowProvider.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/Providers/RejectedRevisionsWorkflowProvider.cs new file mode 100644 index 00000000..719a1b2f --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/Providers/RejectedRevisionsWorkflowProvider.cs @@ -0,0 +1,41 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList.Providers; + +public class RejectedRevisionsWorkflowProvider : IWorkflowProvider +{ + public WorkflowType Type => WorkflowType.Rejected; + + public async Task> GetItems(long currentUserId, IProgramManagerDbContext context, CancellationToken cancellationToken) + { + var query = from revision in context.TaskSectionRevisions + .Where(x => x.Status == RevisionReviewStatus.Pending) + join taskSection in context.TaskSections + on revision.TaskSectionId equals taskSection.Id + where taskSection.CurrentAssignedUserId == currentUserId + select taskSection; + + var sections = await query.ToListAsync(cancellationToken); + + return sections.Select(ts => new WorkflowListItem + { + EntityId = ts.Id, + Title = "برگشت از سمت مدیر", + Type = WorkflowType.Rejected + }).ToList(); + } + + public async Task GetCount(long currentUserId, IProgramManagerDbContext context, CancellationToken cancellationToken) + { + var query = from revision in context.TaskSectionRevisions + .Where(x => x.Status == RevisionReviewStatus.Pending) + join taskSection in context.TaskSections + on revision.TaskSectionId equals taskSection.Id + where taskSection.CurrentAssignedUserId == currentUserId + select revision.Id; + + return await query.CountAsync(cancellationToken); + } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowCountQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowCountQuery.cs new file mode 100644 index 00000000..0de756bd --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowCountQuery.cs @@ -0,0 +1,50 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList.Providers; + +namespace GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList; + +public record WorkflowCountResponse(int Total, int Rejected, int NotAssigned, int PendingForApproval); + +public record WorkflowCountQuery() : IBaseQuery; + +public class WorkflowCountQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + private readonly IAuthHelper _authHelper; + private readonly IEnumerable _providers; + + public WorkflowCountQueryHandler(IProgramManagerDbContext context, IAuthHelper authHelper, IEnumerable providers) + { + _context = context; + _authHelper = authHelper; + _providers = providers; + } + + public async Task> Handle(WorkflowCountQuery request, CancellationToken cancellationToken) + { + long currentUserId = _authHelper.GetCurrentUserId()!.Value; + + int rejectedCount = 0; + int notAssignedCount = 0; + int pendingForApprovalCount = 0; + + foreach (var provider in _providers) + { + var count = await provider.GetCount(currentUserId, _context, cancellationToken); + switch (provider.Type) + { + case WorkflowType.Rejected: + rejectedCount += count; break; + case WorkflowType.NotAssigned: + notAssignedCount += count; break; + case WorkflowType.PendingForApproval: + pendingForApprovalCount += count; break; + } + } + + var total = rejectedCount + notAssignedCount + pendingForApprovalCount; + var response = new WorkflowCountResponse(total, rejectedCount, notAssignedCount, pendingForApprovalCount); + return OperationResult.Success(response); + } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowListQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowListQuery.cs index 0087763e..18ee2e60 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowListQuery.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Workflows/Queries/WorkflowList/WorkflowListQuery.cs @@ -1,7 +1,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; -using Microsoft.EntityFrameworkCore; +using GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList.Providers; namespace GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList; @@ -27,36 +27,30 @@ public class WorkflowListQueryHandler:IBaseQueryHandler _providers; public WorkflowListQueryHandler(IProgramManagerDbContext context, - IAuthHelper authHelper) + IAuthHelper authHelper, + IEnumerable providers) { _context = context; _authHelper = authHelper; + _providers = providers; } public async Task> Handle(WorkflowListQuery request, CancellationToken cancellationToken) { - var currentUserId =_authHelper.GetCurrentUserId(); + var currentUserId = _authHelper.GetCurrentUserId()!.Value; + var items = new List(); - var query = await (from revision in _context.TaskSectionRevisions - .Where(x=>x.Status == RevisionReviewStatus.Pending) - join taskSection in _context.TaskSections.Where(x => x.CurrentAssignedUserId == currentUserId) - on revision.TaskSectionId equals taskSection.Id - select new - { - taskSection, - revision - - }).ToListAsync(cancellationToken: cancellationToken); - - var workflowListItems = query.Select(x=>new WorkflowListItem() + foreach (var provider in _providers) { - EntityId = x.taskSection.Id, - Title = "برگشت از سمت مدیر", - Type = WorkflowType.Rejected - }).ToList(); - var res = new WorkflowListResponse(workflowListItems); + var providerItems = await provider.GetItems(currentUserId, _context, cancellationToken); + if (providerItems?.Count > 0) + items.AddRange(providerItems); + } + + var res = new WorkflowListResponse(items); return OperationResult.Success(res); } } \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/FileExtensions.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/FileExtensions.cs new file mode 100644 index 00000000..018ad5bd --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/FileExtensions.cs @@ -0,0 +1,23 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain.FileManagementAgg.Entities; + +namespace GozareshgirProgramManager.Application._Common.Extensions; + +public static class FileExtensions +{ + public static UploadedFileDto ToDto(this UploadedFile file) + { + return new UploadedFileDto() + { + Id = file.Id, + FileName = file.OriginalFileName, + FileUrl = file.StorageUrl ?? "", + FileSizeBytes = file.FileSizeBytes, + FileType = file.FileType.ToString(), + ThumbnailUrl = file.ThumbnailUrl, + ImageWidth = file.ImageWidth, + ImageHeight = file.ImageHeight, + DurationSeconds = file.DurationSeconds + }; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/UploadedFileDto.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/UploadedFileDto.cs new file mode 100644 index 00000000..a9a0264d --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/UploadedFileDto.cs @@ -0,0 +1,34 @@ +namespace GozareshgirProgramManager.Application._Common.Models; + +public class UploadedFileDto +{ + + public Guid Id { get; set; } + public string FileName { get; set; } = string.Empty; + public string FileUrl { get; set; } = string.Empty; + public long FileSizeBytes { get; set; } + public string FileType { get; set; } = string.Empty; + public string? ThumbnailUrl { get; set; } + public int? ImageWidth { get; set; } + public int? ImageHeight { get; set; } + public int? DurationSeconds { get; set; } + + public string FileSizeFormatted + { + get + { + const long kb = 1024; + const long mb = kb * 1024; + const long gb = mb * 1024; + + if (FileSizeBytes >= gb) + return $"{FileSizeBytes / (double)gb:F2} GB"; + if (FileSizeBytes >= mb) + return $"{FileSizeBytes / (double)mb:F2} MB"; + if (FileSizeBytes >= kb) + return $"{FileSizeBytes / (double)kb:F2} KB"; + + return $"{FileSizeBytes} Bytes"; + } + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs index 07407e12..41a8f761 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionRevision.cs @@ -30,6 +30,13 @@ public class TaskSectionRevision : EntityBase { _files.Add(file); } + + public void MarkReviewed() + { + if (Status == RevisionReviewStatus.Reviewed) + return; + Status = RevisionReviewStatus.Reviewed; + } } public class TaskRevisionFile: EntityBase diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionTimeRequest.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionTimeRequest.cs index 00358963..dba90501 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionTimeRequest.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Task/TaskSection/TaskSectionTimeRequest.cs @@ -25,5 +25,9 @@ public class TaskSectionTimeRequest:EntityBase public TimeSpan RequestedTime { get; private set; } public TaskSectionTimeRequestType RequestType { get; private set; } public TaskSectionTimeRequestStatus RequestStatus { get; private set; } - + + public void AcceptTimeRequest() + { + RequestStatus = TaskSectionTimeRequestStatus.Accepted; + } } \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRevisionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRevisionRepository.cs index 34397d31..491b8551 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRevisionRepository.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRevisionRepository.cs @@ -5,5 +5,5 @@ namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; public interface ITaskSectionRevisionRepository:IRepository { - + Task> GetByTaskSectionId(Guid requestTaskSectionId); } \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs index 32773d41..4b19a0b0 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs @@ -25,6 +25,9 @@ using Shared.Contracts.PmRole.Commands; using Shared.Contracts.PmRole.Queries; using Shared.Contracts.PmUser.Commands; using Shared.Contracts.PmUser.Queries; +using System.Reflection; +using GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList; +using GozareshgirProgramManager.Application.Modules.Workflows.Queries.WorkflowList.Providers; namespace GozareshgirProgramManager.Infrastructure; @@ -114,6 +117,16 @@ public static class DependencyInjection // MediatR Validation Behavior services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>)); + // Workflow providers: auto-register all IWorkflowProvider implementations in the Application assembly + var appAssembly = typeof(IWorkflowProvider).Assembly; + var providerTypes = appAssembly + .GetTypes() + .Where(t => !t.IsAbstract && !t.IsInterface && typeof(IWorkflowProvider).IsAssignableFrom(t)) + .ToList(); + foreach (var providerType in providerTypes) + { + services.AddScoped(typeof(IWorkflowProvider), providerType); + } return services; } diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRevisionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRevisionRepository.cs index 53290925..1241fcca 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRevisionRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRevisionRepository.cs @@ -13,4 +13,12 @@ public class TaskSectionRevisionRepository:RepositoryBase> GetByTaskSectionId(Guid requestTaskSectionId) + { + var res = await _programManagerDbContext.TaskSectionRevisions + .Where(x => requestTaskSectionId == x.TaskSectionId) + .ToListAsync(); + return res; + } } \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs index 0c959e6a..e459f5ff 100644 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/TimeRequestController.cs @@ -1,6 +1,8 @@ -using System.Runtime.InteropServices; using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.AcceptTimeRequest; using GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Commands.CreateTimeRequest; +using GozareshgirProgramManager.Application.Modules.TaskSectionTimeRequests.Queries.CreateTimeRequestDetails; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities.Task.TaskSection; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -17,6 +19,13 @@ public class TimeRequestController:ProgramManagerBaseController _mediator = mediator; } + [HttpGet("Rejected")] + public async Task> GetCreateRejectedTimeRequest(Guid taskSectionId) + { + var command = new CreateTimeRequestDetailsQuery(taskSectionId); + var res = await _mediator.Send(command); + return res; + } [HttpPost("Rejected")] public async Task> CreateRejectedTimeRequest(CreateTimeRequest request) { @@ -43,6 +52,19 @@ public class TimeRequestController:ProgramManagerBaseController var res = await _mediator.Send(command); return res; } + + [HttpPost("Accept")] + public async Task> AcceptTimeRequest(AcceptTimeRequestDto request) + { + var command = new AcceptTimeRequestCommand(request.TimeRequestId, request.SectionId, + request.TimeType, request.Hour, request.Minute); + var res = await _mediator.Send(command); + return res; + } } -public record CreateTimeRequest(int Hours, int Minutes, string Description,Guid TaskSectionId); \ No newline at end of file +public record CreateTimeRequest(int Hours, int Minutes, string Description,Guid TaskSectionId); + +public record AcceptTimeRequestDto(Guid TimeRequestId, Guid SectionId, + TaskSectionAdditionalTimeType TimeType, int Hour, int Minute); + diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/WorkflowController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/WorkflowController.cs index 0f2da3ef..6acda73d 100644 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/WorkflowController.cs +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/WorkflowController.cs @@ -22,4 +22,11 @@ public class WorkflowController:ProgramManagerBaseController return res; } + [HttpGet("count")] + public async Task>> GetCount(WorkflowCountQuery query) + { + var res = await _mediator.Send(query); + return res; + } + } \ No newline at end of file diff --git a/ServiceHost/Properties/launchSettings.json b/ServiceHost/Properties/launchSettings.json index 788962e4..18aaf56a 100644 --- a/ServiceHost/Properties/launchSettings.json +++ b/ServiceHost/Properties/launchSettings.json @@ -19,7 +19,7 @@ "sqlDebugging": true, "dotnetRunMessages": "true", "nativeDebugging": true, - "applicationUrl": "https://localhost:5004;http://localhost:5003;", + "applicationUrl": "https://localhost:5004;http://localhost:5003;https://192.168.0.117:5006", "jsWebView2Debugging": false, "hotReloadEnabled": true }, @@ -30,7 +30,7 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation", - "ASPNETCORE_URLS": "https://localhost:5004;http://localhost:5003" + "ASPNETCORE_URLS": "https://localhost:5004;http://localhost:5003;" }, "distributionName": "" }, @@ -44,7 +44,7 @@ "sqlDebugging": true, "dotnetRunMessages": "true", "nativeDebugging": true, - "applicationUrl": "https://localhost:5004;http://localhost:5003;", + "applicationUrl": "https://localhost:5004;http://localhost:5003;https://192.168.0.117:5006", "jsWebView2Debugging": false, "hotReloadEnabled": true }