From 9469a5f76ef94306f597eadc2ee6f209d2d7840d Mon Sep 17 00:00:00 2001 From: mahan Date: Sat, 13 Dec 2025 13:48:05 +0330 Subject: [PATCH] feat: introduce Shared.Contracts for account management and refactor related services --- ...untManagement.Application.Contracts.csproj | 1 + .../AccountManagementBootstrapper.cs | 3 + ...ountMangement.Infrastructure.EFCore.csproj | 2 + .../Services/AccountQueryService.cs | 49 ++++ DadmehrGostar.sln | 250 ++++++++++++++++++ ...zareshgirProgramManager.Application.csproj | 1 + .../GetUserToGroupCreatingQueryHandler.cs | 72 +++-- .../TransferSectionCommandHandler.cs | 21 +- .../ProjectBoardListQueryHandler.cs | 12 +- .../ProjectSetTimeDetailsQueryHandler.cs | 22 +- .../CreateRole/CreateRoleCommandHandler.cs | 44 --- .../EditRole/EditRoleCommandHandler.cs | 54 ---- .../Queries/GetRoles/GetRolesQueryHandler.cs | 76 ------ .../GetSalarySettingToEditQueryHandler.cs | 38 +-- .../GetUserListWhoHaveSettingsQueryHandler.cs | 65 +++-- .../Commands/CreateUser/CreateUserCommand.cs | 5 - .../CreateUser/CreateUserCommandHandler.cs | 43 --- .../CreateUser/CreateUserCommandValidators.cs | 24 -- .../EditUser/EditUserCommandHandler.cs | 34 --- .../Commands/LoginUser/LoginUserCommand.cs | 11 - .../LoginUser/LoginUserCommandHandler.cs | 98 ------- .../RefreshUserTokenCommand.cs | 11 - .../RefreshUserTokenCommandHandler.cs | 86 ------ .../SignOutUser/SignOutUserCommand.cs | 11 - .../SignOutUser/SignOutUserCommandHandler.cs | 68 ----- .../Commands/SsoLogin/SsoLoginCommand.cs | 10 - .../SsoLogin/SsoLoginCommandHandler.cs | 115 -------- .../GetSingleUserQueryHandler.cs | 124 --------- .../GetUserSelectListQueryHandler.cs | 48 ---- .../Users/Queries/GetUsers/GetUsersQuery.cs | 5 - .../Queries/GetUsers/GetUsersQueryHandler.cs | 49 ---- .../Queries/GetUsers/GetUsersResponse.cs | 46 ---- .../PermissionAgg/Entities/Permission.cs | 21 -- .../DependencyInjection.cs | 16 +- .../Context/ProgramManagerDbContext.cs | 3 - .../Mappings/RefreshTokenMapping.cs | 50 ---- .../Persistence/Mappings/RoleMapping.cs | 23 -- .../Persistence/Mappings/UserMapping.cs | 34 --- .../Repositories/RoleRepository.cs | 24 -- .../SalaryPaymentSettingRepository.cs | 58 ++-- .../UserRefreshTokenRepository.cs | 20 -- .../Repositories/UserRepository.cs | 87 ------ Query.Bootstrapper/QueryBootstrapper.cs | 1 - .../ProgramManager/AuthController.cs | 141 ---------- .../ProgramManager/RoleController.cs | 46 ---- .../ProgramManager/UserController.cs | 67 ----- ServiceHost/Program.cs | 4 +- Shared.Contracts/Account/AccountBasicDto.cs | 14 + .../Account/IAccountQueryService.cs | 25 ++ Shared.Contracts/Shared.Contracts.csproj | 10 + 50 files changed, 520 insertions(+), 1622 deletions(-) create mode 100644 AccountMangement.Infrastructure.EFCore/Services/AccountQueryService.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/CreateRole/CreateRoleCommandHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/EditRole/EditRoleCommandHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Queries/GetRoles/GetRolesQueryHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommand.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandValidators.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/EditUser/EditUserCommandHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/LoginUser/LoginUserCommand.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/LoginUser/LoginUserCommandHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/RefreshUserToken/RefreshUserTokenCommand.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/RefreshUserToken/RefreshUserTokenCommandHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SignOutUser/SignOutUserCommand.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SignOutUser/SignOutUserCommandHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SsoLogin/SsoLoginCommand.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SsoLogin/SsoLoginCommandHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetSingleUser/GetSingleUserQueryHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUserSelectList/GetUserSelectListQueryHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQuery.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQueryHandler.cs delete mode 100644 ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersResponse.cs delete mode 100644 ProgramManager/src/Domain/GozareshgirProgramManager.Domain/PermissionAgg/Entities/Permission.cs delete mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RefreshTokenMapping.cs delete mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RoleMapping.cs delete mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/UserMapping.cs delete mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/RoleRepository.cs delete mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRefreshTokenRepository.cs delete mode 100644 ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRepository.cs delete mode 100644 ServiceHost/Areas/Admin/Controllers/ProgramManager/AuthController.cs delete mode 100644 ServiceHost/Areas/Admin/Controllers/ProgramManager/RoleController.cs delete mode 100644 ServiceHost/Areas/Admin/Controllers/ProgramManager/UserController.cs create mode 100644 Shared.Contracts/Account/AccountBasicDto.cs create mode 100644 Shared.Contracts/Account/IAccountQueryService.cs create mode 100644 Shared.Contracts/Shared.Contracts.csproj diff --git a/AccountManagement.Application.Contracts/AccountManagement.Application.Contracts.csproj b/AccountManagement.Application.Contracts/AccountManagement.Application.Contracts.csproj index 393ad8f9..0e58ca5f 100644 --- a/AccountManagement.Application.Contracts/AccountManagement.Application.Contracts.csproj +++ b/AccountManagement.Application.Contracts/AccountManagement.Application.Contracts.csproj @@ -10,6 +10,7 @@ + diff --git a/AccountManagement.Configuration/AccountManagementBootstrapper.cs b/AccountManagement.Configuration/AccountManagementBootstrapper.cs index 132bf2d6..f51b7baa 100644 --- a/AccountManagement.Configuration/AccountManagementBootstrapper.cs +++ b/AccountManagement.Configuration/AccountManagementBootstrapper.cs @@ -32,9 +32,11 @@ using AccountManagement.Domain.TicketAccessAccountAgg; using AccountManagement.Domain.TicketAgg; using AccountMangement.Infrastructure.EFCore; using AccountMangement.Infrastructure.EFCore.Repository; +using AccountMangement.Infrastructure.EFCore.Services; using Company.Domain.WorkshopAccountAgg; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using Shared.Contracts.Account; using TaskManager.Application; using TaskManager.Infrastructure.EFCore.Repository; @@ -46,6 +48,7 @@ namespace AccountManagement.Configuration { services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj b/AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj index d75abbba..80362a81 100644 --- a/AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj +++ b/AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj @@ -14,8 +14,10 @@ + + diff --git a/AccountMangement.Infrastructure.EFCore/Services/AccountQueryService.cs b/AccountMangement.Infrastructure.EFCore/Services/AccountQueryService.cs new file mode 100644 index 00000000..83c4a350 --- /dev/null +++ b/AccountMangement.Infrastructure.EFCore/Services/AccountQueryService.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Shared.Contracts.Account; + +namespace AccountMangement.Infrastructure.EFCore.Services; + +public class AccountQueryService : IAccountQueryService +{ + private readonly AccountContext _accountContext; + + public AccountQueryService(AccountContext accountContext) + { + _accountContext = accountContext; + } + + public async Task GetAccountAsync(long accountId) + { + return await _accountContext.Accounts + .Where(x => x.id == accountId) + .Select(x => new AccountBasicDto + { + Id = x.id, + Username = x.Username, + Fullname = x.Fullname, + IsActive = x.IsActiveString == "true" + }) + .FirstOrDefaultAsync(); + } + + public async Task> GetProgramManagerAccountListAsync(List accountIds) + { + var ids = accountIds?.ToHashSet() ?? new HashSet(); + if (ids.Count == 0) + return []; + + return await _accountContext.Accounts + .Where(x => ids.Contains(x.id)) + .Select(x => new AccountBasicDto + { + Id = x.id, + Username = x.Username, + Fullname = x.Fullname, + IsActive = x.IsActiveString == "true" + }) + .ToListAsync(); + } +} diff --git a/DadmehrGostar.sln b/DadmehrGostar.sln index 358d6d87..d4d76d3a 100644 --- a/DadmehrGostar.sln +++ b/DadmehrGostar.sln @@ -104,128 +104,378 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GozareshgirProgramManager.D EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GozareshgirProgramManager.Infrastructure", "ProgramManager\src\Infrastructure\GozareshgirProgramManager.Infrastructure\GozareshgirProgramManager.Infrastructure.csproj", "{408281FE-615F-4CBE-BD95-2E86F5ACC6C3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.Contracts", "Shared.Contracts\Shared.Contracts.csproj", "{37F4BC4C-B620-4EFA-B4A7-A9797289E901}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Debug|x64.ActiveCfg = Debug|Any CPU + {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Debug|x64.Build.0 = Debug|Any CPU + {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Debug|x86.ActiveCfg = Debug|Any CPU + {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Debug|x86.Build.0 = Debug|Any CPU {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Release|Any CPU.ActiveCfg = Release|Any CPU {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Release|Any CPU.Build.0 = Release|Any CPU + {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Release|x64.ActiveCfg = Release|Any CPU + {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Release|x64.Build.0 = Release|Any CPU + {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Release|x86.ActiveCfg = Release|Any CPU + {CB6E0A25-B826-4EB0-80CD-D926B1A3D5D5}.Release|x86.Build.0 = Release|Any CPU {26316896-07EB-4D55-AA88-17A57EF615DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {26316896-07EB-4D55-AA88-17A57EF615DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26316896-07EB-4D55-AA88-17A57EF615DD}.Debug|x64.ActiveCfg = Debug|Any CPU + {26316896-07EB-4D55-AA88-17A57EF615DD}.Debug|x64.Build.0 = Debug|Any CPU + {26316896-07EB-4D55-AA88-17A57EF615DD}.Debug|x86.ActiveCfg = Debug|Any CPU + {26316896-07EB-4D55-AA88-17A57EF615DD}.Debug|x86.Build.0 = Debug|Any CPU {26316896-07EB-4D55-AA88-17A57EF615DD}.Release|Any CPU.ActiveCfg = Release|Any CPU {26316896-07EB-4D55-AA88-17A57EF615DD}.Release|Any CPU.Build.0 = Release|Any CPU + {26316896-07EB-4D55-AA88-17A57EF615DD}.Release|x64.ActiveCfg = Release|Any CPU + {26316896-07EB-4D55-AA88-17A57EF615DD}.Release|x64.Build.0 = Release|Any CPU + {26316896-07EB-4D55-AA88-17A57EF615DD}.Release|x86.ActiveCfg = Release|Any CPU + {26316896-07EB-4D55-AA88-17A57EF615DD}.Release|x86.Build.0 = Release|Any CPU {618761ED-3835-4C52-A91F-2240FAE39A71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {618761ED-3835-4C52-A91F-2240FAE39A71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {618761ED-3835-4C52-A91F-2240FAE39A71}.Debug|x64.ActiveCfg = Debug|Any CPU + {618761ED-3835-4C52-A91F-2240FAE39A71}.Debug|x64.Build.0 = Debug|Any CPU + {618761ED-3835-4C52-A91F-2240FAE39A71}.Debug|x86.ActiveCfg = Debug|Any CPU + {618761ED-3835-4C52-A91F-2240FAE39A71}.Debug|x86.Build.0 = Debug|Any CPU {618761ED-3835-4C52-A91F-2240FAE39A71}.Release|Any CPU.ActiveCfg = Release|Any CPU {618761ED-3835-4C52-A91F-2240FAE39A71}.Release|Any CPU.Build.0 = Release|Any CPU + {618761ED-3835-4C52-A91F-2240FAE39A71}.Release|x64.ActiveCfg = Release|Any CPU + {618761ED-3835-4C52-A91F-2240FAE39A71}.Release|x64.Build.0 = Release|Any CPU + {618761ED-3835-4C52-A91F-2240FAE39A71}.Release|x86.ActiveCfg = Release|Any CPU + {618761ED-3835-4C52-A91F-2240FAE39A71}.Release|x86.Build.0 = Release|Any CPU {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Debug|x64.ActiveCfg = Debug|Any CPU + {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Debug|x64.Build.0 = Debug|Any CPU + {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Debug|x86.ActiveCfg = Debug|Any CPU + {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Debug|x86.Build.0 = Debug|Any CPU {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Release|Any CPU.ActiveCfg = Release|Any CPU {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Release|Any CPU.Build.0 = Release|Any CPU + {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Release|x64.ActiveCfg = Release|Any CPU + {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Release|x64.Build.0 = Release|Any CPU + {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Release|x86.ActiveCfg = Release|Any CPU + {0AF931F3-B576-4B42-80EC-CD19BAD3F95F}.Release|x86.Build.0 = Release|Any CPU {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Debug|x64.ActiveCfg = Debug|Any CPU + {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Debug|x64.Build.0 = Debug|Any CPU + {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Debug|x86.ActiveCfg = Debug|Any CPU + {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Debug|x86.Build.0 = Debug|Any CPU {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Release|Any CPU.ActiveCfg = Release|Any CPU {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Release|Any CPU.Build.0 = Release|Any CPU + {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Release|x64.ActiveCfg = Release|Any CPU + {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Release|x64.Build.0 = Release|Any CPU + {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Release|x86.ActiveCfg = Release|Any CPU + {0327F97A-D526-4BD7-92A3-E5B36BB30AC5}.Release|x86.Build.0 = Release|Any CPU {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Debug|x64.ActiveCfg = Debug|Any CPU + {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Debug|x64.Build.0 = Debug|Any CPU + {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Debug|x86.ActiveCfg = Debug|Any CPU + {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Debug|x86.Build.0 = Debug|Any CPU {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Release|Any CPU.ActiveCfg = Release|Any CPU {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Release|Any CPU.Build.0 = Release|Any CPU + {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Release|x64.ActiveCfg = Release|Any CPU + {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Release|x64.Build.0 = Release|Any CPU + {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Release|x86.ActiveCfg = Release|Any CPU + {AB39F1D0-7164-489F-9524-67AEC1DF78B4}.Release|x86.Build.0 = Release|Any CPU {35B6B963-974A-4414-8609-B0668181FA64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {35B6B963-974A-4414-8609-B0668181FA64}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35B6B963-974A-4414-8609-B0668181FA64}.Debug|x64.ActiveCfg = Debug|Any CPU + {35B6B963-974A-4414-8609-B0668181FA64}.Debug|x64.Build.0 = Debug|Any CPU + {35B6B963-974A-4414-8609-B0668181FA64}.Debug|x86.ActiveCfg = Debug|Any CPU + {35B6B963-974A-4414-8609-B0668181FA64}.Debug|x86.Build.0 = Debug|Any CPU {35B6B963-974A-4414-8609-B0668181FA64}.Release|Any CPU.ActiveCfg = Release|Any CPU {35B6B963-974A-4414-8609-B0668181FA64}.Release|Any CPU.Build.0 = Release|Any CPU + {35B6B963-974A-4414-8609-B0668181FA64}.Release|x64.ActiveCfg = Release|Any CPU + {35B6B963-974A-4414-8609-B0668181FA64}.Release|x64.Build.0 = Release|Any CPU + {35B6B963-974A-4414-8609-B0668181FA64}.Release|x86.ActiveCfg = Release|Any CPU + {35B6B963-974A-4414-8609-B0668181FA64}.Release|x86.Build.0 = Release|Any CPU {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Debug|x64.ActiveCfg = Debug|Any CPU + {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Debug|x64.Build.0 = Debug|Any CPU + {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Debug|x86.ActiveCfg = Debug|Any CPU + {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Debug|x86.Build.0 = Debug|Any CPU {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Release|Any CPU.ActiveCfg = Release|Any CPU {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Release|Any CPU.Build.0 = Release|Any CPU + {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Release|x64.ActiveCfg = Release|Any CPU + {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Release|x64.Build.0 = Release|Any CPU + {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Release|x86.ActiveCfg = Release|Any CPU + {68D25B12-9F11-454B-BD3A-C96EBBC888F8}.Release|x86.Build.0 = Release|Any CPU {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Debug|x64.ActiveCfg = Debug|Any CPU + {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Debug|x64.Build.0 = Debug|Any CPU + {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Debug|x86.ActiveCfg = Debug|Any CPU + {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Debug|x86.Build.0 = Debug|Any CPU {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Release|Any CPU.ActiveCfg = Release|Any CPU {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Release|Any CPU.Build.0 = Release|Any CPU + {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Release|x64.ActiveCfg = Release|Any CPU + {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Release|x64.Build.0 = Release|Any CPU + {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Release|x86.ActiveCfg = Release|Any CPU + {C2EBA38E-5C71-4457-BA80-283FB6A848AC}.Release|x86.Build.0 = Release|Any CPU {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Debug|x64.ActiveCfg = Debug|Any CPU + {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Debug|x64.Build.0 = Debug|Any CPU + {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Debug|x86.ActiveCfg = Debug|Any CPU + {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Debug|x86.Build.0 = Debug|Any CPU {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Release|Any CPU.ActiveCfg = Release|Any CPU {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Release|Any CPU.Build.0 = Release|Any CPU + {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Release|x64.ActiveCfg = Release|Any CPU + {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Release|x64.Build.0 = Release|Any CPU + {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Release|x86.ActiveCfg = Release|Any CPU + {E2251AF9-237D-4F63-A3D4-6B9C270D0ED8}.Release|x86.Build.0 = Release|Any CPU {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Debug|x64.ActiveCfg = Debug|Any CPU + {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Debug|x64.Build.0 = Debug|Any CPU + {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Debug|x86.ActiveCfg = Debug|Any CPU + {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Debug|x86.Build.0 = Debug|Any CPU {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Release|Any CPU.ActiveCfg = Release|Any CPU {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Release|Any CPU.Build.0 = Release|Any CPU + {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Release|x64.ActiveCfg = Release|Any CPU + {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Release|x64.Build.0 = Release|Any CPU + {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Release|x86.ActiveCfg = Release|Any CPU + {1D38F80F-8400-43C2-88B3-D2A369AAF1F0}.Release|x86.Build.0 = Release|Any CPU {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Debug|x64.ActiveCfg = Debug|Any CPU + {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Debug|x64.Build.0 = Debug|Any CPU + {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Debug|x86.ActiveCfg = Debug|Any CPU + {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Debug|x86.Build.0 = Debug|Any CPU {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Release|Any CPU.ActiveCfg = Release|Any CPU {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Release|Any CPU.Build.0 = Release|Any CPU + {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Release|x64.ActiveCfg = Release|Any CPU + {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Release|x64.Build.0 = Release|Any CPU + {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Release|x86.ActiveCfg = Release|Any CPU + {55799DFE-885F-4B35-AFEE-0D0CE24E6ED9}.Release|x86.Build.0 = Release|Any CPU {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Debug|x64.ActiveCfg = Debug|Any CPU + {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Debug|x64.Build.0 = Debug|Any CPU + {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Debug|x86.ActiveCfg = Debug|Any CPU + {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Debug|x86.Build.0 = Debug|Any CPU {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Release|Any CPU.ActiveCfg = Release|Any CPU {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Release|Any CPU.Build.0 = Release|Any CPU + {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Release|x64.ActiveCfg = Release|Any CPU + {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Release|x64.Build.0 = Release|Any CPU + {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Release|x86.ActiveCfg = Release|Any CPU + {F138CA45-A2CA-4C77-B8AA-5AC6B4ECB834}.Release|x86.Build.0 = Release|Any CPU {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Debug|x64.ActiveCfg = Debug|Any CPU + {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Debug|x64.Build.0 = Debug|Any CPU + {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Debug|x86.ActiveCfg = Debug|Any CPU + {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Debug|x86.Build.0 = Debug|Any CPU {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Release|Any CPU.Build.0 = Release|Any CPU + {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Release|x64.ActiveCfg = Release|Any CPU + {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Release|x64.Build.0 = Release|Any CPU + {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Release|x86.ActiveCfg = Release|Any CPU + {5EE2EC2E-E1B5-457C-9A1F-642D2BDB4AE7}.Release|x86.Build.0 = Release|Any CPU {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Debug|x64.ActiveCfg = Debug|Any CPU + {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Debug|x64.Build.0 = Debug|Any CPU + {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Debug|x86.ActiveCfg = Debug|Any CPU + {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Debug|x86.Build.0 = Debug|Any CPU {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Release|Any CPU.ActiveCfg = Release|Any CPU {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Release|Any CPU.Build.0 = Release|Any CPU + {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Release|x64.ActiveCfg = Release|Any CPU + {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Release|x64.Build.0 = Release|Any CPU + {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Release|x86.ActiveCfg = Release|Any CPU + {BA69B1F4-2D53-4FAC-A658-FD59EB552269}.Release|x86.Build.0 = Release|Any CPU {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Debug|x64.ActiveCfg = Debug|Any CPU + {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Debug|x64.Build.0 = Debug|Any CPU + {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Debug|x86.ActiveCfg = Debug|Any CPU + {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Debug|x86.Build.0 = Debug|Any CPU {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Release|Any CPU.ActiveCfg = Release|Any CPU {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Release|Any CPU.Build.0 = Release|Any CPU + {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Release|x64.ActiveCfg = Release|Any CPU + {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Release|x64.Build.0 = Release|Any CPU + {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Release|x86.ActiveCfg = Release|Any CPU + {BA6933AF-C104-4271-ADEA-999E1BFC5A6C}.Release|x86.Build.0 = Release|Any CPU {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Debug|x64.ActiveCfg = Debug|Any CPU + {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Debug|x64.Build.0 = Debug|Any CPU + {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Debug|x86.ActiveCfg = Debug|Any CPU + {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Debug|x86.Build.0 = Debug|Any CPU {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Release|Any CPU.ActiveCfg = Release|Any CPU {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Release|Any CPU.Build.0 = Release|Any CPU + {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Release|x64.ActiveCfg = Release|Any CPU + {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Release|x64.Build.0 = Release|Any CPU + {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Release|x86.ActiveCfg = Release|Any CPU + {AFE354B3-CCDF-4810-9FFF-6F10B49757B8}.Release|x86.Build.0 = Release|Any CPU {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Debug|x64.ActiveCfg = Debug|Any CPU + {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Debug|x64.Build.0 = Debug|Any CPU + {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Debug|x86.ActiveCfg = Debug|Any CPU + {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Debug|x86.Build.0 = Debug|Any CPU {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Release|Any CPU.ActiveCfg = Release|Any CPU {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Release|Any CPU.Build.0 = Release|Any CPU + {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Release|x64.ActiveCfg = Release|Any CPU + {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Release|x64.Build.0 = Release|Any CPU + {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Release|x86.ActiveCfg = Release|Any CPU + {9643E1D4-A2FE-4CA1-A303-1A499CDB6D87}.Release|x86.Build.0 = Release|Any CPU {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Debug|x64.ActiveCfg = Debug|Any CPU + {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Debug|x64.Build.0 = Debug|Any CPU + {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Debug|x86.ActiveCfg = Debug|Any CPU + {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Debug|x86.Build.0 = Debug|Any CPU {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Release|Any CPU.ActiveCfg = Release|Any CPU {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Release|Any CPU.Build.0 = Release|Any CPU + {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Release|x64.ActiveCfg = Release|Any CPU + {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Release|x64.Build.0 = Release|Any CPU + {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Release|x86.ActiveCfg = Release|Any CPU + {3CDCCA2F-79F1-43FD-B9C4-211279624148}.Release|x86.Build.0 = Release|Any CPU {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Debug|x64.ActiveCfg = Debug|Any CPU + {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Debug|x64.Build.0 = Debug|Any CPU + {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Debug|x86.ActiveCfg = Debug|Any CPU + {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Debug|x86.Build.0 = Debug|Any CPU {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Release|Any CPU.ActiveCfg = Release|Any CPU {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Release|Any CPU.Build.0 = Release|Any CPU + {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Release|x64.ActiveCfg = Release|Any CPU + {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Release|x64.Build.0 = Release|Any CPU + {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Release|x86.ActiveCfg = Release|Any CPU + {0E6A32F1-1BCB-45A1-BB1A-A5B8AFA8F551}.Release|x86.Build.0 = Release|Any CPU {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Debug|x64.ActiveCfg = Debug|Any CPU + {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Debug|x64.Build.0 = Debug|Any CPU + {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Debug|x86.ActiveCfg = Debug|Any CPU + {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Debug|x86.Build.0 = Debug|Any CPU {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Release|Any CPU.ActiveCfg = Release|Any CPU {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Release|Any CPU.Build.0 = Release|Any CPU + {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Release|x64.ActiveCfg = Release|Any CPU + {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Release|x64.Build.0 = Release|Any CPU + {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Release|x86.ActiveCfg = Release|Any CPU + {339E05B6-E99F-4403-AFDF-CD0540E96C8D}.Release|x86.Build.0 = Release|Any CPU {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Debug|x64.ActiveCfg = Debug|Any CPU + {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Debug|x64.Build.0 = Debug|Any CPU + {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Debug|x86.ActiveCfg = Debug|Any CPU + {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Debug|x86.Build.0 = Debug|Any CPU {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Release|Any CPU.ActiveCfg = Release|Any CPU {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Release|Any CPU.Build.0 = Release|Any CPU + {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Release|x64.ActiveCfg = Release|Any CPU + {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Release|x64.Build.0 = Release|Any CPU + {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Release|x86.ActiveCfg = Release|Any CPU + {02892882-2A02-484B-BAF9-7E63F6BDCFA0}.Release|x86.Build.0 = Release|Any CPU {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Debug|x64.ActiveCfg = Debug|Any CPU + {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Debug|x64.Build.0 = Debug|Any CPU + {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Debug|x86.ActiveCfg = Debug|Any CPU + {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Debug|x86.Build.0 = Debug|Any CPU {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Release|Any CPU.ActiveCfg = Release|Any CPU {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Release|Any CPU.Build.0 = Release|Any CPU + {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Release|x64.ActiveCfg = Release|Any CPU + {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Release|x64.Build.0 = Release|Any CPU + {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Release|x86.ActiveCfg = Release|Any CPU + {BF98173C-42AF-4897-A7CB-4CACEB2B52A2}.Release|x86.Build.0 = Release|Any CPU {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Debug|x64.ActiveCfg = Debug|Any CPU + {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Debug|x64.Build.0 = Debug|Any CPU + {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Debug|x86.ActiveCfg = Debug|Any CPU + {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Debug|x86.Build.0 = Debug|Any CPU {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Release|Any CPU.ActiveCfg = Release|Any CPU {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Release|Any CPU.Build.0 = Release|Any CPU + {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Release|x64.ActiveCfg = Release|Any CPU + {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Release|x64.Build.0 = Release|Any CPU + {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Release|x86.ActiveCfg = Release|Any CPU + {97E148FA-3C36-40DD-B121-D90C1C0F3B47}.Release|x86.Build.0 = Release|Any CPU {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Debug|x64.ActiveCfg = Debug|Any CPU + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Debug|x64.Build.0 = Debug|Any CPU + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Debug|x86.ActiveCfg = Debug|Any CPU + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Debug|x86.Build.0 = Debug|Any CPU {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Release|Any CPU.ActiveCfg = Release|Any CPU {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Release|Any CPU.Build.0 = Release|Any CPU + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Release|x64.ActiveCfg = Release|Any CPU + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Release|x64.Build.0 = Release|Any CPU + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Release|x86.ActiveCfg = Release|Any CPU + {4CDAA60E-C7DD-4883-85CC-E7E26CCC6ED3}.Release|x86.Build.0 = Release|Any CPU {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|x64.ActiveCfg = Debug|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|x64.Build.0 = Debug|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|x86.ActiveCfg = Debug|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|x86.Build.0 = Debug|Any CPU {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|Any CPU.ActiveCfg = Release|Any CPU {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|Any CPU.Build.0 = Release|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|x64.ActiveCfg = Release|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|x64.Build.0 = Release|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|x86.ActiveCfg = Release|Any CPU + {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|x86.Build.0 = Release|Any CPU {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Debug|x64.ActiveCfg = Debug|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Debug|x64.Build.0 = Debug|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Debug|x86.ActiveCfg = Debug|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Debug|x86.Build.0 = Debug|Any CPU {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Release|Any CPU.ActiveCfg = Release|Any CPU {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Release|Any CPU.Build.0 = Release|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Release|x64.ActiveCfg = Release|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Release|x64.Build.0 = Release|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Release|x86.ActiveCfg = Release|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Release|x86.Build.0 = Release|Any CPU {D2B4F1D7-6336-4B30-910C-219F4119303F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D2B4F1D7-6336-4B30-910C-219F4119303F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Debug|x64.ActiveCfg = Debug|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Debug|x64.Build.0 = Debug|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Debug|x86.ActiveCfg = Debug|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Debug|x86.Build.0 = Debug|Any CPU {D2B4F1D7-6336-4B30-910C-219F4119303F}.Release|Any CPU.ActiveCfg = Release|Any CPU {D2B4F1D7-6336-4B30-910C-219F4119303F}.Release|Any CPU.Build.0 = Release|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Release|x64.ActiveCfg = Release|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Release|x64.Build.0 = Release|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Release|x86.ActiveCfg = Release|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Release|x86.Build.0 = Release|Any CPU {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Debug|x64.ActiveCfg = Debug|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Debug|x64.Build.0 = Debug|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Debug|x86.ActiveCfg = Debug|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Debug|x86.Build.0 = Debug|Any CPU {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Release|Any CPU.ActiveCfg = Release|Any CPU {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Release|Any CPU.Build.0 = Release|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Release|x64.ActiveCfg = Release|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Release|x64.Build.0 = Release|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Release|x86.ActiveCfg = Release|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Release|x86.Build.0 = Release|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Debug|x64.ActiveCfg = Debug|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Debug|x64.Build.0 = Debug|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Debug|x86.ActiveCfg = Debug|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Debug|x86.Build.0 = Debug|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Release|Any CPU.Build.0 = Release|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Release|x64.ActiveCfg = Release|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Release|x64.Build.0 = Release|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Release|x86.ActiveCfg = Release|Any CPU + {37F4BC4C-B620-4EFA-B4A7-A9797289E901}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj index 7bd51642..40b5a7bb 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj @@ -14,6 +14,7 @@ + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetUserToGropCreate/GetUserToGroupCreatingQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetUserToGropCreate/GetUserToGroupCreatingQueryHandler.cs index c98b88e9..f7b3d82d 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetUserToGropCreate/GetUserToGroupCreatingQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetUserToGropCreate/GetUserToGroupCreatingQueryHandler.cs @@ -5,6 +5,7 @@ using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.CheckoutAgg.Enums; using Microsoft.EntityFrameworkCore; using PersianTools.Core; +using Shared.Contracts.Account; namespace GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetUserToGropCreate; @@ -14,12 +15,14 @@ namespace GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetUse public class GetUserToGroupCreatingQueryHandler : IBaseQueryHandler { private readonly IProgramManagerDbContext _context; - private readonly IGozareshgirDbContext _gozareshgirDbContext; + private readonly IAccountQueryService _accountQueryService; - public GetUserToGroupCreatingQueryHandler(IProgramManagerDbContext context, IGozareshgirDbContext gozareshgirDbContext) + public GetUserToGroupCreatingQueryHandler( + IProgramManagerDbContext context, + IAccountQueryService accountQueryService) { _context = context; - _gozareshgirDbContext = gozareshgirDbContext; + _accountQueryService = accountQueryService; } public async Task> Handle(GetUserToGroupCreatingQuery request, CancellationToken cancellationToken) @@ -50,35 +53,46 @@ public class GetUserToGroupCreatingQueryHandler : IBaseQueryHandler x.CheckoutStartDate < lastMonthStart + && x.CheckoutEndDate >= lastMonthStart) + on s.AccountId equals ch.UserId into chJoin + from ch in chJoin.DefaultIfEmpty() - // LEFT JOIN - // تنظیمات حقوق - join s in _context.SalaryPaymentSettings - on u.Id equals s.AccountId into sJoin - from s in sJoin.DefaultIfEmpty() + select new + { + AccountId = s.AccountId, + HasCheckout = ch != null + }) + .GroupBy(x => x.AccountId) + .Select(g => new + { + AccountId = g.Key, + HasCheckout = g.Any(x => x.HasCheckout) + }) + .ToListAsync(cancellationToken); - // LEFT JOIN - //فیش - join ch in _context.Checkouts - .Where(x => x.CheckoutStartDate < lastMonthStart - && x.CheckoutEndDate >= lastMonthStart) - on u.Id equals ch.UserId into chJoin - from ch in chJoin.DefaultIfEmpty() + // دریافت اطلاعات Account ها از AccountManagement + var accountIds = settingsAndCheckouts.Select(x => x.AccountId).Distinct().ToList(); + var accounts = await _accountQueryService.GetProgramManagerAccountListAsync(accountIds); + var accountsDict = accounts.ToDictionary(a => a.Id); - group new { s, ch } by new { u.Id, u.FullName } into g - - select new GetUserWhoHaveSettingsAndCheckoutDto - { - UserId = g.Key.Id, - FullName = g.Key.FullName, - - HasSalarySettings = g.Any(x => x.s != null), - HasCheckout = g.Any(x => x.ch != null) - }) - .ToListAsync(cancellationToken); + // ترکیب داده‌ها + var query = settingsAndCheckouts + .Where(x => accountsDict.ContainsKey(x.AccountId)) + .Select(x => new GetUserWhoHaveSettingsAndCheckoutDto + { + UserId = x.AccountId, + FullName = accountsDict[x.AccountId].Fullname, + HasSalarySettings = true, // چون از SalaryPaymentSettings اومده پس حتماً تنظیمات داره + HasCheckout = x.HasCheckout + }) + .ToList(); diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandHandler.cs index 4f27773a..91bdbc8a 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandHandler.cs @@ -2,7 +2,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; -using GozareshgirProgramManager.Domain.UserAgg.Repositories; +using Shared.Contracts.Account; namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.TransferSection; @@ -10,15 +10,15 @@ public class TransferSectionCommandHandler : IBaseCommandHandler>> Handle(ProjectBoardListQuery request, @@ -30,10 +33,9 @@ public class ProjectBoardListQueryHandler : IBaseQueryHandler x.Activities).Select(a => a.UserId).Distinct().ToList(); - var users = await _programManagerDbContext.Users.AsNoTracking() - .Where(x => activityUserIds.Contains(x.Id)) - .Select(x => new { x.Id, x.FullName }) - .ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken); + // Fetch account basics in batch and map to FullName + var accounts = await _accountQueryService.GetProgramManagerAccountListAsync(activityUserIds); + var users = accounts.ToDictionary(a => a.Id, a => a.Fullname); var result = data.Select(x => { diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryHandler.cs index f99f3370..e2084f20 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryHandler.cs @@ -1,11 +1,9 @@ -using DNTPersianUtils.Core; -using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; -using GozareshgirProgramManager.Application.Modules.Projects.DTOs; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; +using Shared.Contracts.Account; namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; @@ -14,10 +12,12 @@ public class ProjectSetTimeDetailsQueryHandler : IBaseQueryHandler { private readonly IProgramManagerDbContext _context; + private readonly IAccountQueryService _accountQueryService; - public ProjectSetTimeDetailsQueryHandler(IProgramManagerDbContext context) + public ProjectSetTimeDetailsQueryHandler(IProgramManagerDbContext context, IAccountQueryService accountQueryService) { _context = context; + _accountQueryService = accountQueryService; } public async Task> Handle(ProjectSetTimeDetailsQuery request, @@ -36,10 +36,10 @@ public class ProjectSetTimeDetailsQueryHandler var userIds = task.Sections.Select(x => x.OriginalAssignedUserId) .Distinct().ToList(); - var users = await _context.Users - .Where(x => userIds.Contains(x.Id)) - .AsNoTracking() - .ToListAsync(cancellationToken); + // Fetch account basics in batch (instead of _context.Users) + var accounts = await _accountQueryService.GetProgramManagerAccountListAsync(userIds); + var accountDict = accounts.ToDictionary(a => a.Id); + var skillIds = task.Sections.Select(x => x.SkillId) .Distinct().ToList(); @@ -51,8 +51,8 @@ public class ProjectSetTimeDetailsQueryHandler var res = new ProjectSetTimeResponse( task.Sections.Select(ts => { - var user = users.FirstOrDefault(x => x.Id == ts.OriginalAssignedUserId); var skill = skills.FirstOrDefault(x => x.Id == ts.SkillId); + var account = accountDict.GetValueOrDefault(ts.OriginalAssignedUserId); return new ProjectSetTimeResponseSections { AdditionalTimes = ts.AdditionalTimes @@ -65,7 +65,7 @@ public class ProjectSetTimeDetailsQueryHandler SkillName = skill?.Name ?? "", TotalAdditionalTime = (int)ts.GetTotalAdditionalTime().TotalHours, TotalEstimateTime = (int)ts.FinalEstimatedHours.TotalHours, - UserName = user?.UserName ?? "", + UserName = account?.Username ?? "", SectionId = ts.Id, InitialDescription = ts.InitialDescription ?? "", InitialTime = (int)ts.InitialEstimatedHours.TotalHours diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/CreateRole/CreateRoleCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/CreateRole/CreateRoleCommandHandler.cs deleted file mode 100644 index c5ef5b2c..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/CreateRole/CreateRoleCommandHandler.cs +++ /dev/null @@ -1,44 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain._Common; -using GozareshgirProgramManager.Domain.PermissionAgg.Entities; -using GozareshgirProgramManager.Domain.RoleAgg.Entities; -using GozareshgirProgramManager.Domain.RoleAgg.Repositories; - -namespace GozareshgirProgramManager.Application.Modules.Roles.Commands.CreateRole; - -public class CreateRoleCommandHandler : IBaseCommandHandler -{ - private readonly IRoleRepository _roleRepository; - private readonly IUnitOfWork _unitOfWork; - - public CreateRoleCommandHandler(IRoleRepository roleRepository, IUnitOfWork unitOfWork) - { - _roleRepository = roleRepository; - _unitOfWork = unitOfWork; - } - - public async Task Handle(CreateRoleCommand request, CancellationToken cancellationToken) - { - - if(string.IsNullOrWhiteSpace(request.RoleName)) - return OperationResult.Failure("نام نقش خالی است"); - if(!request.Permissions.Any()) - return OperationResult.Failure("هیچ دسترسی داده نشده است"); - var permissions = request.Permissions.Where(x => x > 0).Select(x => new Permission(x)).ToList(); - - var role = new Role(request.RoleName, request.GozareshgirRoleId, permissions); - await _roleRepository.CreateAsync(role); - await _unitOfWork.SaveChangesAsync(); - return OperationResult.Success(); - } -} - - -public record CreateRoleCommand : IBaseCommand -{ - public string RoleName { get; set; } - public List Permissions { get; set; } - - public long? GozareshgirRoleId { get; set; } -} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/EditRole/EditRoleCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/EditRole/EditRoleCommandHandler.cs deleted file mode 100644 index 36e50fbb..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/EditRole/EditRoleCommandHandler.cs +++ /dev/null @@ -1,54 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain._Common; -using GozareshgirProgramManager.Domain.PermissionAgg.Entities; -using GozareshgirProgramManager.Domain.RoleAgg.Repositories; - -namespace GozareshgirProgramManager.Application.Modules.Roles.Commands.EditRole; - -public class EditRoleCommandHandler : IBaseCommandHandler -{ - private readonly IRoleRepository _roleRepository; - private readonly IUnitOfWork _unitOfWork; - - public EditRoleCommandHandler(IRoleRepository roleRepository, IUnitOfWork unitOfWork) - { - _roleRepository = roleRepository; - _unitOfWork = unitOfWork; - } - - public async Task Handle(EditRoleCommand request, CancellationToken cancellationToken) - { - if (_roleRepository.Exists(x => x.RoleName == request.RoleName && x.GozareshgirRoleId != request.GozareshgirRoleId)) - return OperationResult.Failure("نام نقش تکراری است"); - - if (string.IsNullOrWhiteSpace(request.RoleName)) - return OperationResult.Failure("نام نقش خالی است"); - - if(request.GozareshgirRoleId == null || request.GozareshgirRoleId == 0) - return OperationResult.Failure("آی دی نقش از سمت گزارشگیر خالی است"); - - var permissions = request.Permissions.Where(x => x > 0).Select(x => new Permission(x)).ToList(); - - - var role =await _roleRepository.GetByGozareshgirRoleIdAsync(request.GozareshgirRoleId); - - if (role != null) - { - role?.Edit(request.RoleName, permissions); - - await _unitOfWork.SaveChangesAsync(); - } - - return OperationResult.Success(); - - } -} - -public record EditRoleCommand : IBaseCommand -{ - public string RoleName { get; set; } - public List Permissions { get; set; } - - public long? GozareshgirRoleId { get; set; } -} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Queries/GetRoles/GetRolesQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Queries/GetRoles/GetRolesQueryHandler.cs deleted file mode 100644 index bcdb5fe1..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Queries/GetRoles/GetRolesQueryHandler.cs +++ /dev/null @@ -1,76 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Application.Modules.Roles.Queries.GetRoles; - -public class GetRolesQueryHandler : IBaseQueryHandler -{ - private readonly IProgramManagerDbContext _context; - - public GetRolesQueryHandler(IProgramManagerDbContext context) - { - _context = context; - } - - public async Task> Handle(GetRolesQuery request, CancellationToken cancellationToken) - { - var query = _context.Roles.AsQueryable(); - - if (!string.IsNullOrWhiteSpace(request.RoleName)) - query = query.Where(x => x.RoleName.Contains(request.RoleName)); - if (request.GozareshgirRoleId > 0) - query = query.Where(x => x.GozareshgirRoleId == request.GozareshgirRoleId); - - var roles = await query - .Select(p => new GetRolesDto() - { - Id = p.Id, - RoleName = p.RoleName, - GozareshgirRoleId = p.GozareshgirRoleId, - Permissions = p.Permissions.Select(x=>x.Code).ToList() - - }) - .ToListAsync(cancellationToken); - if(!roles.Any()) - return OperationResult.NotFound("یافت نشد"); - - var response = new GetRolesResponse( - roles - ); - - return OperationResult.Success(response); - - } -} - - -public record GetRolesQuery(string? RoleName, long? GozareshgirRoleId) : IBaseQuery; - -public record GetRolesResponse(List Role); - -public record GetRolesDto -{ - /// - /// آی دی نقش - /// - public long Id { get; set; } - - /// - /// نام نقش - /// - public string RoleName { get; set; } - - /// - /// آی دی نقش در گزارشگیر - /// - public long? GozareshgirRoleId { get; set; } - - /// - /// لیست کدهای دسترسی - /// - public List Permissions { get; set; } - - -} - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetSalarySettingToEdit/GetSalarySettingToEditQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetSalarySettingToEdit/GetSalarySettingToEditQueryHandler.cs index 1fe869c7..080fcef6 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetSalarySettingToEdit/GetSalarySettingToEditQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetSalarySettingToEdit/GetSalarySettingToEditQueryHandler.cs @@ -3,60 +3,66 @@ using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Commands.CreateSalarySettings; using GozareshgirProgramManager.Domain._Common; using Microsoft.EntityFrameworkCore; -using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; +using Shared.Contracts.Account; namespace GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetSalarySettingToEdit; public class GetSalarySettingToEditQueryHandler : IBaseQueryHandler { private readonly IProgramManagerDbContext _context; + private readonly IAccountQueryService _accountQueryService; - public GetSalarySettingToEditQueryHandler(IProgramManagerDbContext context) + public GetSalarySettingToEditQueryHandler(IProgramManagerDbContext context, IAccountQueryService accountQueryService) { _context = context; + _accountQueryService = accountQueryService; } public async Task> Handle(GetSalarySettingToEditQuery request, CancellationToken cancellationToken) { - var user =await _context.Users.FirstOrDefaultAsync(x => x.Id == request.UserId); - if(user == null) + // دریافت اطلاعات حساب از AccountManagement + var account = await _accountQueryService.GetAccountAsync(request.UserId); + if (account == null) return OperationResult.NotFound("کاربر یافت نشد"); var editSalarySettingsList = await _context.SalaryPaymentSettings + .Where(x => x.AccountId == request.UserId) .Select(x => new GetSalarySettingToEdit() { Id = x.Id, HolidayWorking = x.HolidayWorking, UserId = x.AccountId, MonthlySalary = x.MonthlySalary.ToMoney(), - WorkingHoursList = x.WorkingHoursList.Select(wh => new WorkingHoursListDto { - StartShiftOne =wh.HasShiftOne ? wh.StartShiftOne.ToString(@"hh\:mm") : null, + StartShiftOne = wh.HasShiftOne ? wh.StartShiftOne.ToString(@"hh\:mm") : null, EndShiftOne = wh.HasShiftOne ? wh.EndShiftOne.ToString(@"hh\:mm") : null, StartShiftTwo = wh.HasShiftTow ? wh.StartShiftTwo.ToString(@"hh\:mm") : null, - EndShiftTwo = wh.HasShiftTow ? wh.EndShiftTwo.ToString(@"hh\:mm") :null, + EndShiftTwo = wh.HasShiftTow ? wh.EndShiftTwo.ToString(@"hh\:mm") : null, RestTime = wh.HasRestTime ? wh.RestTime.ToString(@"hh\:mm") : null, HasRestTime = wh.HasRestTime, HasShiftOne = wh.HasShiftOne, HasShiftTow = wh.HasShiftTow, PersianDayOfWeek = wh.PersianDayOfWeek, IsActiveDay = wh.IsActiveDay - }).OrderBy(wh=>wh.PersianDayOfWeek).ToList(), + }).OrderBy(wh => wh.PersianDayOfWeek).ToList(), - }).FirstOrDefaultAsync(x => x.UserId == request.UserId); + }).FirstOrDefaultAsync(cancellationToken); - var response = new GetSalarySettingToEditResponse(request.UserId,user.FullName,editSalarySettingsList); + if (editSalarySettingsList == null) + { + return OperationResult.NotFound("تنظیمات مورد نظر یافت نشد"); + } + + var response = new GetSalarySettingToEditResponse(request.UserId, account.Fullname, editSalarySettingsList); return OperationResult.Success(response); - } } public record GetSalarySettingToEditResponse(long UserId, string FullName, GetSalarySettingToEdit EditSalarySettingsList); -public record GetSalarySettingToEditQuery(long UserId) :IBaseQuery; - +public record GetSalarySettingToEditQuery(long UserId) : IBaseQuery; public record GetSalarySettingToEdit { @@ -77,12 +83,10 @@ public record GetSalarySettingToEdit /// /// حقوق ماهانه /// - public string MonthlySalary { get; set; } + public string MonthlySalary { get; set; } = string.Empty; /// /// لیست روزهای هفته و ساعات کاری /// - public List WorkingHoursList { get; set; } + public List WorkingHoursList { get; set; } = new(); } - - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetUserListWhoHaveSettings/GetUserListWhoHaveSettingsQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetUserListWhoHaveSettings/GetUserListWhoHaveSettingsQueryHandler.cs index 05fd3674..ea2192df 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetUserListWhoHaveSettings/GetUserListWhoHaveSettingsQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetUserListWhoHaveSettings/GetUserListWhoHaveSettingsQueryHandler.cs @@ -4,62 +4,71 @@ using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; using Microsoft.EntityFrameworkCore; +using Shared.Contracts.Account; namespace GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetUserListWhoHaveSettings; public class GetUserListWhoHaveSettingsQueryHandler : IBaseQueryHandler { private readonly IProgramManagerDbContext _context; + private readonly IAccountQueryService _accountQueryService; - public GetUserListWhoHaveSettingsQueryHandler(IProgramManagerDbContext context) + public GetUserListWhoHaveSettingsQueryHandler(IProgramManagerDbContext context, IAccountQueryService accountQueryService) { _context = context; + _accountQueryService = accountQueryService; } public async Task> Handle(GetUserListWhoHaveSettingsQuery request, CancellationToken cancellationToken) { - var query = await ( - from u in _context.Users - join s in _context.SalaryPaymentSettings - on u.Id equals s.AccountId into settingsGroup - select new GetUserWhoHaveSettingsDto + // Get all salary settings + var allSettings = await _context.SalaryPaymentSettings.ToListAsync(cancellationToken); + + // Get all unique account IDs + var accountIds = allSettings.Select(s => s.AccountId).Distinct().ToList(); + + // Get all user data in one batch through AccountQueryService + var accounts = await _accountQueryService.GetProgramManagerAccountListAsync(accountIds); + var accountDictionary = accounts.ToDictionary(a => a.Id, a => a); + + // Map settings to DTOs + var userSettingsQuery = allSettings + .Where(setting => accountDictionary.ContainsKey(setting.AccountId)) + .Select(setting => { - UserId = u.Id, - FullName = u.FullName, - HasSalarySettings = settingsGroup.Any(), - MontlySalary = settingsGroup.Any() ? settingsGroup.FirstOrDefault().MonthlySalary.ToMoney() : "", - WeeklyWorkingTimeAvrageInt = settingsGroup - .SelectMany(x => x.WorkingHoursList) - .Sum(w => (int?)w.ShiftDurationInMinutes) ?? 0 - } - ).ToListAsync(cancellationToken); + var userBasic = accountDictionary[setting.AccountId]; + return new GetUserWhoHaveSettingsDto + { + UserId = userBasic.Id, + FullName = userBasic.Fullname, + HasSalarySettings = true, + MontlySalary = setting.MonthlySalary.ToMoney(), + WeeklyWorkingTimeAvrageInt = setting.WorkingHoursList?.Sum(w => (int?)w.ShiftDurationInMinutes) ?? 0 + }; + }) + .ToList(); + + var list = userSettingsQuery; if (!string.IsNullOrWhiteSpace(request.FullName)) - query = query.Where(x => x.FullName.Contains(request.FullName)).ToList(); + list = list.Where(x => x.FullName.Contains(request.FullName)).ToList(); if (request.HasSalarySettings != HasSalarySettings.Default) { bool hasSettings = request.HasSalarySettings == HasSalarySettings.HasSettings; - query = query.Where(x => x.HasSalarySettings == hasSettings).ToList(); + list = list.Where(x => x.HasSalarySettings == hasSettings).ToList(); } - - var operationQuery = query.Select(user => + + var operationQuery = list.Select(user => { var weeklyWorkingTimeAvrage = user.WeeklyWorkingTimeAvrageInt.ConvertIntDurationToHoursAndMinutes(); - return new GetUserWhoHaveSettingsDto - { - UserId = user.UserId, - FullName = user.FullName, - HasSalarySettings = user.HasSalarySettings, - MontlySalary = user.MontlySalary, - WeeklyWorkingTimeAvrageInt = user.WeeklyWorkingTimeAvrageInt, - WeeklyWorkingTimeAvrage = weeklyWorkingTimeAvrage - }; + return user with { WeeklyWorkingTimeAvrage = weeklyWorkingTimeAvrage }; }).ToList(); + var response = new GetUserListWhoHaveSettingsResponse(operationQuery); return OperationResult.Success(response); diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommand.cs deleted file mode 100644 index 4eba06a0..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommand.cs +++ /dev/null @@ -1,5 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; - -public record CreateUserCommand(string FullName, string UserName, string Password, string Mobile, string? Email, long? AccountId, List Roles) : IBaseCommand; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandHandler.cs deleted file mode 100644 index 535697b3..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandHandler.cs +++ /dev/null @@ -1,43 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain._Common; -using GozareshgirProgramManager.Domain.RoleUserAgg; -using GozareshgirProgramManager.Domain.UserAgg.Entities; -using GozareshgirProgramManager.Domain.UserAgg.Repositories; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; - -public class CreateUserCommandHandler : IBaseCommandHandler -{ - private readonly IUserRepository _userRepository; - private readonly IUnitOfWork _unitOfWork; - - public CreateUserCommandHandler(IUnitOfWork unitOfWork, IUserRepository userRepository) - { - _unitOfWork = unitOfWork; - _userRepository = userRepository; - } - - public async Task Handle(CreateUserCommand request, CancellationToken cancellationToken) - { - - #region CustomValidation - if (_userRepository.Exists(x => x.FullName == request.FullName)) - return OperationResult.Failure("نام و خانوادگی تکراری است"); - if (_userRepository.Exists(x => x.UserName == request.UserName)) - return OperationResult.Failure("نام کاربری تکراری است"); - if (_userRepository.Exists(x=> !string.IsNullOrWhiteSpace(x.Mobile) && x.Mobile == request.Mobile)) - return OperationResult.ValidationError("این شماره همراه قبلا به فرد دیگری اختصاص داده شده است"); - if(request.AccountId == 0) - return OperationResult.Failure("آی دی اکانت، از سمت گزارشگیر صفر است"); - #endregion - - var userRoles = request.Roles.Where(x => x > 0).Select(x => new RoleUser(x)).ToList() ; - var create = new User(request.FullName, request.UserName, request.Password, request.Mobile, - request.Email, request?.AccountId, userRoles); - - await _userRepository.CreateAsync(create); - await _unitOfWork.SaveChangesAsync(cancellationToken); - return OperationResult.Success(); - } -} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandValidators.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandValidators.cs deleted file mode 100644 index 68f9f1a7..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandValidators.cs +++ /dev/null @@ -1,24 +0,0 @@ -using FluentValidation; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; - -public class CreateUserCommandValidators : AbstractValidator -{ - public CreateUserCommandValidators() - { - RuleFor(x => x.FullName) - .NotEmpty() - .NotNull() - .WithMessage("نام و نام خانوادگی نمی تواند خالی باشد"); - - RuleFor(x => x.Mobile) - .NotNull().NotEmpty().WithMessage("شماره همراه نمی تواند خالی باشد"); - RuleFor(x=>x.Mobile) - .Length(11).WithMessage("طول شماره همراه می بایست 11 رقم باشد"); - RuleFor(x => x.UserName) - .NotEmpty().NotNull().WithMessage("نام کاربری نمیتوان خالی باشد"); - - - - } -} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/EditUser/EditUserCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/EditUser/EditUserCommandHandler.cs deleted file mode 100644 index 1920f1fb..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/EditUser/EditUserCommandHandler.cs +++ /dev/null @@ -1,34 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain._Common; -using GozareshgirProgramManager.Domain.RoleUserAgg; -using GozareshgirProgramManager.Domain.UserAgg.Repositories; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.EditUser; - -public class EditUserCommandHandler :IBaseCommandHandler -{ - private readonly IUserRepository _userRepository; - private readonly IUnitOfWork _unitOfWork; - - public EditUserCommandHandler(IUserRepository userRepository, IUnitOfWork unitOfWork) - { - _userRepository = userRepository; - _unitOfWork = unitOfWork; - } - - public async Task Handle(EditUserCommand request, CancellationToken cancellationToken) - { - var user = await _userRepository.GetByGozareshgirAccountId(request.AccountId); - if (user != null) - { - var userRoles = request.Roles.Where(x => x > 0).Select(x => new RoleUser(x)).ToList(); - user.Edit(request.FullName, request.UserName, request.Mobile, userRoles, request.IsActive); - await _unitOfWork.SaveChangesAsync(); - } - - return OperationResult.Success(); - } -} - -public record EditUserCommand(string FullName, string UserName, string Mobile,long AccountId, List Roles, bool IsActive) : IBaseCommand; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/LoginUser/LoginUserCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/LoginUser/LoginUserCommand.cs deleted file mode 100644 index 80d51cb2..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/LoginUser/LoginUserCommand.cs +++ /dev/null @@ -1,11 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using MediatR; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.LoginUser; - -/// -/// دستور ورود کاربر به سیستم -/// -public record LoginUserCommand(long UserId) : IBaseCommand; - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/LoginUser/LoginUserCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/LoginUser/LoginUserCommandHandler.cs deleted file mode 100644 index cb284fd0..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/LoginUser/LoginUserCommandHandler.cs +++ /dev/null @@ -1,98 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain._Common; -using GozareshgirProgramManager.Domain.UserAgg.Entities; -using GozareshgirProgramManager.Domain.UserAgg.Repositories; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.LoginUser; - -/// -/// Handler برای ورود کاربر به سیستم -/// -public class LoginUserCommandHandler : IRequestHandler> -{ - private readonly IUserRepository _userRepository; - private readonly IUserRefreshTokenRepository _refreshTokenRepository; - private readonly IAuthHelper _authHelper; - private readonly IUnitOfWork _unitOfWork; - - public LoginUserCommandHandler( - IUserRepository userRepository, - IAuthHelper authHelper, - IUnitOfWork unitOfWork, IUserRefreshTokenRepository refreshTokenRepository) - { - _userRepository = userRepository; - _authHelper = authHelper; - _unitOfWork = unitOfWork; - _refreshTokenRepository = refreshTokenRepository; - } - - public async Task> Handle(LoginUserCommand request, CancellationToken cancellationToken) - { - // اعتبارسنجی - if (request.UserId <= 0) - { - return OperationResult.Failure("شناسه کاربری معتبر نیست", ErrorType.BadRequest); - } - - // یافتن کاربر - var user = await _userRepository.GetUserWithRolesByIdAsync(request.UserId, cancellationToken); - - if (user == null) - { - return OperationResult.Failure("کاربر یافت نشد", ErrorType.NotFound); - } - - // بررسی فعال بودن کاربر - if (!user.IsActive) - { - return OperationResult.Failure("حساب کاربری غیرفعال است", ErrorType.Unauthorized); - } - - // تولید توکن‌ها با استفاده از AuthHelper - var roles = user.RoleUser - .Select(r => r.RoleId.ToString()).ToList(); - - var session = _authHelper.SignIn( - user.Id, - user.UserName, - user.FullName, - user.AccountId??0, - roles); - // دریافت اطلاعات درخواست با استفاده از AuthHelper - var ipAddress = _authHelper.GetClientIpAddress(); - var userAgent = _authHelper.GetUserAgent(); - - // ذخیره Refresh Token در دیتابیس - //user.AddRefreshToken(refreshToken, refreshTokenExpiration, ipAddress, userAgent); - - var refreshTokenEntity = new UserRefreshToken( - user.Id, - session.RefreshToken, - session.RefreshTokenExpiration, - ipAddress, - userAgent); - - await _refreshTokenRepository.CreateAsync(refreshTokenEntity); - - - await _unitOfWork.SaveChangesAsync(cancellationToken); - - - // ساخت پاسخ (RefreshToken به فرانت داده نمی‌شود) - var response = new LoginResponse - { - AccessToken = session.AccessToken, - ExpiresAt = session.AccessTokenExpiration, - UserId = user.Id, - FullName = user.FullName, - UserName = user.UserName, - Roles = user.RoleUser.Select(r => r.RoleId).ToList() - }; - - return OperationResult.Success(response); - } -} - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/RefreshUserToken/RefreshUserTokenCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/RefreshUserToken/RefreshUserTokenCommand.cs deleted file mode 100644 index 31cf5838..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/RefreshUserToken/RefreshUserTokenCommand.cs +++ /dev/null @@ -1,11 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using MediatR; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.RefreshUserToken; - -/// -/// دستور تازه‌سازی توکن دسترسی کاربر -/// -public record RefreshUserTokenCommand() : IBaseCommand; - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/RefreshUserToken/RefreshUserTokenCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/RefreshUserToken/RefreshUserTokenCommandHandler.cs deleted file mode 100644 index 12bfb62b..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/RefreshUserToken/RefreshUserTokenCommandHandler.cs +++ /dev/null @@ -1,86 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain._Common; -using Microsoft.EntityFrameworkCore; -using MediatR; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.RefreshUserToken; - -/// -/// Handler برای تازه‌سازی توکن دسترسی -/// -public class RefreshUserTokenCommandHandler : IBaseCommandHandler -{ - private readonly IAuthHelper _authHelper; - private readonly IProgramManagerDbContext _context; - - public RefreshUserTokenCommandHandler( - IAuthHelper authHelper, - IProgramManagerDbContext context) - { - _authHelper = authHelper; - _context = context; - } - - public async Task Handle(RefreshUserTokenCommand request, CancellationToken cancellationToken) - { - - var refreshToken = _authHelper.GetRefreshTokenFromCookie(); - - // یافتن کاربر و Refresh Token فعال از دیتابیس - var user = await _context.Users - .Include(u => u.RefreshTokens) - .Include(u => u.RoleUser) - .FirstOrDefaultAsync(u => u.RefreshTokens.Any(r=>r.Token ==refreshToken), cancellationToken); - - if (user == null) - { - return OperationResult.Failure("کاربر یافت نشد", ErrorType.NotFound); - } - - // بررسی فعال بودن کاربر - if (!user.IsActive) - { - return OperationResult.Failure("حساب کاربری غیرفعال است", ErrorType.Unauthorized); - } - - // پیدا کردن Refresh Token فعال - var activeRefreshToken = user.RefreshTokens - .FirstOrDefault(rt => rt.Token == refreshToken && rt.IsActive); - - if (activeRefreshToken == null) - { - return OperationResult.Failure( - "نشست شما منقضی شده است. لطفاً دوباره وارد شوید", - ErrorType.Unauthorized); - } - - if (!activeRefreshToken.IsActive|| activeRefreshToken.IsRevoked||activeRefreshToken.IsExpired) - { - return OperationResult.Failure( - "نشست شما منقضی شده است. لطفاً دوباره وارد شوید", - ErrorType.Unauthorized); - } - - // تولید Access Token جدید با استفاده از AuthHelper - var roles = user.RoleUser.Select(r => r.RoleId.ToString()).ToList(); - var newAccessToken = _authHelper.GenerateAccessToken( - user.Id, - user.UserName, - user.FullName, - user.AccountId, - roles); - - var response = new AccessTokenResponse - { - AccessToken = newAccessToken, - ExpiresAt = DateTime.UtcNow.AddMinutes(30), - UserId = user.Id, - FullName = user.FullName, - UserName = user.UserName - }; - - return OperationResult.Success(response); - } -} - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SignOutUser/SignOutUserCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SignOutUser/SignOutUserCommand.cs deleted file mode 100644 index 7c9c6bda..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SignOutUser/SignOutUserCommand.cs +++ /dev/null @@ -1,11 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using MediatR; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.SignOutUser; - -/// -/// دستور خروج کاربر از سیستم -/// -public record SignOutUserCommand(string RefreshToken) : IBaseCommand; - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SignOutUser/SignOutUserCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SignOutUser/SignOutUserCommandHandler.cs deleted file mode 100644 index 92c69fcf..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SignOutUser/SignOutUserCommandHandler.cs +++ /dev/null @@ -1,68 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain._Common; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.SignOutUser; - -/// -/// Handler برای خروج کاربر از سیستم -/// -public class SignOutUserCommandHandler : IBaseCommandHandler -{ - private readonly IAuthHelper _authHelper; - private readonly IProgramManagerDbContext _context; - private readonly IUnitOfWork _unitOfWork; - - public SignOutUserCommandHandler( - IAuthHelper _authHelper, - IProgramManagerDbContext context, - IUnitOfWork unitOfWork) - { - this._authHelper = _authHelper; - _context = context; - _unitOfWork = unitOfWork; - } - - public async Task Handle(SignOutUserCommand request, CancellationToken cancellationToken) - { - // دریافت UserId از Claims با استفاده از AuthHelper - var userId = _authHelper.GetCurrentUserId(); - - if (!userId.HasValue) - { - return OperationResult.Failure("کاربر احراز هویت نشده است", ErrorType.Unauthorized); - } - - if (string.IsNullOrEmpty(request.RefreshToken)) - { - return OperationResult.Failure("توکن تازه‌سازی یافت نشد", ErrorType.BadRequest); - } - - // یافتن کاربر - var user = await _context.Users - .Include(u => u.RefreshTokens) - .FirstOrDefaultAsync(u => u.Id == userId.Value, cancellationToken); - - if (user == null) - { - return OperationResult.Failure("کاربر یافت نشد", ErrorType.NotFound); - } - - try - { - // لغو Refresh Token - user.RevokeRefreshToken(request.RefreshToken); - await _unitOfWork.SaveChangesAsync(cancellationToken); - _authHelper.SignOut(); - - return OperationResult.Success(); - } - catch (InvalidOperationException ex) - { - return OperationResult.Failure(ex.Message, ErrorType.BadRequest); - } - } -} - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SsoLogin/SsoLoginCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SsoLogin/SsoLoginCommand.cs deleted file mode 100644 index 0c6d5a33..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SsoLogin/SsoLoginCommand.cs +++ /dev/null @@ -1,10 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.SsoLogin; - -/// -/// دستور ورود از طریق SSO با استفاده از توکن JWT -/// -public record SsoLoginCommand(string Token) : IBaseCommand; - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SsoLogin/SsoLoginCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SsoLogin/SsoLoginCommandHandler.cs deleted file mode 100644 index 3e638729..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/SsoLogin/SsoLoginCommandHandler.cs +++ /dev/null @@ -1,115 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Domain._Common; -using GozareshgirProgramManager.Domain.UserAgg.Entities; -using GozareshgirProgramManager.Domain.UserAgg.Repositories; -using MediatR; - -namespace GozareshgirProgramManager.Application.Modules.Users.Commands.SsoLogin; - -/// -/// Handler برای ورود از طریق SSO با استفاده از JWT Token -/// -public class SsoLoginCommandHandler : IRequestHandler> -{ - private readonly IUserRepository _userRepository; - private readonly IUserRefreshTokenRepository _refreshTokenRepository; - private readonly IAuthHelper _authHelper; - private readonly IUnitOfWork _unitOfWork; - - public SsoLoginCommandHandler( - IUserRepository userRepository, - IAuthHelper authHelper, - IUnitOfWork unitOfWork, - IUserRefreshTokenRepository refreshTokenRepository) - { - _userRepository = userRepository; - _authHelper = authHelper; - _unitOfWork = unitOfWork; - _refreshTokenRepository = refreshTokenRepository; - } - - public async Task> Handle(SsoLoginCommand request, CancellationToken cancellationToken) - { - // اعتبارسنجی - if (string.IsNullOrWhiteSpace(request.Token)) - { - return OperationResult.Failure("توکن SSO معتبر نیست", ErrorType.BadRequest); - } - - // اعتبارسنجی توکن و استخراج Claims - var principal = _authHelper.ValidateToken(request.Token); - if (principal == null) - { - return OperationResult.Failure("توکن SSO نامعتبر یا منقضی شده است", ErrorType.Unauthorized); - } - - // استخراج AccountId از Claims - var accountIdClaim = principal.FindFirst("AccountId")?.Value; - if (string.IsNullOrEmpty(accountIdClaim) || !long.TryParse(accountIdClaim, out var accountId)) - { - return OperationResult.Failure("AccountId در توکن یافت نشد", ErrorType.BadRequest); - } - - // یافتن کاربر بر اساس AccountId - var user = await _userRepository.GetByGozareshgirAccountId(accountId); - - if (user == null) - { - return OperationResult.Failure("کاربر با AccountId مشخص شده یافت نشد", ErrorType.NotFound); - } - - // بررسی فعال بودن کاربر - if (!user.IsActive) - { - return OperationResult.Failure("حساب کاربری غیرفعال است", ErrorType.Unauthorized); - } - - // بارگذاری نقش‌های کاربر - user = await _userRepository.GetUserWithRolesByIdAsync(user.Id, cancellationToken); - if (user == null) - { - return OperationResult.Failure("خطا در بارگذاری اطلاعات کاربر", ErrorType.InternalServerError); - } - - // تولید توکن‌های جدید برای کاربر - var roles = user.RoleUser - .Select(r => r.RoleId.ToString()).ToList(); - - var session = _authHelper.SignIn( - user.Id, - user.UserName, - user.FullName, - user.AccountId ?? 0, - roles); - - // دریافت اطلاعات درخواست - var ipAddress = _authHelper.GetClientIpAddress(); - var userAgent = _authHelper.GetUserAgent(); - - // ذخیره Refresh Token در دیتابیس - var refreshTokenEntity = new UserRefreshToken( - user.Id, - session.RefreshToken, - session.RefreshTokenExpiration, - ipAddress, - userAgent); - - await _refreshTokenRepository.CreateAsync(refreshTokenEntity); - await _unitOfWork.SaveChangesAsync(cancellationToken); - - // ساخت پاسخ - var response = new LoginResponse - { - AccessToken = session.AccessToken, - ExpiresAt = session.AccessTokenExpiration, - UserId = user.Id, - FullName = user.FullName, - UserName = user.UserName, - Roles = user.RoleUser.Select(r => r.RoleId).ToList() - }; - - return OperationResult.Success(response); - } -} - diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetSingleUser/GetSingleUserQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetSingleUser/GetSingleUserQueryHandler.cs deleted file mode 100644 index 2d79108e..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetSingleUser/GetSingleUserQueryHandler.cs +++ /dev/null @@ -1,124 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetSingleUser; - -public class GetSingleUserQueryHandler : IBaseQueryHandler -{ - private readonly IProgramManagerDbContext _context; - - public GetSingleUserQueryHandler(IProgramManagerDbContext context) - { - _context = context; - } - - public async Task> Handle(GetSingleUserQuery request, CancellationToken cancellationToken) - { - - if (!string.IsNullOrWhiteSpace(request.accountId)) - { - long accountId = 0; - try - { - accountId = Convert.ToInt64(request.accountId); - } - catch (Exception e) - { - return (OperationResult)OperationResult.Failure("فقط عدد وارد کنید"); - } - - - if (accountId > 0) - { - var user = await _context.Users - .FirstOrDefaultAsync(x => x.AccountId == accountId); - - - if(user != null) - { - List roles = user.RoleUser.Select(x => x.RoleId).ToList(); - var response = new GetSingleUserResponse - { - FullName = user.FullName, - UserName = user.UserName, - ProfilePhotoPath = user.ProfilePhotoPath, - Mobile = user.Mobile, - IsActive = user.IsActive, - AccountId = user.AccountId, - Roles = roles, - RoleListDto = await _context.Roles.Where(x => roles.Contains(x.Id)).Select(x=> new RoleListDto() - { - RoleName = x.RoleName, - RoleId = x.Id, - Permissions = x.Permissions.Select(x=>x.Code).ToList() - }).ToListAsync(), - }; - - return OperationResult.Success(response); - } - else - { - return (OperationResult)OperationResult.NotFound("کاربر یافت نشد"); - } - } - } - - return (OperationResult)OperationResult.Failure("آی دی اکانت گزارشگیر پر نشده است"); - } -} - - -public record GetSingleUserResponse -{ - /// - /// نام و نام خانوادگی - /// - public string FullName { get; set; } - - /// - /// نام کاربری - /// - public string UserName { get; set; } - - - - /// - /// مسیر عکس پروفایل - /// - public string ProfilePhotoPath { get; set; } - - /// - /// شماره موبایل - /// - public string Mobile { get; set; } - - - /// - /// فعال/غیر فعال بودن یوزر - /// - public bool IsActive { get; set; } - - /// - /// آی دی کاربر در گزارشگیر - /// - public long? AccountId { get; set; } - - /// - /// نقش ها - /// - public List Roles { get; set; } - - public List RoleListDto { get; set; } -}; - - -public record RoleListDto -{ - public string RoleName { get; set; } - public long RoleId { get; set; } - public List Permissions { get; set; } - -} - -public record GetSingleUserQuery(string? accountId) : IBaseQuery; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUserSelectList/GetUserSelectListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUserSelectList/GetUserSelectListQueryHandler.cs deleted file mode 100644 index 7b45273a..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUserSelectList/GetUserSelectListQueryHandler.cs +++ /dev/null @@ -1,48 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Application.Modules.Users.Queries.GetSingleUser; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetUserSelectList; - -public class GetUserSelectListQueryHandler : IBaseQueryHandler -{ - private readonly IProgramManagerDbContext _context; - - public GetUserSelectListQueryHandler(IProgramManagerDbContext context) - { - _context = context; - } - - public async Task> Handle(GetUserSelectListQuery request, CancellationToken cancellationToken) - { - - var query = await _context.Users.Select(x => new GetUserSelectListDto() - { - FullName = x.FullName, - Id = x.Id - }).ToListAsync(); - - var response = new GetUserSelectListResponse(query); - - - return OperationResult.Success(response); - } -} - - -public record GetUserSelectListResponse(List? GetUserSelectListDto); - -public record GetUserSelectListDto -{ - /// - /// نام و نام خانوادگی - /// - public string FullName { get; set; } - - /// - /// آی دی کاربر - /// - public long Id { get; set; } -} -public record GetUserSelectListQuery() : IBaseQuery; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQuery.cs deleted file mode 100644 index 9a3e15e8..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQuery.cs +++ /dev/null @@ -1,5 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; - -namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetUsers; - -public record GetUsersQuery(string? FullName, string? UserName, string? Mobile) : IBaseQuery; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQueryHandler.cs deleted file mode 100644 index cb6467f4..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQueryHandler.cs +++ /dev/null @@ -1,49 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetUsers; - -public class GetUsersQueryHandler :IBaseQueryHandler -{ - private readonly IProgramManagerDbContext _context; - - public GetUsersQueryHandler(IProgramManagerDbContext context) - { - _context = context; - } - - public async Task> Handle(GetUsersQuery request, CancellationToken cancellationToken) - { - var query = _context.Users.AsQueryable(); - - //if (request.ParentId != null) - //{ - // query = query.Where(x => x.ParentId == request.ParentId); - //} - - var users = await query - .Select(p => new GetUserDto() - { - - FullName = p.FullName, - Mobile = p.Mobile, - UserName = p.UserName, - AccountId = p.AccountId, - IsActive = p.IsActive, - ProfilePhotoPath = p.ProfilePhotoPath, - - - }) - .ToListAsync(cancellationToken); - - var response = new GetUsersResponse( - users - ); - - return OperationResult.Success(response); - } - - - -} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersResponse.cs deleted file mode 100644 index e1cd043c..00000000 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersResponse.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetUsers; - -public record GetUsersResponse(List User); - -public record GetUserDto -{ - /// - /// نام و نام خانوادگی - /// - public string FullName { get; set; } - - /// - /// نام کاربری - /// - public string UserName { get; set; } - - - - /// - /// مسیر عکس پروفایل - /// - public string ProfilePhotoPath { get; set; } - - /// - /// شماره موبایل - /// - public string Mobile { get; set; } - - - /// - /// فعال/غیر فعال بودن یوزر - /// - public bool IsActive { get; set; } - - /// - /// آی دی کاربر در گزارشگیر - /// - public long? AccountId { get; set; } - - /// - /// نقش ها - /// - public List Roles { get; set; } - -} - diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/PermissionAgg/Entities/Permission.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/PermissionAgg/Entities/Permission.cs deleted file mode 100644 index 49e5cdc8..00000000 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/PermissionAgg/Entities/Permission.cs +++ /dev/null @@ -1,21 +0,0 @@ -using GozareshgirProgramManager.Domain.RoleAgg.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using GozareshgirProgramManager.Domain._Common; - -namespace GozareshgirProgramManager.Domain.PermissionAgg.Entities; - -public class Permission -{ - public long Id { get; private set; } - public int Code { get; private set; } - public Role Role { get; private set; } - - public Permission(int code) - { - Code = code; - } -} \ 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 a17403b0..4cfa127e 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs @@ -6,21 +6,14 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.CustomerAgg.Repositories; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; -using GozareshgirProgramManager.Domain.RoleAgg.Repositories; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; using GozareshgirProgramManager.Domain.SkillAgg.Repositories; -using GozareshgirProgramManager.Domain.UserAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence; using GozareshgirProgramManager.Infrastructure.Persistence.Context; using GozareshgirProgramManager.Infrastructure.Persistence.Repositories; using GozareshgirProgramManager.Infrastructure.Services.Authentication; using MediatR; -using FluentValidation; using GozareshgirProgramManager.Domain.CheckoutAgg.Repositories; -using GozareshgirProgramManager.Domain.RoleAgg.Repositories; -using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; -using GozareshgirProgramManager.Domain.SkillAgg.Repositories; - using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -55,12 +48,7 @@ public static class DependencyInjection // Unit of Work services.AddScoped(); - - //Users - services.AddScoped(); - - //Roles - services.AddScoped(); + //WorkingHours services.AddScoped(); @@ -83,8 +71,6 @@ public static class DependencyInjection services.AddScoped(); services.AddScoped(); - - services.AddScoped(); // JWT Settings services.Configure(configuration.GetSection("JwtSettings")); diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs index 69327586..5a8b0fc5 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs @@ -4,10 +4,7 @@ using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Domain.CustomerAgg; using GozareshgirProgramManager.Domain.ProjectAgg.Entities; -using GozareshgirProgramManager.Domain.RoleAgg.Entities; -using GozareshgirProgramManager.Domain.RoleUserAgg; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; -using GozareshgirProgramManager.Domain.UserAgg.Entities; using GozareshgirProgramManager.Domain.SkillAgg.Entities; using Microsoft.EntityFrameworkCore; diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RefreshTokenMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RefreshTokenMapping.cs deleted file mode 100644 index 42ac6330..00000000 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RefreshTokenMapping.cs +++ /dev/null @@ -1,50 +0,0 @@ -using GozareshgirProgramManager.Domain.UserAgg.Entities; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; - -public class RefreshTokenMapping : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("UserRefreshTokens"); - builder.HasKey(x => x.Id); - - builder.Property(x => x.Token) - .HasMaxLength(500) - .IsRequired(); - - builder.Property(x => x.ExpiresAt) - .IsRequired(); - - builder.Property(x => x.RevokedAt) - .IsRequired(false); - - builder.Property(x => x.IpAddress) - .HasMaxLength(50) - .IsRequired(false); - - builder.Property(x => x.UserAgent) - .HasMaxLength(500) - .IsRequired(false); - - builder.Property(x => x.UserId) - .IsRequired(); - - // رابطه با User - builder.HasOne(x => x.User) - .WithMany(u => u.RefreshTokens) - .HasForeignKey(x => x.UserId) - .OnDelete(DeleteBehavior.Cascade); - - // Index برای بهینه‌سازی جستجو - builder.HasIndex(x => x.Token) - .IsUnique(); - - builder.HasIndex(x => x.UserId); - - builder.HasIndex(x => x.ExpiresAt); - } -} - diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RoleMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RoleMapping.cs deleted file mode 100644 index 085a3d81..00000000 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RoleMapping.cs +++ /dev/null @@ -1,23 +0,0 @@ -using GozareshgirProgramManager.Domain.RoleAgg.Entities; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; - -public class RoleMapping : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("PmRoles"); - builder.HasKey(x => x.Id); - - builder.Property(x => x.RoleName).HasMaxLength(100).IsRequired(); - - builder.OwnsMany(x => x.Permissions, navigationBuilder => - { - navigationBuilder.HasKey(x => x.Id); - navigationBuilder.ToTable("PmRolePermissions"); - navigationBuilder.WithOwner(x => x.Role); - }); - } -} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/UserMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/UserMapping.cs deleted file mode 100644 index 39ca99ac..00000000 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/UserMapping.cs +++ /dev/null @@ -1,34 +0,0 @@ -using GozareshgirProgramManager.Domain.UserAgg.Entities; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; - -public class UserMapping :IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("Users"); - builder.HasKey(x => x.Id); - - builder.Property(x => x.FullName).HasMaxLength(100).IsRequired(); - builder.Property(x => x.UserName).HasMaxLength(100).IsRequired(); - builder.Property(x => x.Password).HasMaxLength(1000).IsRequired(); - builder.Property(x => x.ProfilePhotoPath).HasMaxLength(500).IsRequired(false); - builder.Property(x => x.Mobile).HasMaxLength(20).IsRequired(); - builder.Property(x => x.Email).HasMaxLength(150).IsRequired(false); ; - builder.Property(x => x.VerifyCode).HasMaxLength(10).IsRequired(false); - builder.OwnsMany(x => x.RoleUser, navigationBuilder => - { - navigationBuilder.HasKey(x => x.Id); - navigationBuilder.ToTable("RoleUsers"); - navigationBuilder.WithOwner(x => x.User); - }); - - builder.HasMany(x=>x.RefreshTokens) - .WithOne(x=>x.User) - .HasForeignKey(x=>x.UserId) - .OnDelete(DeleteBehavior.Cascade); - - } -} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/RoleRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/RoleRepository.cs deleted file mode 100644 index 01198c37..00000000 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/RoleRepository.cs +++ /dev/null @@ -1,24 +0,0 @@ -using GozareshgirProgramManager.Domain.RoleAgg.Entities; -using GozareshgirProgramManager.Domain.RoleAgg.Repositories; -using GozareshgirProgramManager.Infrastructure.Persistence._Common; -using GozareshgirProgramManager.Infrastructure.Persistence.Context; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; - -public class RoleRepository : RepositoryBase, IRoleRepository -{ - private readonly ProgramManagerDbContext _context; - public RoleRepository(ProgramManagerDbContext context) : base(context) - { - _context = context; - } - - public async Task GetByGozareshgirRoleIdAsync(long? gozareshgirRolId) - { - return await _context.Roles.FirstOrDefaultAsync(x => x.GozareshgirRoleId == gozareshgirRolId); - } - - - -} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SalaryPaymentSettingRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SalaryPaymentSettingRepository.cs index 4af80655..d016c134 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SalaryPaymentSettingRepository.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SalaryPaymentSettingRepository.cs @@ -1,19 +1,22 @@ -using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetSalarySettingToEdit; -using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.DTOs; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.DTOs; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; using GozareshgirProgramManager.Infrastructure.Persistence._Common; using GozareshgirProgramManager.Infrastructure.Persistence.Context; using Microsoft.EntityFrameworkCore; +using Shared.Contracts.Account; namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; public class SalaryPaymentSettingRepository : RepositoryBase, ISalaryPaymentSettingRepository { private readonly ProgramManagerDbContext _context; - public SalaryPaymentSettingRepository(ProgramManagerDbContext context) : base(context) + private readonly IAccountQueryService _accountQueryService; + + public SalaryPaymentSettingRepository(ProgramManagerDbContext context, IAccountQueryService accountQueryService) : base(context) { _context = context; + _accountQueryService = accountQueryService; } @@ -25,31 +28,36 @@ public class SalaryPaymentSettingRepository : RepositoryBase> GetAllSettings(List userIdList) { - _context.SalaryPaymentSettings.AsNoTracking(); - var query = await _context.SalaryPaymentSettings.Where(s=> userIdList.Contains(s.AccountId)) - .Join(_context.Users.AsNoTracking(), - setting => setting.AccountId, - user => user.Id, - (setting, user) => new { setting, user } - ) - .Select(x => new UserSalarySettingDto - { - UserId = x.user.Id, - HolidayWorking = x.setting!.HolidayWorking, - FullName = x.user.FullName, - MonthlySalary = x.setting.MonthlySalary, - WorkingHoursListDto = x.setting.WorkingHoursList - .Where(wh => wh.IsActiveDay) - .Select(wh => new WorkingHoursListDto() - { - ShiftDuration = wh.ShiftDuration, - PersianDayOfWeek = wh.PersianDayOfWeek - }).ToList() - }) + // دریافت تنظیمات حقوق + var settings = await _context.SalaryPaymentSettings + .AsNoTracking() + .Where(s => userIdList.Contains(s.AccountId)) .ToListAsync(); - return query; + // دریافت اطلاعات پایه کاربران از ACL + var accountIds = settings.Select(s => s.AccountId).Distinct().ToList(); + var accounts = await _accountQueryService.GetProgramManagerAccountListAsync(accountIds); + var accountDictionary = accounts.ToDictionary(a => a.Id, a => a); + // ترکیب داده‌ها + var result = settings.Select(setting => new UserSalarySettingDto + { + UserId = setting.AccountId, + HolidayWorking = setting.HolidayWorking, + FullName = accountDictionary.ContainsKey(setting.AccountId) + ? accountDictionary[setting.AccountId].Username + : "Unknown", + MonthlySalary = setting.MonthlySalary, + WorkingHoursListDto = setting.WorkingHoursList + .Where(wh => wh.IsActiveDay) + .Select(wh => new WorkingHoursListDto + { + ShiftDuration = wh.ShiftDuration, + PersianDayOfWeek = wh.PersianDayOfWeek + }).ToList() + }).ToList(); + + return result; } public void RemoveRangeSalarySettings(List removedItems) diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRefreshTokenRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRefreshTokenRepository.cs deleted file mode 100644 index 7200e888..00000000 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRefreshTokenRepository.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Linq.Expressions; -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Domain.UserAgg.Entities; -using GozareshgirProgramManager.Domain.UserAgg.Repositories; -using GozareshgirProgramManager.Infrastructure.Persistence._Common; -using GozareshgirProgramManager.Infrastructure.Persistence.Context; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; - -public class UserRefreshTokenRepository : RepositoryBase, IUserRefreshTokenRepository -{ - private readonly ProgramManagerDbContext _context; - public UserRefreshTokenRepository(ProgramManagerDbContext context) : base(context) - { - _context = context; - } - - -} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRepository.cs deleted file mode 100644 index 7b83ef6e..00000000 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRepository.cs +++ /dev/null @@ -1,87 +0,0 @@ -using GozareshgirProgramManager.Domain.UserAgg.Entities; -using GozareshgirProgramManager.Domain.UserAgg.Repositories; -using GozareshgirProgramManager.Infrastructure.Persistence._Common; -using GozareshgirProgramManager.Infrastructure.Persistence.Context; -using Microsoft.EntityFrameworkCore; - -namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; - -public class UserRepository : RepositoryBase, IUserRepository -{ - private readonly ProgramManagerDbContext _context; - public UserRepository(ProgramManagerDbContext context) : base(context) - { - _context = context; - } - - public Task GetByIdAsync(long id) - { - throw new NotImplementedException(); - } - - public async Task GetByGozareshgirAccountId(long accountId) - { - return await _context.Users.FirstOrDefaultAsync(x => x.AccountId == accountId); - } - - public Task GetByEmailAsync(string email) - { - throw new NotImplementedException(); - } - - public Task GetByMobileAsync(string mobile) - { - throw new NotImplementedException(); - } - - public Task> GetAllAsync() - { - throw new NotImplementedException(); - } - - public Task> GetActiveUsersAsync() - { - throw new NotImplementedException(); - } - - public Task AddAsync(User user) - { - throw new NotImplementedException(); - } - - public void Update(User user) - { - throw new NotImplementedException(); - } - - public void Delete(User user) - { - throw new NotImplementedException(); - } - - public Task ExistsAsync(long id) - { - throw new NotImplementedException(); - } - - public Task UsernameExistsAsync(string username) - { - throw new NotImplementedException(); - } - - public Task EmailExistsAsync(string email) - { - throw new NotImplementedException(); - } - - public Task MobileExistsAsync(string mobile) - { - throw new NotImplementedException(); - } - - public async Task GetUserWithRolesByIdAsync(long userId, CancellationToken cancellationToken) - { - return await _context.Users.Include(x => x.RoleUser) - .FirstOrDefaultAsync(x=>x.Id == userId, cancellationToken); - } -} \ No newline at end of file diff --git a/Query.Bootstrapper/QueryBootstrapper.cs b/Query.Bootstrapper/QueryBootstrapper.cs index a4f55718..d6582d18 100644 --- a/Query.Bootstrapper/QueryBootstrapper.cs +++ b/Query.Bootstrapper/QueryBootstrapper.cs @@ -12,6 +12,5 @@ namespace Query.Bootstrapper services.AddTransient(); } - } } diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/AuthController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/AuthController.cs deleted file mode 100644 index 22e3c173..00000000 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/AuthController.cs +++ /dev/null @@ -1,141 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Interfaces; -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Application.Modules.Users.Commands.LoginUser; -using GozareshgirProgramManager.Application.Modules.Users.Commands.RefreshUserToken; -using GozareshgirProgramManager.Application.Modules.Users.Commands.SignOutUser; -using GozareshgirProgramManager.Application.Modules.Users.Commands.SsoLogin; -using MediatR; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using ServiceHost.BaseControllers; - -namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; - -/// -/// کنترلر احراز هویت -/// -public class AuthController : ProgramManagerBaseController -{ - private readonly IAuthHelper _authHelper; - private readonly IMediator _mediator; - - public AuthController(IAuthHelper authHelper, IMediator mediator) - { - _authHelper = authHelper; - _mediator = mediator; - } - - /// - /// ورود به سیستم با شناسه کاربری - /// - /// شناسه کاربر - /// فقط Access Token - Refresh Token در سرور ذخیره می‌شود - [HttpPost("login")] - [AllowAnonymous] - public async Task>> Login([FromBody] LoginByIdRequest request) - { - var command = new LoginUserCommand(request.UserId); - var result = await _mediator.Send(command); - - return result; - } - - /// - /// ورود به سیستم از طریق SSO با استفاده از توکن JWT - /// توکن JWT از query string دریافت می‌شود و Claims آن استخراج می‌شود - /// سپس کاربر بر اساس AccountId موجود در Claims لاگین می‌شود - /// - /// JWT Token از سیستم خارجی - /// Access Token و اطلاعات کاربر - [HttpGet("sso-login")] - [AllowAnonymous] - public async Task>> SsoLogin([FromQuery] string token) - { - if (string.IsNullOrWhiteSpace(token)) - { - return BadRequest(OperationResult.Failure("توکن الزامی است", ErrorType.BadRequest)); - } - - var command = new SsoLoginCommand(token); - var result = await _mediator.Send(command); - - return result; - } - - /// - /// خروج از سیستم - /// - [HttpPost("signout")] - [Authorize] - public new async Task> SignOut() - { - // دریافت Refresh Token از Header با استفاده از AuthHelper - var refreshToken = _authHelper.GetRefreshTokenFromCookie(); - - if (string.IsNullOrEmpty(refreshToken)) - { - return OperationResult.Failure("توکن تازه‌سازی یافت نشد"); - } - - var command = new SignOutUserCommand(refreshToken); - var result = await _mediator.Send(command); - - if (result.IsSuccess) - { - return Ok(result); - } - - return StatusCode(result.ErrorType switch - { - ErrorType.Unauthorized => 401, - ErrorType.BadRequest => 400, - ErrorType.NotFound => 404, - _ => 500 - }, result); - } - - /// - /// تازه‌سازی توکن دسترسی - /// توکن منقضی شده را می‌گیرد و Access Token جدید برمی‌گرداند - /// Refresh Token از دیتابیس خوانده می‌شود و به فرانت داده نمی‌شود - /// - [HttpPost("refresh")] - [AllowAnonymous] - public async Task> RefreshAccessToken() - { - - var refreshTokenCommand = new RefreshUserTokenCommand(); - var result = await _mediator.Send(refreshTokenCommand); - - return result; - } - - /// - /// دریافت اطلاعات کاربر جاری - /// - [HttpGet("current")] - public IActionResult GetCurrentUser() - { - if (!_authHelper.IsAuthenticated()) - { - return Unauthorized(new { message = "کاربر احراز هویت نشده است" }); - } - - return Ok(new - { - userId = _authHelper.GetCurrentUserId(), - fullName= _authHelper.GetCurrentFullName(), - roles = _authHelper.GetCurrentUserRoles() - }); - } -} - -/// -/// درخواست ورود با شناسه کاربری -/// -public class LoginByIdRequest -{ - public long UserId { get; set; } -} - - diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/RoleController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/RoleController.cs deleted file mode 100644 index 39e7ff7d..00000000 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/RoleController.cs +++ /dev/null @@ -1,46 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Application.Modules.Roles.Commands.CreateRole; -using GozareshgirProgramManager.Application.Modules.Roles.Commands.EditRole; -using GozareshgirProgramManager.Application.Modules.Roles.Queries.GetRoles; -using MediatR; -using Microsoft.AspNetCore.Mvc; -using ServiceHost.BaseControllers; - -namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; - -public class RoleController : ProgramManagerBaseController -{ - private readonly IMediator _mediator; - - public RoleController(IMediator mediator) - { - _mediator = mediator; - } - - - [HttpGet] - public async Task>> Get([FromQuery] GetRolesQuery query) - { - var res = await _mediator.Send(query); - return res; - } - - - [HttpPost] - public async Task> Create([FromBody] CreateRoleCommand command) - { - var res = await _mediator.Send(command); - return res; - } - - - - [HttpPost("edit")] - public async Task> Edit([FromBody] EditRoleCommand command) - { - var res = await _mediator.Send(command); - return res; - } - - -} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/UserController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/UserController.cs deleted file mode 100644 index f0f7ada3..00000000 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/UserController.cs +++ /dev/null @@ -1,67 +0,0 @@ -using GozareshgirProgramManager.Application._Common.Models; -using GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; -using GozareshgirProgramManager.Application.Modules.Users.Commands.EditUser; -using GozareshgirProgramManager.Application.Modules.Users.Queries.GetSingleUser; -using GozareshgirProgramManager.Application.Modules.Users.Queries.GetUsers; -using GozareshgirProgramManager.Application.Modules.Users.Queries.GetUserSelectList; -using MediatR; -using Microsoft.AspNetCore.Mvc; -using ServiceHost.BaseControllers; - -namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; - -public class UserController : ProgramManagerBaseController -{ - private readonly IMediator _mediator; - - - public UserController(IMediator mediator) - { - _mediator = mediator; - } - - - [HttpGet] - public async Task>> Get([FromQuery] GetUsersQuery query) - { - var res = await _mediator.Send(query); - return res; - } - - - [HttpGet("{accountId}")] - public async Task>> GetUserByAccountId(string accountId) - { - var query = new GetSingleUserQuery(accountId); - var res = await _mediator.Send(query); - - return res; - } - - [HttpGet("GetUserSelectList")] - public async Task>> GetUserSelectList() - { - var query = new GetUserSelectListQuery(); - var res = await _mediator.Send(query); - - return res; - } - - - [HttpPost("create")] - public async Task> Create([FromBody] CreateUserCommand command) - { - var res = await _mediator.Send(command); - return res; - } - - - [HttpPost("edit")] - public async Task> Edit([FromBody] EditUserCommand command) - { - var res = await _mediator.Send(command); - return res; - } - - -} \ No newline at end of file diff --git a/ServiceHost/Program.cs b/ServiceHost/Program.cs index 3bb89c85..b75816e4 100644 --- a/ServiceHost/Program.cs +++ b/ServiceHost/Program.cs @@ -39,7 +39,7 @@ using Swashbuckle.AspNetCore.SwaggerUI; using AccountManagement.Domain.InternalApiCaller; using FluentValidation; using GozareshgirProgramManager.Application._Bootstrapper; -using GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; using GozareshgirProgramManager.Infrastructure; using GozareshgirProgramManager.Infrastructure.Persistence.Seed; @@ -63,7 +63,7 @@ var connectionStringProgramManager = builder.Configuration.GetConnectionString(" builder.Services.AddProgramManagerApplication(); builder.Services.AddProgramManagerInfrastructure(builder.Configuration); -builder.Services.AddValidatorsFromAssemblyContaining(); +builder.Services.AddValidatorsFromAssemblyContaining(); builder.Services.AddScoped(); #region MongoDb diff --git a/Shared.Contracts/Account/AccountBasicDto.cs b/Shared.Contracts/Account/AccountBasicDto.cs new file mode 100644 index 00000000..0f97fa61 --- /dev/null +++ b/Shared.Contracts/Account/AccountBasicDto.cs @@ -0,0 +1,14 @@ +namespace Shared.Contracts.Account; +/// +/// این DTO هیچ وابستگی به DbContext یا Entity ندارد +/// DTO مینیمال برای انتقال اطلاعات پایه حساب کاربری بین ماژول‌ها +/// +public class AccountBasicDto +{ + public bool IsActive { get; init; } + public string Fullname { get; init; } + public string Username { get; init; } + public long Id { get; init; } +} + + diff --git a/Shared.Contracts/Account/IAccountQueryService.cs b/Shared.Contracts/Account/IAccountQueryService.cs new file mode 100644 index 00000000..15d52361 --- /dev/null +++ b/Shared.Contracts/Account/IAccountQueryService.cs @@ -0,0 +1,25 @@ +namespace Shared.Contracts.Account; + +/// +/// Contract Interface برای دسترسی به اطلاعات پایه کاربران از سایر ماژول‌ها +/// این Interface به عنوان ACL (Anti-Corruption Layer) عمل می‌کند +/// +/// مزایا: +/// - هیچ وابستگی به Implementation ندارد +/// - ماژول‌های دیگر فقط به این Contract دسترسی دارند +/// - امکان تبدیل به Microservice بدون Breaking Change +/// - Testability بالا (Mock کردن آسان) +/// +public interface IAccountQueryService +{ + /// + /// دریافت اطلاعات پایه یک کاربر + /// + Task GetAccountAsync(long accountId); + + /// + /// دریافت اطلاعات پایه لیستی از کاربران (Batch Query برای جلوگیری از N+1) + /// + Task> GetProgramManagerAccountListAsync(List accountIds); +} + diff --git a/Shared.Contracts/Shared.Contracts.csproj b/Shared.Contracts/Shared.Contracts.csproj new file mode 100644 index 00000000..5fd9bd06 --- /dev/null +++ b/Shared.Contracts/Shared.Contracts.csproj @@ -0,0 +1,10 @@ + + + + net10.0 + enable + enable + + + +