From 3c72311096e4a7294cbc29f1a6d6e06ee030ae58 Mon Sep 17 00:00:00 2001 From: mahan Date: Thu, 1 Jan 2026 10:11:17 +0330 Subject: [PATCH 1/3] refactor: update namespace for AuthorizedBankDetails application components --- .../AuthorizedBankDetails/IAuthorizedBankDetailsApplication.cs | 2 +- .../AuthorizedBankDetailsApplication.cs | 1 + CompanyManagment.EFCore/Services/UidService.cs | 1 + PersonalContractingParty.Config/PersonalBootstrapper.cs | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CompanyManagment.App.Contracts/AuthorizedBankDetails/IAuthorizedBankDetailsApplication.cs b/CompanyManagment.App.Contracts/AuthorizedBankDetails/IAuthorizedBankDetailsApplication.cs index 90368d4a..38b1b6ed 100644 --- a/CompanyManagment.App.Contracts/AuthorizedBankDetails/IAuthorizedBankDetailsApplication.cs +++ b/CompanyManagment.App.Contracts/AuthorizedBankDetails/IAuthorizedBankDetailsApplication.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using _0_Framework.Application; using Company.Application.Contracts.AuthorizedBankDetails; -namespace Company.Application.Contracts.AuthorizedBankDetails +namespace CompanyManagment.App.Contracts.AuthorizedBankDetails { public interface IAuthorizedBankDetailsApplication { diff --git a/CompanyManagment.Application/AuthorizedBankDetailsApplication.cs b/CompanyManagment.Application/AuthorizedBankDetailsApplication.cs index b3a88421..89e16169 100644 --- a/CompanyManagment.Application/AuthorizedBankDetailsApplication.cs +++ b/CompanyManagment.Application/AuthorizedBankDetailsApplication.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using _0_Framework.Application; using Company.Application.Contracts.AuthorizedBankDetails; using Company.Domain.AuthorizedBankDetailsAgg; +using CompanyManagment.App.Contracts.AuthorizedBankDetails; namespace CompanyManagment.Application { diff --git a/CompanyManagment.EFCore/Services/UidService.cs b/CompanyManagment.EFCore/Services/UidService.cs index 52e8772b..893c2c2a 100644 --- a/CompanyManagment.EFCore/Services/UidService.cs +++ b/CompanyManagment.EFCore/Services/UidService.cs @@ -10,6 +10,7 @@ using CompanyManagment.App.Contracts.AuthorizedPerson; using _0_Framework.Application; using _0_Framework.Application.UID; using Company.Application.Contracts.AuthorizedBankDetails; +using CompanyManagment.App.Contracts.AuthorizedBankDetails; namespace CompanyManagment.EFCore.Services; diff --git a/PersonalContractingParty.Config/PersonalBootstrapper.cs b/PersonalContractingParty.Config/PersonalBootstrapper.cs index 92e63a87..4765fafb 100644 --- a/PersonalContractingParty.Config/PersonalBootstrapper.cs +++ b/PersonalContractingParty.Config/PersonalBootstrapper.cs @@ -236,6 +236,7 @@ using P_TextManager.Domin.TextManagerAgg; using CompanyManagment.App.Contracts.PaymentCallback; using CompanyManagment.App.Contracts.SepehrPaymentGateway; using Company.Domain.CameraBugReportAgg; +using CompanyManagment.App.Contracts.AuthorizedBankDetails; using CompanyManagment.App.Contracts.CameraBugReport; using CameraBugReportRepository = CompanyManagement.Infrastructure.Mongo.CameraBugReportRepo.CameraBugReportRepository; using CompanyManagment.EFCore.Services; From 287b31e3568345cdeac146eb4b0cb3d6aa1b6dce Mon Sep 17 00:00:00 2001 From: mahan Date: Thu, 1 Jan 2026 12:50:34 +0330 Subject: [PATCH 2/3] refactor: improve code readability by formatting and organizing constructor parameters --- .../AccountApplication.cs | 176 ++++++++++-------- 1 file changed, 100 insertions(+), 76 deletions(-) diff --git a/AccountManagement.Application/AccountApplication.cs b/AccountManagement.Application/AccountApplication.cs index 912cd863..b1734099 100644 --- a/AccountManagement.Application/AccountApplication.cs +++ b/AccountManagement.Application/AccountApplication.cs @@ -18,7 +18,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; - using Shared.Contracts.PmUser.Commands; using Shared.Contracts.PmUser.Queries; @@ -48,7 +47,13 @@ public class AccountApplication : IAccountApplication private readonly IPmUserCommandService _pmUserCommandService; public AccountApplication(IAccountRepository accountRepository, IPasswordHasher passwordHasher, - IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker, ISmsService smsService, ICameraAccountRepository cameraAccountRepository, IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository, IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository, ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository, ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository, IUnitOfWork unitOfWork, IPmUserQueryService pmUserQueryService, IPmUserCommandService pmUserCommandService) + IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker, + ISmsService smsService, ICameraAccountRepository cameraAccountRepository, + IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository, + IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository, + ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository, + ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository, IUnitOfWork unitOfWork, + IPmUserQueryService pmUserQueryService, IPmUserCommandService pmUserCommandService) { _authHelper = authHelper; _roleRepository = roleRepository; @@ -68,7 +73,6 @@ public class AccountApplication : IAccountApplication _fileUploader = fileUploader; _passwordHasher = passwordHasher; _accountRepository = accountRepository; - } public OperationResult EditClient(EditClientAccount command) @@ -89,7 +93,8 @@ public class AccountApplication : IAccountApplication (x.Mobile == command.Mobile && x.id != command.Id))) return opreation.Failed("شماره موبایل تکراری است"); if (_accountRepository.Exists(x => - (x.NationalCode == command.NationalCode && !string.IsNullOrWhiteSpace(x.NationalCode) && x.id != command.Id))) + (x.NationalCode == command.NationalCode && !string.IsNullOrWhiteSpace(x.NationalCode) && + x.id != command.Id))) return opreation.Failed("کد ملی تکراری است"); if (_accountRepository.Exists(x => (x.Email == command.Email && !string.IsNullOrWhiteSpace(x.Email) && x.id != command.Id))) @@ -97,7 +102,8 @@ public class AccountApplication : IAccountApplication var path = $"profilePhotos"; var picturePath = _fileUploader.Upload(command.ProfilePhoto, path); - editAccount.EditClient(command.Fullname, command.Username, command.Mobile, picturePath, command.Email, command.NationalCode); + editAccount.EditClient(command.Fullname, command.Username, command.Mobile, picturePath, command.Email, + command.NationalCode); _accountRepository.SaveChanges(); return opreation.Succcedded(); } @@ -142,8 +148,8 @@ public class AccountApplication : IAccountApplication if (_fileUploader != null) { picturePath = _fileUploader.Upload(command.ProfilePhoto, path); - } + var account = new Account(command.Fullname, command.Username, password, command.Mobile, command.RoleId, picturePath, roleName.Name, "true", "false"); @@ -158,7 +164,8 @@ public class AccountApplication : IAccountApplication if (command.UserRoles == null) return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است"); var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList(); - var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname, command.Username, account.Password, command.Mobile, + var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname, command.Username, + account.Password, command.Mobile, null, account.id, pmUserRoles)); if (!createPm.isSuccess) { @@ -167,7 +174,6 @@ public class AccountApplication : IAccountApplication } - //var url = "api/user/create"; //var key = SecretKeys.ProgramManagerInternalApi; @@ -252,29 +258,30 @@ public class AccountApplication : IAccountApplication // $"api/user/{account.id}", // key //); - var userResult =await _pmUserQueryService.GetPmUserDataByAccountId(account.id); + var userResult = await _pmUserQueryService.GetPmUserDataByAccountId(account.id); if (command.UserRoles == null) return operation.Failed("حداقل یک نقش برای کاربر مدیریت پروژه لازم است"); var pmUserRoles = command.UserRoles.Where(x => x > 0).ToList(); //اگر کاربر در پروگرام منیجر قبلا ایجاد شده - if (userResult.Id >0) + if (userResult.Id > 0) { if (!command.UserRoles.Any()) { _unitOfWork.RollbackAccountContext(); return operation.Failed("حداقل یک نقش باید انتخاب شود"); } - - var editPm =await _pmUserCommandService.Edit(new EditPmUserDto(command.Fullname, command.Username, command.Mobile, account.id, pmUserRoles, + + var editPm = await _pmUserCommandService.Edit(new EditPmUserDto(command.Fullname, command.Username, + command.Mobile, account.id, pmUserRoles, command.IsProgramManagerUser)); if (!editPm.isSuccess) { _unitOfWork.RollbackAccountContext(); return operation.Failed("خطا در ویرایش کاربر پروگرام منیجر"); } - + //var parameters = new EditUserCommand( // command.Fullname, // command.Username, @@ -302,7 +309,6 @@ public class AccountApplication : IAccountApplication // _unitOfWork.RollbackAccountContext(); // return operation.Failed(response.Error); //} - } else //اگر کاربر قبلا ایجاد نشده { @@ -315,19 +321,15 @@ public class AccountApplication : IAccountApplication return operation.Failed("حداقل یک نقش باید انتخاب شود"); } - - - - - var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname, command.Username, account.Password, command.Mobile, + var createPm = await _pmUserCommandService.Create(new CreatePmUserDto(command.Fullname, + command.Username, account.Password, command.Mobile, null, account.id, pmUserRoles)); if (!createPm.isSuccess) { _unitOfWork.RollbackAccountContext(); return operation.Failed("خطا در ویرایش کاربر پروگرام منیجر"); } - //var parameters = new CreateProgramManagerUser( @@ -362,7 +364,6 @@ public class AccountApplication : IAccountApplication // return operation.Failed(response.Error); //} } - } _unitOfWork.CommitAccountContext(); @@ -376,7 +377,6 @@ public class AccountApplication : IAccountApplication public OperationResult Login(Login command) { - long idAutoriz = 0; var operation = new OperationResult(); if (string.IsNullOrWhiteSpace(command.Password)) @@ -401,21 +401,27 @@ public class AccountApplication : IAccountApplication .Select(x => x.Code) .ToList(); //PmPermission - var PmUserData = _pmUserQueryService.GetPmUserDataByAccountId(account.id).GetAwaiter().GetResult(); - if (PmUserData.AccountId > 0 && PmUserData.IsActive) + var PmUserData = _pmUserQueryService.GetPmUserDataByAccountId(account.id) + .GetAwaiter().GetResult(); + long? pmUserId = null; + if (PmUserData != null) { - - var pmUserPermissions = - PmUserData.RoleListDto != null - ? PmUserData.RoleListDto - .SelectMany(x => x.Permissions) - .Where(p => p != 99) - .Distinct() - .ToList() - : new List(); - permissions.AddRange(pmUserPermissions); + if (PmUserData.AccountId > 0 && PmUserData.IsActive) + { + var pmUserPermissions = + PmUserData.RoleListDto != null + ? PmUserData.RoleListDto + .SelectMany(x => x.Permissions) + .Where(p => p != 99) + .Distinct() + .ToList() + : new List(); + permissions.AddRange(pmUserPermissions); + } + + pmUserId = PmUserData.Id > 0 ? PmUserData.Id : null; } - + int? positionValue; if (account.PositionId != null) @@ -426,24 +432,25 @@ public class AccountApplication : IAccountApplication { positionValue = null; } - var pmUserId = PmUserData.AccountId > 0 ? PmUserData.AccountId : null; + var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname , account.Username, account.Mobile, account.ProfilePhoto, - permissions, account.RoleName, account.AdminAreaPermission, - account.ClientAriaPermission, positionValue,0,pmUserId); + permissions, account.RoleName, account.AdminAreaPermission, + account.ClientAriaPermission, positionValue, 0, pmUserId); if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" && account.IsActiveString == "true") { var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes(); authViewModel.Permissions = clientPermissions; - var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim - { - PersonnelCount = x.PersonnelCount, - Id = x.Id, - Name = x.WorkshopFullName, - Slug = _passwordHasher.SlugHasher(x.Id) - }).OrderByDescending(x => x.PersonnelCount).ToList(); + var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => + new WorkshopClaim + { + PersonnelCount = x.PersonnelCount, + Id = x.Id, + Name = x.WorkshopFullName, + Slug = _passwordHasher.SlugHasher(x.Id) + }).OrderByDescending(x => x.PersonnelCount).ToList(); authViewModel.WorkshopList = workshopList; if (workshopList.Any()) { @@ -456,10 +463,14 @@ public class AccountApplication : IAccountApplication _authHelper.Signin(authViewModel); - if ((account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" && account.IsActiveString == "true") || (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false" && account.IsActiveString == "true")) + if ((account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" && + account.IsActiveString == "true") || (account.AdminAreaPermission == "true" && + account.ClientAriaPermission == "false" && + account.IsActiveString == "true")) idAutoriz = 1; - if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" && account.IsActiveString == "true") + if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" && + account.IsActiveString == "true") idAutoriz = 2; } @@ -471,7 +482,8 @@ public class AccountApplication : IAccountApplication var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile; var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId, - cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId, cameraAccount.IsActiveSting); + cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId, + cameraAccount.IsActiveSting); if (cameraAccount.IsActiveSting == "true") { _authHelper.CameraSignIn(authViewModel); @@ -481,7 +493,6 @@ public class AccountApplication : IAccountApplication { idAutoriz = 0; } - } if (subAccount != null) @@ -511,12 +522,14 @@ public class AccountApplication : IAccountApplication authViewModel.WorkshopSlug = _passwordHasher.SlugHasher(workshop.WorkshopId); authViewModel.WorkshopId = workshop.WorkshopId; } + _authHelper.Signin(authViewModel); idAutoriz = 2; } return operation.Succcedded(idAutoriz); } + public OperationResult LoginWithMobile(long id) { var operation = new OperationResult(); @@ -525,7 +538,6 @@ public class AccountApplication : IAccountApplication return operation.Failed(ApplicationMessages.WrongUserPass); - var permissions = _roleRepository.Get(account.RoleId) .Permissions .Select(x => x.Code) @@ -541,20 +553,22 @@ public class AccountApplication : IAccountApplication } var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname - , account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, positionValue); + , account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, + account.AdminAreaPermission, account.ClientAriaPermission, positionValue); if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" && account.IsActiveString == "true") { var clientPermissions = _accountPermissionSubtitle1Repository.GetAllPermissionCodes(); authViewModel.Permissions = clientPermissions; - var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim - { - PersonnelCount = x.PersonnelCount, - Id = x.Id, - Name = x.WorkshopFullName, - Slug = _passwordHasher.SlugHasher(x.Id) - }).OrderByDescending(x => x.PersonnelCount).ToList(); + var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => + new WorkshopClaim + { + PersonnelCount = x.PersonnelCount, + Id = x.Id, + Name = x.WorkshopFullName, + Slug = _passwordHasher.SlugHasher(x.Id) + }).OrderByDescending(x => x.PersonnelCount).ToList(); authViewModel.WorkshopList = workshopList; if (workshopList.Any()) { @@ -567,13 +581,15 @@ public class AccountApplication : IAccountApplication _authHelper.Signin(authViewModel); long idAutoriz = 0; - if (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" || account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false") + if (account.AdminAreaPermission == "true" && account.ClientAriaPermission == "true" || + account.AdminAreaPermission == "true" && account.ClientAriaPermission == "false") idAutoriz = 1; if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false") idAutoriz = 2; return operation.Succcedded(idAutoriz); } + public void Logout() { _authHelper.SignOut(); @@ -609,6 +625,7 @@ public class AccountApplication : IAccountApplication _accountRepository.SaveChanges(); return operation.Succcedded(); } + public EditAccount GetByVerifyCode(string code, string phone) { return _accountRepository.GetByVerifyCode(code, phone); @@ -637,7 +654,6 @@ public class AccountApplication : IAccountApplication await _accountRepository.RemoveCode(id); return operation.Succcedded(); - } @@ -682,7 +698,6 @@ public class AccountApplication : IAccountApplication return operation.Failed("این اکانت وجود ندارد"); - var permissions = _roleRepository.Get(account.RoleId) .Permissions .Select(x => x.Code) @@ -691,7 +706,8 @@ public class AccountApplication : IAccountApplication _authHelper.SignOut(); var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname - , account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, "false", "true", null); + , account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, "false", "true", + null); var workshopList = _workshopRepository.GetWorkshopsByClientAccountId(account.id).Select(x => new WorkshopClaim { PersonnelCount = x.PersonnelCount, @@ -711,9 +727,11 @@ public class AccountApplication : IAccountApplication authViewModel.WorkshopName = workshop.Name; authViewModel.WorkshopId = workshop.Id; } + _authHelper.Signin(authViewModel); return operation.Succcedded(2); } + public OperationResult DirectCameraLogin(long cameraAccountId) { var prAcc = _authHelper.CurrentAccountInfo(); @@ -723,24 +741,22 @@ public class AccountApplication : IAccountApplication return operation.Failed("این اکانت وجود ندارد"); - - - _authHelper.SignOut(); var mobile = string.IsNullOrWhiteSpace(cameraAccount.Mobile) ? " " : cameraAccount.Mobile; var authViewModel = new CameraAuthViewModel(cameraAccount.id, cameraAccount.WorkshopId, - cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId, cameraAccount.IsActiveSting); + cameraAccount.Username, mobile, cameraAccount.WorkshopName, cameraAccount.AccountId, + cameraAccount.IsActiveSting); if (cameraAccount.IsActiveSting == "true") { _authHelper.CameraSignIn(authViewModel); - } else { return operation.Failed("این اکانت غیر فعال شده است"); } + return operation.Succcedded(2); } @@ -773,10 +789,12 @@ public class AccountApplication : IAccountApplication { return this._accountLeftworkRepository.SaveWorkshopAccount(workshopAccountList, startDate, leftDate, accountId); } + public OperationResult CreateNewWorkshopAccount(long currentAccountId, long newAccountId) { return this._accountLeftworkRepository.CopyWorkshopToNewAccount(currentAccountId, newAccountId); } + #region Mahan public List AccountsForAssign(long taskId) @@ -790,6 +808,7 @@ public class AccountApplication : IAccountApplication { return new List(); } + return _accountRepository.GetAccountsByPositionId(positionId); } @@ -807,7 +826,6 @@ public class AccountApplication : IAccountApplication return operation.Failed("این اکانت وجود ندارد"); - var permissions = _roleRepository.Get(account.RoleId) .Permissions .Select(x => x.Code) @@ -816,10 +834,10 @@ public class AccountApplication : IAccountApplication _authHelper.SignOut(); var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname - , account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, account.Position.PositionValue); + , account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, + account.AdminAreaPermission, account.ClientAriaPermission, account.Position.PositionValue); _authHelper.Signin(authViewModel); return operation.Succcedded(2); - } public async Task> GetAdminSelectList() @@ -828,8 +846,11 @@ public class AccountApplication : IAccountApplication } #endregion + #region Pooya - public OperationResult IsPhoneNumberAndPasswordValid(long accountId, string phoneNumber, string password, string rePassword) + + public OperationResult IsPhoneNumberAndPasswordValid(long accountId, string phoneNumber, string password, + string rePassword) { OperationResult op = new(); @@ -847,7 +868,8 @@ public class AccountApplication : IAccountApplication return op.Failed("رمز عبور نمی تواند کمتر از 8 کاراکتر باشد"); } - if ((string.IsNullOrWhiteSpace(phoneNumber) || entity.Mobile == phoneNumber) && string.IsNullOrWhiteSpace(rePassword)) + if ((string.IsNullOrWhiteSpace(phoneNumber) || entity.Mobile == phoneNumber) && + string.IsNullOrWhiteSpace(rePassword)) return op.Failed("چیزی برای تغییر وجود ندارد"); @@ -873,20 +895,22 @@ public class AccountApplication : IAccountApplication var entity = _accountRepository.Get(command.AccountId); if (entity == null) return op.Failed(ApplicationMessages.RecordNotFound); - var validationResult = IsPhoneNumberAndPasswordValid(command.AccountId, command.PhoneNumber, command.Password, command.RePassword); + var validationResult = IsPhoneNumberAndPasswordValid(command.AccountId, command.PhoneNumber, command.Password, + command.RePassword); if (validationResult.IsSuccedded == false) return validationResult; if (!string.IsNullOrWhiteSpace(command.RePassword)) { - entity.ChangePassword(_passwordHasher.Hash(command.Password)); } if (!string.IsNullOrWhiteSpace(command.PhoneNumber)) { - entity.Edit(entity.Fullname, entity.Username, command.PhoneNumber, entity.RoleId, entity.ProfilePhoto, entity.RoleName); + entity.Edit(entity.Fullname, entity.Username, command.PhoneNumber, entity.RoleId, entity.ProfilePhoto, + entity.RoleName); } + _accountRepository.SaveChanges(); return op.Succcedded(); } @@ -982,6 +1006,7 @@ public class AccountApplication : IAccountApplication // return claimsResponse.Failed(ApplicationMessages.WrongUserPass); //} + #endregion @@ -1024,5 +1049,4 @@ public class AccountApplication : IAccountApplication { return await _pmUserQueryService.GetPmUserDataByAccountId(accountId); } - } \ No newline at end of file From 3340edcc175e0b94e208115708ca5bfad525da51 Mon Sep 17 00:00:00 2001 From: mahan Date: Thu, 1 Jan 2026 15:41:58 +0330 Subject: [PATCH 3/3] feat: add total hours and minutes tracking to project, phase, and task calculations --- .../GetProjectsList/GetProjectListDto.cs | 2 + .../GetProjectsListQueryHandler.cs | 70 ++++++++++++------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectListDto.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectListDto.cs index 74a58946..7066148e 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectListDto.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectListDto.cs @@ -11,6 +11,8 @@ public record GetProjectListDto public bool HasFront { get; set; } public bool HasBackend { get; set; } public bool HasDesign { get; set; } + public int TotalHours { get; set; } + public int Minutes { get; set; } } 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 1815c2bc..e79b7fe4 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 @@ -53,17 +53,19 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler p.CreationDate) .ToListAsync(cancellationToken); var result = new List(); - + foreach (var project in projects) { - var percentage = await CalculateProjectPercentage(project, cancellationToken); + var (percentage, totalTime) = await CalculateProjectPercentage(project, cancellationToken); result.Add(new GetProjectListDto { Id = project.Id, Name = project.Name, Level = ProjectHierarchyLevel.Project, ParentId = null, - Percentage = percentage + Percentage = percentage, + TotalHours = (int)totalTime.TotalHours, + Minutes = totalTime.Minutes, }); } @@ -86,14 +88,16 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler CalculateProjectPercentage(Project project, CancellationToken cancellationToken) + private async Task<(int Percentage, TimeSpan TotalTime)> CalculateProjectPercentage(Project project, CancellationToken cancellationToken) { // گرفتن تمام فازهای پروژه var phases = await _context.ProjectPhases @@ -219,20 +225,24 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler(); + var totalTime = TimeSpan.Zero; + foreach (var phase in phases) { - var phasePercentage = await CalculatePhasePercentage(phase, cancellationToken); + var (phasePercentage, phaseTime) = await CalculatePhasePercentage(phase, cancellationToken); phasePercentages.Add(phasePercentage); + totalTime += phaseTime; } - return phasePercentages.Any() ? (int)phasePercentages.Average() : 0; + var averagePercentage = phasePercentages.Any() ? (int)phasePercentages.Average() : 0; + return (averagePercentage, totalTime); } - private async Task CalculatePhasePercentage(ProjectPhase phase, CancellationToken cancellationToken) + private async Task<(int Percentage, TimeSpan TotalTime)> CalculatePhasePercentage(ProjectPhase phase, CancellationToken cancellationToken) { // گرفتن تمام تسک‌های فاز var tasks = await _context.ProjectTasks @@ -240,20 +250,24 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler(); + var totalTime = TimeSpan.Zero; + foreach (var task in tasks) { - var taskPercentage = await CalculateTaskPercentage(task, cancellationToken); + var (taskPercentage, taskTime) = await CalculateTaskPercentage(task, cancellationToken); taskPercentages.Add(taskPercentage); + totalTime += taskTime; } - return taskPercentages.Any() ? (int)taskPercentages.Average() : 0; + var averagePercentage = taskPercentages.Any() ? (int)taskPercentages.Average() : 0; + return (averagePercentage, totalTime); } - private async Task CalculateTaskPercentage(ProjectTask task, CancellationToken cancellationToken) + private async Task<(int Percentage, TimeSpan TotalTime)> CalculateTaskPercentage(ProjectTask task, CancellationToken cancellationToken) { // گرفتن تمام سکشن‌های تسک با activities var sections = await _context.TaskSections @@ -262,33 +276,39 @@ public class GetProjectsListQueryHandler : IBaseQueryHandler(); + var totalTime = TimeSpan.Zero; + foreach (var section in sections) { - var sectionPercentage = CalculateSectionPercentage(section); + var (sectionPercentage, sectionTime) = CalculateSectionPercentage(section); sectionPercentages.Add(sectionPercentage); + totalTime += sectionTime; } - return sectionPercentages.Any() ? (int)sectionPercentages.Average() : 0; + var averagePercentage = sectionPercentages.Any() ? (int)sectionPercentages.Average() : 0; + return (averagePercentage, totalTime); } - private static int CalculateSectionPercentage(TaskSection section) + private static (int Percentage, TimeSpan TotalTime) CalculateSectionPercentage(TaskSection section) { // محاسبه کل زمان تخمین زده شده (اولیه + اضافی) var totalEstimatedHours = section.FinalEstimatedHours.TotalHours; - if (totalEstimatedHours <= 0) - return 0; - // محاسبه کل زمان صرف شده از activities - var totalSpentHours = section.Activities.Sum(a => a.GetTimeSpent().TotalHours); + var totalSpentTime = TimeSpan.FromHours(section.Activities.Sum(a => a.GetTimeSpent().TotalHours)); + + if (totalEstimatedHours <= 0) + return (0, section.FinalEstimatedHours); + + var totalSpentHours = totalSpentTime.TotalHours; // محاسبه درصد (حداکثر 100%) var percentage = (totalSpentHours / totalEstimatedHours) * 100; - return Math.Min((int)Math.Round(percentage), 100); + return (Math.Min((int)Math.Round(percentage), 100), section.FinalEstimatedHours); } }