diff --git a/Marco.Pms.Services/Controllers/CollectionController.cs b/Marco.Pms.Services/Controllers/CollectionController.cs
index 56a78e7..0b13983 100644
--- a/Marco.Pms.Services/Controllers/CollectionController.cs
+++ b/Marco.Pms.Services/Controllers/CollectionController.cs
@@ -5,6 +5,9 @@ using Marco.Pms.Model.Collection;
using Marco.Pms.Model.Dtos.Collection;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.MongoDBModels.Utility;
+using Marco.Pms.Model.OrganizationModel;
+using Marco.Pms.Model.Projects;
+using Marco.Pms.Model.ServiceProject;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Collection;
@@ -15,7 +18,6 @@ using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
using MongoDB.Driver;
using Document = Marco.Pms.Model.DocumentManager.Document;
@@ -55,7 +57,8 @@ namespace Marco.Pms.Services.Controllers
///
/// Fetches a paginated and filtered list of invoices after validating permissions.
///
- [HttpGet]
+
+ [HttpGet("invoice/list")]
public async Task GetInvoiceListAsync([FromQuery] Guid? projectId, [FromQuery] string? searchString, [FromQuery] DateTime? fromDate, [FromQuery] DateTime? toDate,
[FromQuery] int pageSize = 20, [FromQuery] int pageNumber = 1, [FromQuery] bool isActive = true, [FromQuery] bool isPending = false)
{
@@ -213,748 +216,616 @@ namespace Marco.Pms.Services.Controllers
}
-
///
- /// Retrieves complete details of a specific invoice including associated comments, attachments, and payments.
+ /// Retrieves detailed information about a specific invoice including related data such as
+ /// comments, attachments, payments, and associated project information after validating permissions.
///
- /// The unique identifier of the invoice.
- /// Returns invoice details with associated data or a NotFound/BadRequest response.
+ /// The unique identifier of the invoice to fetch.
+ /// Returns invoice details with related entities or appropriate error responses.
[HttpGet("invoice/details/{id}")]
public async Task GetInvoiceDetailsAsync(Guid id)
{
- _logger.LogInfo("Fetching details for InvoiceId: {InvoiceId}, TenantId: {TenantId}", id, tenantId);
-
- // Get the currently logged-in employee
- var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
-
- // Log starting permission checks
- _logger.LogInfo("Starting permission checks for EmployeeId: {EmployeeId}", loggedInEmployee.Id);
-
- // Initiate permission check tasks asynchronously
- var adminPermissionTask = Task.Run(async () =>
+ try
{
- using var scope = _serviceScopeFactory.CreateScope();
- var _permission = scope.ServiceProvider.GetRequiredService();
- return await _permission.HasPermission(PermissionsMaster.CollectionAdmin, loggedInEmployee.Id);
- });
+ _logger.LogInfo("GetInvoiceDetailsAsync called for InvoiceId: {InvoiceId}, TenantId: {TenantId}", id, tenantId);
- var viewPermissionTask = Task.Run(async () =>
- {
- using var scope = _serviceScopeFactory.CreateScope();
- var _permission = scope.ServiceProvider.GetRequiredService();
- return await _permission.HasPermission(PermissionsMaster.ViewCollection, loggedInEmployee.Id);
- });
+ // Retrieve currently logged-in employee for permissions validation
+ var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
+ _logger.LogInfo("Permission checks initiated for EmployeeId: {EmployeeId}", loggedInEmployee.Id);
- var createPermissionTask = Task.Run(async () =>
- {
- using var scope = _serviceScopeFactory.CreateScope();
- var _permission = scope.ServiceProvider.GetRequiredService();
- return await _permission.HasPermission(PermissionsMaster.CreateCollection, loggedInEmployee.Id);
- });
+ // Run all necessary permission checks in parallel using scoped DI contexts
+ var permissionTasks = new[]
+ {
+ HasPermissionAsync(PermissionsMaster.CollectionAdmin, loggedInEmployee.Id),
+ HasPermissionAsync(PermissionsMaster.ViewCollection, loggedInEmployee.Id),
+ HasPermissionAsync(PermissionsMaster.CreateCollection, loggedInEmployee.Id),
+ HasPermissionAsync(PermissionsMaster.EditCollection, loggedInEmployee.Id),
+ HasPermissionAsync(PermissionsMaster.AddPayment, loggedInEmployee.Id)
+ };
+ await Task.WhenAll(permissionTasks);
- var editPermissionTask = Task.Run(async () =>
- {
- using var scope = _serviceScopeFactory.CreateScope();
- var _permission = scope.ServiceProvider.GetRequiredService();
- return await _permission.HasPermission(PermissionsMaster.EditCollection, loggedInEmployee.Id);
- });
+ // Aggregate permission results
+ if (permissionTasks.All(t => !t.Result))
+ {
+ _logger.LogWarning("Permission denied for EmployeeId {EmployeeId} without required collection permissions.", loggedInEmployee.Id);
+ return StatusCode(403, ApiResponse