Added the get list of payment request filter API

This commit is contained in:
ashutosh.nehete 2025-11-03 16:06:33 +05:30
parent 83d1dc4891
commit a204efb133
3 changed files with 62 additions and 153 deletions

View File

@ -143,6 +143,22 @@ namespace Marco.Pms.Services.Controllers
return StatusCode(response.StatusCode, response);
}
[HttpGet("payment-request/payee")]
public async Task<IActionResult> GetPayeeNameList()
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _expensesService.GetPayeeNameListAsync(loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpGet("payment-request/filter")]
public async Task<IActionResult> GetPaymentRequestFilterObject()
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _expensesService.GetPaymentRequestFilterObjectAsync(loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpPost("payment-request/create")]
public async Task<IActionResult> CreatePaymentRequest([FromBody] PaymentRequestDto model)
{

View File

@ -1246,159 +1246,6 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("End GetPaymentRequestListAsync for TenantId={TenantId}, EmployeeId={EmployeeId}", tenantId, loggedInEmployee.Id);
}
}
public async Task<ApiResponse<object>> GetPaymentRequestDetails(Guid? id, string? paymentRequestUId, Employee loggedInEmployee, Guid tenantId)
{
if (!id.HasValue && string.IsNullOrWhiteSpace(paymentRequestUId))
{
return ApiResponse<object>.ErrorResponse("User must proivde atleast one parameter", "User must proivde atleast one parameter", 400);
}
var hasViewSelfPermissionTask = Task.Run(async () =>
{
using var scope = _serviceScopeFactory.CreateScope();
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
return await permissionService.HasPermission(PermissionsMaster.ExpenseViewSelf, loggedInEmployee.Id);
});
var hasViewAllPermissionTask = Task.Run(async () =>
{
using var scope = _serviceScopeFactory.CreateScope();
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
return await permissionService.HasPermission(PermissionsMaster.ExpenseViewAll, loggedInEmployee.Id);
});
var hasReviewPermissionTask = Task.Run(async () =>
{
using var scope = _serviceScopeFactory.CreateScope();
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
return await permissionService.HasPermission(PermissionsMaster.ExpenseReview, loggedInEmployee.Id);
});
var hasApprovePermissionTask = Task.Run(async () =>
{
using var scope = _serviceScopeFactory.CreateScope();
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
return await permissionService.HasPermission(PermissionsMaster.ExpenseApprove, loggedInEmployee.Id);
});
var hasProcessPermissionTask = Task.Run(async () =>
{
using var scope = _serviceScopeFactory.CreateScope();
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
return await permissionService.HasPermission(PermissionsMaster.ExpenseProcess, loggedInEmployee.Id);
});
await Task.WhenAll(hasViewSelfPermissionTask, hasViewAllPermissionTask, hasReviewPermissionTask, hasApprovePermissionTask, hasProcessPermissionTask);
var hasViewSelfPermission = hasViewSelfPermissionTask.Result;
var hasViewAllPermission = hasViewAllPermissionTask.Result;
var hasReviewPermission = hasReviewPermissionTask.Result;
var hasApprovePermission = hasApprovePermissionTask.Result;
var hasProcessPermission = hasProcessPermissionTask.Result;
if (!hasViewSelfPermission && !hasViewAllPermission && !hasReviewPermission && !hasApprovePermission && !hasProcessPermission)
{
// User has neither required permission. Deny access.
_logger.LogWarning("Access DENIED for employee {EmployeeId} attempting to get payment request list.", loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(new List<ExpenseList>(), "You do not have permission to view any payment request.", 200);
}
var paymentRequest = await _context.PaymentRequests
.Include(pr => pr.Currency)
.Include(pr => pr.Project)
.Include(pr => pr.RecurringPayment)
.Include(pr => pr.ExpenseCategory)
.Include(pr => pr.ExpenseStatus)
.Include(pr => pr.CreatedBy)
.ThenInclude(e => e!.JobRole)
.Include(pr => pr.UpdatedBy)
.ThenInclude(e => e!.JobRole)
.Where(pr => (pr.Id == id || (pr.UIDPrefix + "/" + pr.UIDPostfix.ToString().PadLeft(5, '0')) == paymentRequestUId) &&
pr.TenantId == tenantId &&
pr.Currency != null &&
pr.ExpenseCategory != null &&
pr.ExpenseStatus != null &&
pr.CreatedBy != null &&
pr.CreatedBy.JobRole != null).FirstOrDefaultAsync();
if (paymentRequest == null)
{
return ApiResponse<object>.ErrorResponse("Payment Request not found", "Payment Request not found", 404);
}
var selfCheck = hasViewSelfPermission && !hasViewAllPermission && !hasReviewPermission && !hasApprovePermission && !hasProcessPermission && paymentRequest.CreatedById != loggedInEmployee.Id;
if (selfCheck)
{
// User has neither required permission. Deny access.
_logger.LogWarning("Access DENIED for employee {EmployeeId} attempting to get payment request list.", loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(new List<ExpenseList>(), "You do not have permission to view any payment request.", 200);
}
var nextStatusTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
using var scope = _serviceScopeFactory.CreateScope();
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
var nextStatus = await context.ExpensesStatusMapping
.Include(esm => esm.NextStatus)
.Where(esm => esm.StatusId == paymentRequest.ExpenseStatusId && esm.NextStatus != null)
.Select(esm => esm.NextStatus!)
.ToListAsync();
var nextStatusIds = nextStatus.Select(esm => esm.Id).ToList();
var permissionMapping = await context.StatusPermissionMapping.Where(spm => nextStatusIds.Contains(spm.StatusId)).ToListAsync();
List<ExpensesStatusMasterVM> results = new List<ExpensesStatusMasterVM>();
foreach (var status in nextStatus)
{
var permissionIds = permissionMapping.Where(spm => spm.StatusId == status.Id).Select(spm => spm.PermissionId).ToList();
var hasPermission = await permissionService.HasPermissionAny(permissionIds, loggedInEmployee.Id);
var hasStatusPermission = Review == status.Id && loggedInEmployee.Id == paymentRequest.CreatedById;
if (!hasPermission && !hasStatusPermission)
{
continue;
}
var result = _mapper.Map<ExpensesStatusMasterVM>(status);
result.PermissionIds = permissionIds;
results.Add(result);
}
return results;
});
var documnetTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
var documents = await context.PaymentRequestAttachments
.Include(pra => pra.Document)
.Where(pra => pra.PaymentRequestId == paymentRequest.Id && pra.Document != null)
.Select(pra => pra.Document!)
.ToListAsync();
return documents.Select(d =>
{
var result = _mapper.Map<PaymentRequestAttachmentVM>(d);
result.Url = _s3Service.GeneratePreSignedUrl(d.S3Key);
return result;
}).ToList();
});
await Task.WhenAll(nextStatusTask, documnetTask);
var nextStatus = nextStatusTask.Result;
var attachementVMs = documnetTask.Result;
var response = _mapper.Map<PaymentRequestDetailsVM>(paymentRequest);
response.PaymentRequestUID = $"{paymentRequest.UIDPrefix}/{paymentRequest.UIDPostfix:D5}";
response.Attachments = attachementVMs;
response.NextStatus = nextStatus;
return ApiResponse<object>.SuccessResponse(response, "Payment request fetched successfully", 200);
}
public async Task<ApiResponse<object>> GetPaymentRequestDetailsAsync(Guid? id, string? paymentRequestUId, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("Start GetPaymentRequestDetailsAsync called by EmployeeId: {EmployeeId} for TenantId: {TenantId} with Id: {Id}, UID: {UID}",
@ -1582,7 +1429,51 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("End GetPaymentRequestDetailsAsync called by EmployeeId: {EmployeeId}", loggedInEmployee.Id);
}
}
public async Task<ApiResponse<object>> GetPayeeNameListAsync(Employee loggedInEmployee, Guid tenantId)
{
try
{
var payeeList = await _context.PaymentRequests.Where(e => e.TenantId == tenantId).Select(e => e.Payee).Distinct().ToListAsync();
_logger.LogInfo("Employee {EmployeeId} fetched list of payees from payment request in a tenant {TenantId}", loggedInEmployee.Id, tenantId);
return ApiResponse<object>.SuccessResponse(payeeList, $"{payeeList.Count} records of payees fetched from payment request", 200);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Databsae Exception occured while fetching payee list from payment request");
return ApiResponse<object>.ErrorResponse("Databsae Exception", ExceptionMapper(dbEx), 500);
}
}
public async Task<ApiResponse<object>> GetPaymentRequestFilterObjectAsync(Employee loggedInEmployee, Guid tenantId)
{
try
{
var paymentRequests = await _context.PaymentRequests
.Include(pr => pr.Currency)
.Include(pr => pr.Project)
.Include(pr => pr.ExpenseCategory)
.Include(pr => pr.ExpenseStatus)
.Include(pr => pr.CreatedBy)
.Where(e => e.TenantId == tenantId)
.ToListAsync();
// Construct the final object from the results of the completed tasks.
var response = new
{
Projects = paymentRequests.Where(pr => pr.Project != null).Select(pr => new { Id = pr.Project!.Id, Name = pr.Project.Name }).Distinct().ToList(),
Currency = paymentRequests.Where(pr => pr.Currency != null).Select(pr => new { Id = pr.Currency!.Id, Name = pr.Currency.CurrencyName }).Distinct().ToList(),
CreatedBy = paymentRequests.Where(pr => pr.CreatedBy != null).Select(pr => new { Id = pr.CreatedBy!.Id, Name = $"{pr.CreatedBy.FirstName} {pr.CreatedBy.LastName}" }).Distinct().ToList(),
Status = paymentRequests.Where(pr => pr.ExpenseStatus != null).Select(pr => new { Id = pr.ExpenseStatus!.Id, Name = pr.ExpenseStatus.Name }).Distinct().ToList(),
ExpensesCategory = paymentRequests.Where(pr => pr.ExpenseCategory != null).Select(pr => new { Id = pr.ExpenseCategory!.Id, Name = pr.ExpenseCategory.Name }).Distinct().ToList(),
Payees = paymentRequests.Where(pr => !string.IsNullOrWhiteSpace(pr.Payee)).Select(pr => new { Id = pr.Payee, Name = pr.Payee }).Distinct().ToList()
};
return ApiResponse<object>.SuccessResponse(response, "Successfully fetched the filter list", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occured while fetching the list filters for payment requests");
return ApiResponse<object>.ErrorResponse("Internal Exception Occured", ExceptionMapper(ex), 500);
}
}
public async Task<ApiResponse<object>> CreatePaymentRequestAsync(PaymentRequestDto model, Employee loggedInEmployee, Guid tenantId)
{

View File

@ -20,6 +20,8 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
#region =================================================================== Payment Request Functions ===================================================================
Task<ApiResponse<object>> GetPaymentRequestListAsync(string? searchString, string? filter, bool isActive, int pageSize, int pageNumber, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetPaymentRequestDetailsAsync(Guid? id, string? paymentRequestUId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetPayeeNameListAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetPaymentRequestFilterObjectAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreatePaymentRequestAsync(PaymentRequestDto model, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> EditPaymentRequestAsync(Guid id, PaymentRequestDto model, Employee loggedInEmployee, Guid tenantId);
#endregion