Added the API to get list of recurring payments
This commit is contained in:
parent
e21a9b8eda
commit
46806b34bb
@ -224,10 +224,18 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
#region =================================================================== Payment Request Functions ===================================================================
|
|
||||||
|
|
||||||
|
#region =================================================================== Recurring Payment Functions ===================================================================
|
||||||
|
|
||||||
|
[HttpGet("get/recurring-payment/list")]
|
||||||
|
public async Task<IActionResult> GetRecurringPaymentList([FromQuery] string? searchString, [FromQuery] string? filter, [FromQuery] bool isActive = true, [FromQuery] int pageSize = 20, [FromQuery] int pageNumber = 1)
|
||||||
|
{
|
||||||
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _expensesService.GetRecurringPaymentListAsync(searchString, filter, isActive, pageSize, pageNumber, loggedInEmployee, tenantId);
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Payment Request Functions ===================================================================
|
#region =================================================================== Payment Request Functions ===================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2504,10 +2504,160 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
#region =================================================================== Payment Request Functions ===================================================================
|
|
||||||
|
|
||||||
|
#region =================================================================== Recurring Payment Functions ===================================================================
|
||||||
|
public async Task<ApiResponse<object>> GetRecurringPaymentListAsync(string? searchString, string? filter, bool isActive, int pageSize, int pageNumber, Employee loggedInEmployee, Guid tenantId)
|
||||||
|
{
|
||||||
|
_logger.LogInfo("Start GetRecurringPaymentListAsync called by EmployeeId: {EmployeeId} for TenantId: {TenantId}, PageNumber: {PageNumber}, PageSize: {PageSize}",
|
||||||
|
loggedInEmployee.Id, tenantId, pageNumber, pageSize);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check permissions concurrently: view self and view all recurring payments
|
||||||
|
var hasViewSelfPermissionTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
|
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
|
return await permissionService.HasPermission(PermissionsMaster.ViewSelfRecurring, loggedInEmployee.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
var hasViewAllPermissionTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
|
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
|
return await permissionService.HasPermission(PermissionsMaster.ViewAllRecurring, loggedInEmployee.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
await Task.WhenAll(hasViewSelfPermissionTask, hasViewAllPermissionTask);
|
||||||
|
|
||||||
|
bool hasViewSelfPermission = hasViewSelfPermissionTask.Result;
|
||||||
|
bool hasViewAllPermission = hasViewAllPermissionTask.Result;
|
||||||
|
|
||||||
|
// Deny access if user has no relevant permissions
|
||||||
|
if (!hasViewAllPermission && !hasViewSelfPermission)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Access DENIED: Employee {EmployeeId} has no permission to view recurring payments.", loggedInEmployee.Id);
|
||||||
|
return ApiResponse<object>.SuccessResponse(new { }, "You do not have permission to view any recurring payment.", 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base query with required navigation properties and tenant + active status filters
|
||||||
|
var recurringPaymentQuery = _context.RecurringPayments
|
||||||
|
.Include(rp => rp.Currency)
|
||||||
|
.Include(rp => rp.ExpenseCategory)
|
||||||
|
.Include(rp => rp.Status)
|
||||||
|
.Include(rp => rp.Project)
|
||||||
|
.Include(rp => rp.CreatedBy).ThenInclude(e => e!.JobRole)
|
||||||
|
.Where(rp => rp.TenantId == tenantId && rp.IsActive == isActive);
|
||||||
|
|
||||||
|
// If user has only view-self permission, restrict to their own payments
|
||||||
|
if (hasViewSelfPermission && !hasViewAllPermission)
|
||||||
|
{
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery.Where(rp => rp.CreatedById == loggedInEmployee.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialize and apply advanced filters
|
||||||
|
RecurringPaymentFilter? recurringPaymentFilter = TryDeserializeRecurringPaymentFilter(filter);
|
||||||
|
|
||||||
|
if (recurringPaymentFilter != null)
|
||||||
|
{
|
||||||
|
if (recurringPaymentFilter.ProjectIds?.Any() ?? false)
|
||||||
|
{
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery
|
||||||
|
.Where(rp => rp.ProjectId.HasValue && recurringPaymentFilter.ProjectIds.Contains(rp.ProjectId.Value));
|
||||||
|
}
|
||||||
|
if (recurringPaymentFilter.StatusIds?.Any() ?? false)
|
||||||
|
{
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery
|
||||||
|
.Where(rp => recurringPaymentFilter.StatusIds.Contains(rp.StatusId));
|
||||||
|
}
|
||||||
|
if (recurringPaymentFilter.CreatedByIds?.Any() ?? false)
|
||||||
|
{
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery
|
||||||
|
.Where(rp => recurringPaymentFilter.CreatedByIds.Contains(rp.CreatedById));
|
||||||
|
}
|
||||||
|
if (recurringPaymentFilter.CurrencyIds?.Any() ?? false)
|
||||||
|
{
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery
|
||||||
|
.Where(rp => recurringPaymentFilter.CurrencyIds.Contains(rp.CurrencyId));
|
||||||
|
}
|
||||||
|
if (recurringPaymentFilter.ExpenseCategoryIds?.Any() ?? false)
|
||||||
|
{
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery
|
||||||
|
.Where(rp => rp.ExpenseCategoryId.HasValue && recurringPaymentFilter.ExpenseCategoryIds.Contains(rp.ExpenseCategoryId.Value));
|
||||||
|
}
|
||||||
|
if (recurringPaymentFilter.Payees?.Any() ?? false)
|
||||||
|
{
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery
|
||||||
|
.Where(rp => recurringPaymentFilter.Payees.Contains(rp.Payee));
|
||||||
|
}
|
||||||
|
if (recurringPaymentFilter.StartDate.HasValue && recurringPaymentFilter.EndDate.HasValue)
|
||||||
|
{
|
||||||
|
DateTime startDate = recurringPaymentFilter.StartDate.Value.Date;
|
||||||
|
DateTime endDate = recurringPaymentFilter.EndDate.Value.Date;
|
||||||
|
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery
|
||||||
|
.Where(rp => rp.CreatedAt.Date >= startDate && rp.CreatedAt.Date <= endDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply search string filter if provided
|
||||||
|
if (!string.IsNullOrWhiteSpace(searchString))
|
||||||
|
{
|
||||||
|
recurringPaymentQuery = recurringPaymentQuery
|
||||||
|
.Where(rp =>
|
||||||
|
rp.Payee.Contains(searchString) ||
|
||||||
|
rp.Title.Contains(searchString) ||
|
||||||
|
(rp.UIDPrefix + "/" + rp.UIDPostfix.ToString().PadLeft(5, '0')).Contains(searchString)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get total count of matching records for pagination
|
||||||
|
var totalEntities = await recurringPaymentQuery.CountAsync();
|
||||||
|
|
||||||
|
// Calculate total pages (ceil)
|
||||||
|
var totalPages = (int)Math.Ceiling((double)totalEntities / pageSize);
|
||||||
|
|
||||||
|
// Fetch paginated data ordered by creation date desc
|
||||||
|
var recurringPayments = await recurringPaymentQuery
|
||||||
|
.OrderByDescending(rp => rp.CreatedAt)
|
||||||
|
.Skip((pageNumber - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Map entities to view models and set recurring payment UID
|
||||||
|
var results = recurringPayments.Select(rp =>
|
||||||
|
{
|
||||||
|
var vm = _mapper.Map<RecurringPaymentVM>(rp);
|
||||||
|
vm.RecurringPaymentUId = $"{rp.UIDPrefix}/{rp.UIDPostfix:D5}";
|
||||||
|
return vm;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
var response = new
|
||||||
|
{
|
||||||
|
CurrentPage = pageNumber,
|
||||||
|
TotalPages = totalPages,
|
||||||
|
TotalEntities = totalEntities,
|
||||||
|
Data = results,
|
||||||
|
};
|
||||||
|
|
||||||
|
_logger.LogInfo("Recurring payments fetched successfully: {Count} records for TenantId: {TenantId}, Page: {PageNumber}/{TotalPages}",
|
||||||
|
results.Count, tenantId, pageNumber, totalPages);
|
||||||
|
|
||||||
|
return ApiResponse<object>.SuccessResponse(response, $"{results.Count} recurring payments fetched successfully.", 200);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error in GetRecurringPaymentListAsync called by EmployeeId: {EmployeeId} for TenantId: {TenantId}: {Message}", loggedInEmployee.Id, tenantId, ex.Message);
|
||||||
|
return ApiResponse<object>.ErrorResponse("An error occurred while fetching recurring payments.", ex.Message, 500);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_logger.LogInfo("End GetRecurringPaymentListAsync called by EmployeeId: {EmployeeId}", loggedInEmployee.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Payment Request Functions ===================================================================
|
#region =================================================================== Payment Request Functions ===================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -29,8 +29,8 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
Task<ApiResponse<object>> DeletePaymentRequestAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> DeletePaymentRequestAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Payment Request Functions ===================================================================
|
#region =================================================================== Recurring Payment Functions ===================================================================
|
||||||
|
Task<ApiResponse<object>> GetRecurringPaymentListAsync(string? searchString, string? filter, bool isActive, int pageSize, int pageNumber, Employee loggedInEmployee, Guid tenantId);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user