Merge branch 'Feature/EmployeesBankInfo/client-api' into Main

This commit is contained in:
2026-02-01 18:16:33 +03:30
9 changed files with 265 additions and 13 deletions

View File

@@ -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<EmployeeBankInformation> entities);
[Obsolete("از متد async استفاده کنید")]
List<GroupedEmployeeBankInformationViewModel> Search(long workshopId, EmployeeBankInformationSearchModel searchParams);
Task<List<GroupedEmployeeBankInformationViewModel>> SearchAsync(long workshopId,
EmployeeBankInformationSearchModel searchParams);
GroupedEmployeeBankInformationViewModel GetByEmployeeId(long workshopId, long employeeId);
List<EmployeeBankInformation> GetRangeByEmployeeId(long workshopId, long employeeId);
EmployeeBankInformationViewModel GetDetails(long id);
List<GroupedEmployeeBankInformationViewModel> GetAllByWorkshopId(long workshopId);
List<EmployeeBankInformationViewModelForExcel> SearchForExcel(long workshopId,
EmployeeBankInformationSearchModel searchParams);
List<EmployeeBankInformationViewModelForExcel> SearchForExcel(long workshopId, EmployeeBankInformationSearchModel searchParams);
/// <summary>
/// جزئیات اطلاعات بانکی بر اساس پرسنل
/// </summary>
/// <param name="workshopId"></param>
/// <param name="employeeId"></param>
/// <returns></returns>
Task<GetEmployeeBankInfoDetailsDto> GetDetailsByEmployeeIdAsync(long workshopId, long employeeId);
}
}

View File

@@ -0,0 +1,14 @@
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; }
public string BankName { get; set; }
public string BankLogoPath { get; set; }
public bool IsDefault { get; set; }
public long BankId { get; set; }
}

View File

@@ -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<GetEmployeeBankInfoDetailsBankItemDto> BankItems { get; set; }
}

View File

@@ -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<CreateEmployeeInformation> command);
OperationResult Edit(EditEmployeeInformation command);
[Obsolete("از متد Async استفاده شود")]
List<GroupedEmployeeBankInformationViewModel> Search(long workshopId, EmployeeBankInformationSearchModel searchParams);
List<EmployeeBankInformationViewModelForExcel> SearchForExcel(long workshopId,
EmployeeBankInformationSearchModel searchParams);
@@ -17,5 +20,22 @@ namespace CompanyManagment.App.Contracts.EmployeeBankInformation
OperationResult RemoveByEmployeeId(long workshopId, long employeeId);
List<GroupedEmployeeBankInformationViewModel> GetAllByWorkshopId(long workshopId);
OperationResult SetDefault(long workshopId, long bankInfoId);
/// <summary>
/// گرفتن لیست اطلاعات بانکی
/// </summary>
/// <param name="workshopId"></param>
/// <param name="searchParams"></param>
/// <returns></returns>
Task<List<GroupedEmployeeBankInformationViewModel>> SearchAsync
(long workshopId, EmployeeBankInformationSearchModel searchParams);
/// <summary>
/// جزئیات اطلاعات بانکی بر اساس پرسنل
/// </summary>
/// <param name="workshopId"></param>
/// <param name="employeeId"></param>
/// <returns></returns>
Task<GetEmployeeBankInfoDetailsDto> GetDetailsByEmployeeIdAsync(long workshopId, long employeeId);
}
}

View File

@@ -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,13 @@ namespace CompanyManagment.Application
}
//todo: add CardNumber, BankAccountNumber, etc validations
public async Task<List<GroupedEmployeeBankInformationViewModel>> SearchAsync(long workshopId,
EmployeeBankInformationSearchModel searchParams)
{
return await _employeeBankInformationRepository.SearchAsync(workshopId, searchParams);
}
public OperationResult Edit(EditEmployeeInformation command)
{
OperationResult op = new();
@@ -168,9 +175,6 @@ namespace CompanyManagment.Application
{
var entity = _employeeBankInformationRepository.GetByEmployeeId(workshopId, employeeId);
if (entity == null)
return new();
return entity;
}
@@ -211,6 +215,12 @@ namespace CompanyManagment.Application
return _employeeBankInformationRepository.GetAllByWorkshopId(workshopId);
}
public async Task<GetEmployeeBankInfoDetailsDto> GetDetailsByEmployeeIdAsync(long workshopId, long employeeId)
{
return await _employeeBankInformationRepository.GetDetailsByEmployeeIdAsync(workshopId, employeeId);
}
#region Private Methods
private OperationResult ValidateCreateOperation(List<GroupedEmployeeBankInformationViewModel> workshopEmployeeBankInfoList, CreateEmployeeInformation command)
@@ -253,8 +263,7 @@ namespace CompanyManagment.Application
return !workshopRecords.Exists(x =>
x.WorkshopId == workshopId && x.EmployeeId == employeeId);
}
#endregion
}
}

View File

@@ -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<long, EmployeeBa
}).ToList();
}
public async Task<List<GroupedEmployeeBankInformationViewModel>> 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<EmployeeBankInformation> entities)
{
@@ -265,4 +337,55 @@ public class EmployeeBankInformationRepository : RepositoryBase<long, EmployeeBa
};
}).ToList();
}
public async Task<GetEmployeeBankInfoDetailsDto> 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,
Id = x.id
};
}).ToList()
};
return res;
}
}

View File

@@ -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

View File

@@ -0,0 +1,49 @@
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<ActionResult<List<GroupedEmployeeBankInformationViewModel>>> GetList(
EmployeeBankInformationSearchModel searchModel)
{
return await _employeeBankInformationApplication.SearchAsync(_workshopId, searchModel);
}
[HttpGet("{employeeId:long}")]
public async Task<ActionResult<GetEmployeeBankInfoDetailsDto>> GetDetails(long employeeId)
{
return await _employeeBankInformationApplication.GetDetailsByEmployeeIdAsync(_workshopId, employeeId);
}
public ActionResult<OperationResult> Create(CreateEmployeeInformation command)
{
command.WorkshopId = _workshopId;
return _employeeBankInformationApplication.Create(command);
}
public ActionResult<OperationResult> Edit(EditEmployeeInformation command)
{
command.WorkshopId = _workshopId;
return _employeeBankInformationApplication.Edit(command);
}
public ActionResult<OperationResult> Remove(long id)
{
return _employeeBankInformationApplication.Remove(id);
}
}

View File

@@ -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");
}
}
}
}