From 1382305433d7b50e1660df0572609c3531b6bc1e Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 14 Jan 2026 16:32:46 +0330 Subject: [PATCH 1/2] add EmployeeBankInfoController.cs and set api for get list and get details --- .../IEmployeeBankInformationRepository.cs | 25 +++- .../GetEmployeeBankInfoDetailsBankItemDto.cs | 13 ++ .../GetEmployeeBankInfoDetailsDto.cs | 10 ++ .../IEmployeeBankInformationApplication.cs | 22 +++- .../EmployeeBankInformationApplication.cs | 19 ++- .../EmployeeBankInformationRepository.cs | 122 ++++++++++++++++++ .../ProjectSetTimeDetailsQueryHandler.cs | 3 +- .../Controllers/EmployeeBankInfoController.cs | 31 +++++ .../Company/EmployeesBankInfo/Index.cshtml.cs | 11 +- 9 files changed, 245 insertions(+), 11 deletions(-) create mode 100644 CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsBankItemDto.cs create mode 100644 CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsDto.cs create mode 100644 ServiceHost/Areas/Client/Controllers/EmployeeBankInfoController.cs diff --git a/Company.Domain/EmployeeBankInformationAgg/IEmployeeBankInformationRepository.cs b/Company.Domain/EmployeeBankInformationAgg/IEmployeeBankInformationRepository.cs index 6eae8bf8..69e447f5 100644 --- a/Company.Domain/EmployeeBankInformationAgg/IEmployeeBankInformationRepository.cs +++ b/Company.Domain/EmployeeBankInformationAgg/IEmployeeBankInformationRepository.cs @@ -1,7 +1,11 @@  +using System; using _0_Framework.Domain; using CompanyManagment.App.Contracts.EmployeeBankInformation; using System.Collections.Generic; +using System.Security.AccessControl; +using System.Threading.Tasks; +using CompanyManagment.App.Contracts.Workshop; namespace Company.Domain.EmployeeBankInformationAgg { @@ -11,14 +15,31 @@ namespace Company.Domain.EmployeeBankInformationAgg void Remove(EmployeeBankInformation bankInformation); void RemoveRange(List entities); + [Obsolete("از متد async استفاده کنید")] List Search(long workshopId, EmployeeBankInformationSearchModel searchParams); + + Task> SearchAsync(long workshopId, + EmployeeBankInformationSearchModel searchParams); + GroupedEmployeeBankInformationViewModel GetByEmployeeId(long workshopId, long employeeId); List GetRangeByEmployeeId(long workshopId, long employeeId); EmployeeBankInformationViewModel GetDetails(long id); List GetAllByWorkshopId(long workshopId); + + List SearchForExcel(long workshopId, + EmployeeBankInformationSearchModel searchParams); - - List SearchForExcel(long workshopId, EmployeeBankInformationSearchModel searchParams); + /// + /// جزئیات اطلاعات بانکی بر اساس پرسنل + /// + /// + /// + /// + Task GetDetailsByEmployeeIdAsync(long workshopId, long employeeId); + + + } + } diff --git a/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsBankItemDto.cs b/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsBankItemDto.cs new file mode 100644 index 00000000..23cb6145 --- /dev/null +++ b/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsBankItemDto.cs @@ -0,0 +1,13 @@ +namespace CompanyManagment.App.Contracts.EmployeeBankInformation; + +public class GetEmployeeBankInfoDetailsBankItemDto +{ + public string CardNumber { get; set; } + public string ShebaNumber { get; set; } + public string BankAccountNumber { get; set; } + public string BankName { get; set; } + public string BankLogoPath { get; set; } + public bool IsDefault { get; set; } + public long BankId { get; set; } + +} \ No newline at end of file diff --git a/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsDto.cs b/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsDto.cs new file mode 100644 index 00000000..955ffd15 --- /dev/null +++ b/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsDto.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace CompanyManagment.App.Contracts.EmployeeBankInformation; + +public class GetEmployeeBankInfoDetailsDto +{ + public long EmployeeId { get; set; } + public string EmployeeFullName { get; set; } + public List BankItems { get; set; } +} \ No newline at end of file diff --git a/CompanyManagment.App.Contracts/EmployeeBankInformation/IEmployeeBankInformationApplication.cs b/CompanyManagment.App.Contracts/EmployeeBankInformation/IEmployeeBankInformationApplication.cs index f052fb5f..a4540375 100644 --- a/CompanyManagment.App.Contracts/EmployeeBankInformation/IEmployeeBankInformationApplication.cs +++ b/CompanyManagment.App.Contracts/EmployeeBankInformation/IEmployeeBankInformationApplication.cs @@ -1,5 +1,7 @@ -using _0_Framework.Application; +using System; +using _0_Framework.Application; using System.Collections.Generic; +using System.Threading.Tasks; namespace CompanyManagment.App.Contracts.EmployeeBankInformation { @@ -8,6 +10,7 @@ namespace CompanyManagment.App.Contracts.EmployeeBankInformation OperationResult Create(CreateEmployeeInformation command); OperationResult GroupCreate(long workshopId, List command); OperationResult Edit(EditEmployeeInformation command); + [Obsolete("از متد Async استفاده شود")] List Search(long workshopId, EmployeeBankInformationSearchModel searchParams); List SearchForExcel(long workshopId, EmployeeBankInformationSearchModel searchParams); @@ -17,5 +20,22 @@ namespace CompanyManagment.App.Contracts.EmployeeBankInformation OperationResult RemoveByEmployeeId(long workshopId, long employeeId); List GetAllByWorkshopId(long workshopId); OperationResult SetDefault(long workshopId, long bankInfoId); + + /// + /// گرفتن لیست اطلاعات بانکی + /// + /// + /// + /// + Task> SearchAsync + (long workshopId, EmployeeBankInformationSearchModel searchParams); + + /// + /// جزئیات اطلاعات بانکی بر اساس پرسنل + /// + /// + /// + /// + Task GetDetailsByEmployeeIdAsync(long workshopId, long employeeId); } } diff --git a/CompanyManagment.Application/EmployeeBankInformationApplication.cs b/CompanyManagment.Application/EmployeeBankInformationApplication.cs index 81d71500..d955d967 100644 --- a/CompanyManagment.Application/EmployeeBankInformationApplication.cs +++ b/CompanyManagment.Application/EmployeeBankInformationApplication.cs @@ -4,6 +4,7 @@ using Company.Domain.EmployeeBankInformationAgg; using CompanyManagment.App.Contracts.EmployeeBankInformation; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace CompanyManagment.Application { @@ -101,7 +102,14 @@ namespace CompanyManagment.Application } - //todo: add CardNumber, BankAccountNumber, etc validations + public async Task> SearchAsync(long workshopId, + EmployeeBankInformationSearchModel searchParams) + { + return await _employeeBankInformationRepository.SearchAsync(workshopId, searchParams); + } + + + //todo: add CardNumber, BankAccountNumber, etc validations public OperationResult Edit(EditEmployeeInformation command) { OperationResult op = new(); @@ -168,9 +176,6 @@ namespace CompanyManagment.Application { var entity = _employeeBankInformationRepository.GetByEmployeeId(workshopId, employeeId); - if (entity == null) - return new(); - return entity; } @@ -211,6 +216,12 @@ namespace CompanyManagment.Application return _employeeBankInformationRepository.GetAllByWorkshopId(workshopId); } + + public async Task GetDetailsByEmployeeIdAsync(long workshopId, long employeeId) + { + return await _employeeBankInformationRepository.GetDetailsByEmployeeIdAsync(workshopId, employeeId); + } + #region Private Methods private OperationResult ValidateCreateOperation(List workshopEmployeeBankInfoList, CreateEmployeeInformation command) diff --git a/CompanyManagment.EFCore/Repository/EmployeeBankInformationRepository.cs b/CompanyManagment.EFCore/Repository/EmployeeBankInformationRepository.cs index a567ae11..461a4976 100644 --- a/CompanyManagment.EFCore/Repository/EmployeeBankInformationRepository.cs +++ b/CompanyManagment.EFCore/Repository/EmployeeBankInformationRepository.cs @@ -6,6 +6,8 @@ using CompanyManagment.App.Contracts.EmployeeBankInformation; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; +using _0_Framework.Exceptions; namespace CompanyManagment.EFCore.Repository; @@ -76,6 +78,76 @@ public class EmployeeBankInformationRepository : RepositoryBase> SearchAsync(long workshopId, EmployeeBankInformationSearchModel searchParams) + { + var bankInfoQuery = _companyContext.EmployeeBankInformationSet + .Where(x => x.WorkshopId == workshopId) + .Select(x => new + { + x.BankId, + x.EmployeeId, + x.WorkshopId, + }).AsQueryable(); + + if (searchParams.BankId > 0) + bankInfoQuery = bankInfoQuery.Where(x => x.BankId == searchParams.BankId); + + if (searchParams.EmployeeId > 0) + bankInfoQuery = bankInfoQuery.Where(x => x.EmployeeId == searchParams.EmployeeId); + + var bankInfoList = await bankInfoQuery.ToListAsync(); + + var employeeIds = bankInfoList.Select(x => x.EmployeeId).Distinct().ToList(); + + var employees = await _companyContext.Employees + .Where(x => employeeIds.Contains(x.id)).ToListAsync(); + + var personnelCodes = await _companyContext.PersonnelCodeSet + .Where(x=>employeeIds.Contains(x.EmployeeId) && x.WorkshopId == workshopId) + .ToDictionaryAsync(x=>x.EmployeeId,x=>x.PersonnelCode); + + var bankIds = bankInfoList.Select(x=>x.BankId).Distinct().ToList(); + + var banks =await _companyContext.Banks.Where(x => bankIds.Contains(x.id)).ToListAsync(); + + + //Get bank logos from account context + var mediaIds = banks.Select(x=>x.BankLogoMediaId).ToList(); + + var banksLogos = _accountContext.Medias.Where(y => mediaIds.Contains(y.id)) + .Select(media => new { media.Path, MediaId = media.id }).ToList(); + + var banksWithLogo = banks.Select(x => new + { + Logo = banksLogos.FirstOrDefault(l => l.MediaId == x.BankLogoMediaId), + Bank = x + }).ToList(); + + return bankInfoList.GroupBy(x => x.EmployeeId).Select(x => + { + var employee = employees.FirstOrDefault(e=>e.id == x.Key); + + var selectBankId = x.Select(b => b.BankId); + + var selectBanks = banksWithLogo + .Where(b => selectBankId.Contains(b.Bank.id)).ToList(); + + return new GroupedEmployeeBankInformationViewModel() + { + BankPicturesList = + selectBanks.Select(y => y.Logo.Path).ToList(), + EmployeeId = x.Key, + WorkshopId = workshopId, + EmployeeName = employee?.FullName ?? "", + TotalBankAccountsCount = x.Count(), + PersonnelCode = personnelCodes.TryGetValue(x.Key,out var value)? + value.ToString() : + "", + BankNamesList = selectBanks.Select(y => y.Bank.BankName).ToList() + }; + }).ToList(); + } + public void RemoveByEmployeeId(IEnumerable entities) { @@ -265,4 +337,54 @@ public class EmployeeBankInformationRepository : RepositoryBase GetDetailsByEmployeeIdAsync(long workshopId, long employeeId) + { + var employeeBankInfos =await _companyContext.EmployeeBankInformationSet + .Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId).ToListAsync(); + + if (employeeBankInfos.Count == 0) + { + throw new NotFoundException("اطلاعات بانکی یافت نشد"); + } + var employee = await _companyContext.Employees + .FirstOrDefaultAsync(x=>x.id == employeeId); + + if (employee == null) + { + throw new NotFoundException("پرسنل مورد نظر یافت نشد"); + } + + var employeeFullName = employee.FullName; + + var bankIds = employeeBankInfos.Select(x => x.BankId).Distinct().ToList(); + + var banks = await _companyContext.Banks.Where(x => bankIds.Contains(x.id)).ToListAsync(); + + var mediaIds = banks.Select(x => x.BankLogoMediaId).ToList(); + + var bankLogos = await _accountContext.Medias.Where(x=>mediaIds.Contains(x.id)).ToListAsync(); + + var res = new GetEmployeeBankInfoDetailsDto() + { + EmployeeId = employeeId, + EmployeeFullName = employeeFullName, + BankItems = employeeBankInfos.Select(x => + { + var bank = banks.FirstOrDefault(y => y.id == x.BankId); + var bankLogo = bankLogos.FirstOrDefault(l => bank?.BankLogoMediaId == l.id); + return new GetEmployeeBankInfoDetailsBankItemDto() + { + BankId = x.BankId, + BankAccountNumber = x.BankAccountNumber, + BankLogoPath = bankLogo?.Path ?? "", + BankName = bank?.BankName ?? "", + CardNumber = x.CardNumber, + ShebaNumber = x.ShebaNumber, + IsDefault = x.IsDefault + }; + }).ToList() + }; + return res; + } } \ No newline at end of file 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 b3600159..c5b5fe39 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 @@ -62,7 +62,8 @@ public class ProjectSetTimeDetailsQueryHandler var res = new ProjectSetTimeResponse( skills.Select(skill => { - var section = task.Sections + var section = task + .Sections .FirstOrDefault(x => x.SkillId == skill.Id); var user = users.FirstOrDefault(x => x.Id == section?.OriginalAssignedUserId); return new ProjectSetTimeResponseSkill diff --git a/ServiceHost/Areas/Client/Controllers/EmployeeBankInfoController.cs b/ServiceHost/Areas/Client/Controllers/EmployeeBankInfoController.cs new file mode 100644 index 00000000..5fd277f9 --- /dev/null +++ b/ServiceHost/Areas/Client/Controllers/EmployeeBankInfoController.cs @@ -0,0 +1,31 @@ +using _0_Framework.Application; +using CompanyManagment.App.Contracts.EmployeeBankInformation; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Client.Controllers; + +public class EmployeeBankInfoController:ClientBaseController +{ + private readonly IEmployeeBankInformationApplication _employeeBankInformationApplication; + private readonly long _workshopId; + + public EmployeeBankInfoController(IEmployeeBankInformationApplication employeeBankInformationApplication,IAuthHelper authHelper) + { + _employeeBankInformationApplication = employeeBankInformationApplication; + _workshopId = authHelper.GetWorkshopId(); + } + + [HttpGet] + public async Task>> GetList(EmployeeBankInformationSearchModel searchModel) + { + return await _employeeBankInformationApplication.SearchAsync(_workshopId, searchModel); + } + + [HttpGet("{employeeId:long}")] + public async Task GetDetails(long employeeId) + { + return await _employeeBankInformationApplication.GetDetailsByEmployeeIdAsync(_workshopId,employeeId); + } + +} \ No newline at end of file diff --git a/ServiceHost/Areas/Client/Pages/Company/EmployeesBankInfo/Index.cshtml.cs b/ServiceHost/Areas/Client/Pages/Company/EmployeesBankInfo/Index.cshtml.cs index ca173d6e..53b162ef 100644 --- a/ServiceHost/Areas/Client/Pages/Company/EmployeesBankInfo/Index.cshtml.cs +++ b/ServiceHost/Areas/Client/Pages/Company/EmployeesBankInfo/Index.cshtml.cs @@ -28,7 +28,11 @@ namespace ServiceHost.Areas.Client.Pages.Company.EmployeesBankInfo private readonly IWebHostEnvironment _hostEnvironment; - public IndexModel(IPasswordHasher passwordHasher, IWorkshopApplication workshopApplication, IHttpContextAccessor contextAccessor, IAuthHelper authHelper, IEmployeeBankInformationApplication employeeBankInformationApplication, IEmployeeApplication employeeApplication, IBankApplication bankApplication, IWebHostEnvironment hostEnvironment) + public IndexModel(IPasswordHasher passwordHasher, IWorkshopApplication workshopApplication, + IHttpContextAccessor contextAccessor, IAuthHelper authHelper, + IEmployeeBankInformationApplication employeeBankInformationApplication, + IEmployeeApplication employeeApplication, IBankApplication bankApplication, + IWebHostEnvironment hostEnvironment) { _passwordHasher = passwordHasher; _workshopApplication = workshopApplication; @@ -64,7 +68,8 @@ namespace ServiceHost.Areas.Client.Pages.Company.EmployeesBankInfo public IActionResult OnGetEmployeeBankInfoListAjax(EmployeeBankInformationSearchModel searchModel) { - var resultData = _employeeBankInformationApplication.Search(_workshopId, searchModel); + var resultData = _employeeBankInformationApplication + .Search(_workshopId, searchModel); return new JsonResult(new { success = true, @@ -242,4 +247,4 @@ namespace ServiceHost.Areas.Client.Pages.Company.EmployeesBankInfo $"اطلاعات بانکی پرسنل.xlsx"); } } -} +} \ No newline at end of file From 8faddedd467f865e69f71dcbc4734252bfb83843 Mon Sep 17 00:00:00 2001 From: mahan Date: Wed, 14 Jan 2026 17:45:03 +0330 Subject: [PATCH 2/2] add create and edit controller api --- .../GetEmployeeBankInfoDetailsBankItemDto.cs | 1 + .../EmployeeBankInformationApplication.cs | 6 +-- .../EmployeeBankInformationRepository.cs | 3 +- .../Controllers/EmployeeBankInfoController.cs | 38 ++++++++++++++----- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsBankItemDto.cs b/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsBankItemDto.cs index 23cb6145..1654da19 100644 --- a/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsBankItemDto.cs +++ b/CompanyManagment.App.Contracts/EmployeeBankInformation/GetEmployeeBankInfoDetailsBankItemDto.cs @@ -2,6 +2,7 @@ namespace CompanyManagment.App.Contracts.EmployeeBankInformation; public class GetEmployeeBankInfoDetailsBankItemDto { + public long Id { get; set; } public string CardNumber { get; set; } public string ShebaNumber { get; set; } public string BankAccountNumber { get; set; } diff --git a/CompanyManagment.Application/EmployeeBankInformationApplication.cs b/CompanyManagment.Application/EmployeeBankInformationApplication.cs index d955d967..8414cdc2 100644 --- a/CompanyManagment.Application/EmployeeBankInformationApplication.cs +++ b/CompanyManagment.Application/EmployeeBankInformationApplication.cs @@ -108,8 +108,7 @@ namespace CompanyManagment.Application return await _employeeBankInformationRepository.SearchAsync(workshopId, searchParams); } - - //todo: add CardNumber, BankAccountNumber, etc validations + public OperationResult Edit(EditEmployeeInformation command) { OperationResult op = new(); @@ -264,8 +263,7 @@ namespace CompanyManagment.Application return !workshopRecords.Exists(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId); } - - + #endregion } } diff --git a/CompanyManagment.EFCore/Repository/EmployeeBankInformationRepository.cs b/CompanyManagment.EFCore/Repository/EmployeeBankInformationRepository.cs index 461a4976..27a563d0 100644 --- a/CompanyManagment.EFCore/Repository/EmployeeBankInformationRepository.cs +++ b/CompanyManagment.EFCore/Repository/EmployeeBankInformationRepository.cs @@ -381,7 +381,8 @@ public class EmployeeBankInformationRepository : RepositoryBase>> GetList(EmployeeBankInformationSearchModel searchModel) + public async Task>> GetList( + EmployeeBankInformationSearchModel searchModel) { - return await _employeeBankInformationApplication.SearchAsync(_workshopId, searchModel); - } - - [HttpGet("{employeeId:long}")] - public async Task GetDetails(long employeeId) - { - return await _employeeBankInformationApplication.GetDetailsByEmployeeIdAsync(_workshopId,employeeId); + return await _employeeBankInformationApplication.SearchAsync(_workshopId, searchModel); } + [HttpGet("{employeeId:long}")] + public async Task> GetDetails(long employeeId) + { + return await _employeeBankInformationApplication.GetDetailsByEmployeeIdAsync(_workshopId, employeeId); + } + + public ActionResult Create(CreateEmployeeInformation command) + { + command.WorkshopId = _workshopId; + return _employeeBankInformationApplication.Create(command); + } + + public ActionResult Edit(EditEmployeeInformation command) + { + command.WorkshopId = _workshopId; + return _employeeBankInformationApplication.Edit(command); + } + + public ActionResult Remove(long id) + { + return _employeeBankInformationApplication.Remove(id); + } } \ No newline at end of file