Added the projectId in get expense pending list API
This commit is contained in:
parent
7e15c517ac
commit
91f4305995
@ -774,16 +774,16 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("expense/pendings")]
|
[HttpGet("expense/pendings")]
|
||||||
public async Task<IActionResult> GetPendingExpenseListAsync()
|
public async Task<IActionResult> GetPendingExpenseListAsync([FromQuery] Guid? projectId)
|
||||||
{
|
{
|
||||||
// Start log with correlation fields
|
// Start log with correlation fields
|
||||||
_logger.LogDebug(
|
_logger.LogDebug(
|
||||||
"GetPendingExpenseListAsync started. TenantId={TenantId}", tenantId); // [Start Log] [memory:4][memory:1]
|
"GetPendingExpenseListAsync started. Project={ProjectId} TenantId={TenantId}", projectId ?? Guid.Empty, tenantId); // [Start Log]
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Resolve current employee once; avoid using scoped services inside Task.Run
|
// Resolve current employee once; avoid using scoped services inside Task.Run
|
||||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); // [User Context] [memory:1]
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); // [User Context]
|
||||||
|
|
||||||
// Resolve permission service from current scope once
|
// Resolve permission service from current scope once
|
||||||
using var scope = _serviceScopeFactory.CreateScope();
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
@ -816,12 +816,12 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
|
|
||||||
_logger.LogInfo(
|
_logger.LogInfo(
|
||||||
"Permissions resolved: Review={Review}, Approve={Approve}, Process={Process}",
|
"Permissions resolved: Review={Review}, Approve={Approve}, Process={Process}",
|
||||||
hasReviewPermission, hasApprovePermission, hasProcessPermission); // [Permissions Log] [memory:4]
|
hasReviewPermission, hasApprovePermission, hasProcessPermission); // [Permissions Log]
|
||||||
|
|
||||||
// Build base query: read-only, tenant-scoped
|
// Build base query: read-only, tenant-scoped
|
||||||
var baseQuery = _context.Expenses
|
var baseQuery = _context.Expenses
|
||||||
.AsNoTracking() // Reduce tracking overhead for read-only list
|
.AsNoTracking() // Reduce tracking overhead for read-only list
|
||||||
.Where(e => e.IsActive && e.TenantId == tenantId); // [Base Filter] [memory:7]
|
.Where(e => e.IsActive && e.TenantId == tenantId); // [Base Filter]
|
||||||
|
|
||||||
// Important: fix operator precedence by grouping OR conditions
|
// Important: fix operator precedence by grouping OR conditions
|
||||||
// Pending means Draft always, plus role-gated statuses
|
// Pending means Draft always, plus role-gated statuses
|
||||||
@ -841,9 +841,11 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
(e.StatusId == Draft && e.CreatedById == loggedInEmployee.Id)
|
(e.StatusId == Draft && e.CreatedById == loggedInEmployee.Id)
|
||||||
|| (hasReviewPermission && e.StatusId == Review)
|
|| (hasReviewPermission && e.StatusId == Review)
|
||||||
|| (hasApprovePermission && e.StatusId == Approve)
|
|| (hasApprovePermission && e.StatusId == Approve)
|
||||||
|| (hasProcessPermission && e.StatusId == ProcessPending)); // [Correct Precedence] [memory:7]
|
|| (hasProcessPermission && e.StatusId == ProcessPending)); // [Correct Precedence]
|
||||||
|
|
||||||
// Project to DTO in SQL to avoid heavy Include graph.
|
// Project to DTO in SQL to avoid heavy Include graph.
|
||||||
|
if (projectId.HasValue)
|
||||||
|
pendingQuery = pendingQuery.Where(e => e.ProjectId == projectId);
|
||||||
|
|
||||||
// Prefer ProjectTo when profiles exist; otherwise project minimal fields
|
// Prefer ProjectTo when profiles exist; otherwise project minimal fields
|
||||||
var response = await pendingQuery
|
var response = await pendingQuery
|
||||||
@ -865,24 +867,24 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
PaidByName = e.PaidBy != null ? $"{e.PaidBy.FirstName} {e.PaidBy.LastName}" : null
|
PaidByName = e.PaidBy != null ? $"{e.PaidBy.FirstName} {e.PaidBy.LastName}" : null
|
||||||
})
|
})
|
||||||
.OrderByDescending(x => x.TransactionDate)
|
.OrderByDescending(x => x.TransactionDate)
|
||||||
.ToListAsync(); // Single round-trip; no Include needed for this shape [memory:7]
|
.ToListAsync(); // Single round-trip; no Include needed for this shape
|
||||||
|
|
||||||
_logger.LogInfo(
|
_logger.LogInfo(
|
||||||
"GetPendingExpenseListAsync completed. TenantId={TenantId}, Count={Count}",
|
"GetPendingExpenseListAsync completed. TenantId={TenantId}, Count={Count}",
|
||||||
tenantId, response.Count); // [Completion Log] [memory:4]
|
tenantId, response.Count); // [Completion Log]
|
||||||
|
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(response, "Pending Expenses fetched successfully", 200)); // [Success Response] [memory:1]
|
return Ok(ApiResponse<object>.SuccessResponse(response, "Pending Expenses fetched successfully", 200)); // [Success Response]
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("GetPendingExpenseListAsync canceled by client. TenantId={TenantId}", tenantId); // [Cancel Log] [memory:4]
|
_logger.LogWarning("GetPendingExpenseListAsync canceled by client. TenantId={TenantId}", tenantId); // [Cancel Log]
|
||||||
return StatusCode(499, ApiResponse<object>.ErrorResponse("Client has canceled the opration", "Client has canceled the opration", 499)); // [Cancel Response] [memory:1]
|
return StatusCode(499, ApiResponse<object>.ErrorResponse("Client has canceled the opration", "Client has canceled the opration", 499)); // [Cancel Response]
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "GetPendingExpenseListAsync failed. TenantId={TenantId}", tenantId); // [Error Log] [memory:4]
|
_logger.LogError(ex, "GetPendingExpenseListAsync failed. TenantId={TenantId}", tenantId); // [Error Log]
|
||||||
return StatusCode(500,
|
return StatusCode(500,
|
||||||
ApiResponse<object>.ErrorResponse("An error occurred while fetching pending expenses.", "An error occurred while fetching pending expenses.", 500)); // [Error Response] [memory:1]
|
ApiResponse<object>.ErrorResponse("An error occurred while fetching pending expenses.", "An error occurred while fetching pending expenses.", 500)); // [Error Response]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user