Removed Project ForignKey From PaymentRequest Table
This commit is contained in:
parent
1b94592026
commit
c7a73e78fb
File diff suppressed because one or more lines are too long
@ -0,0 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Removed_Project_ForignKey_From_RecurringPayment_Table : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_RecurringPayments_Projects_ProjectId",
|
||||
table: "RecurringPayments");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_RecurringPayments_ProjectId",
|
||||
table: "RecurringPayments");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RecurringPayments_ProjectId",
|
||||
table: "RecurringPayments",
|
||||
column: "ProjectId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_RecurringPayments_Projects_ProjectId",
|
||||
table: "RecurringPayments",
|
||||
column: "ProjectId",
|
||||
principalTable: "Projects",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2922,8 +2922,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
|
||||
b.HasIndex("ExpenseCategoryId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.HasIndex("StatusId");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
@ -7612,10 +7610,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
.WithMany()
|
||||
.HasForeignKey("ExpenseCategoryId");
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Projects.Project", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId");
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Expenses.Masters.RecurringPaymentStatus", "Status")
|
||||
.WithMany()
|
||||
.HasForeignKey("StatusId")
|
||||
@ -7638,8 +7632,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
|
||||
b.Navigation("ExpenseCategory");
|
||||
|
||||
b.Navigation("Project");
|
||||
|
||||
b.Navigation("Status");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Expenses.Masters;
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.Projects;
|
||||
using Marco.Pms.Model.TenantModels;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
@ -29,10 +28,6 @@ namespace Marco.Pms.Model.Expenses
|
||||
public DateTime? LatestPRGeneratedAt { get; set; }
|
||||
public DateTime? NextStrikeDate { get; set; }
|
||||
public Guid? ProjectId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ProjectId")]
|
||||
public Project? Project { get; set; }
|
||||
public int PaymentBufferDays { get; set; }
|
||||
public Guid? ExpenseCategoryId { get; set; }
|
||||
|
||||
|
||||
@ -110,23 +110,16 @@ namespace Marco.Pms.Services.Service
|
||||
Guid loggedInEmployeeId = loggedInEmployee.Id;
|
||||
List<ExpenseList> expenseVM = new List<ExpenseList>();
|
||||
var totalEntites = 0;
|
||||
var hasViewSelfPermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseViewSelf, loggedInEmployeeId);
|
||||
});
|
||||
|
||||
var hasViewAllPermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseViewAll, loggedInEmployeeId);
|
||||
});
|
||||
var hasViewSelfPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseViewSelf, loggedInEmployee.Id);
|
||||
var hasViewAllPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseViewAll, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(hasViewSelfPermissionTask, hasViewAllPermissionTask);
|
||||
|
||||
if (!hasViewAllPermissionTask.Result && !hasViewSelfPermissionTask.Result)
|
||||
var hasViewAllPermission = hasViewAllPermissionTask.Result;
|
||||
var hasViewSelfPermission = hasViewSelfPermissionTask.Result;
|
||||
|
||||
if (!hasViewAllPermission && !hasViewSelfPermission)
|
||||
{
|
||||
// User has neither required permission. Deny access.
|
||||
_logger.LogWarning("Access DENIED for employee {EmployeeId} attempting to get expenses list.", loggedInEmployeeId);
|
||||
@ -165,11 +158,11 @@ namespace Marco.Pms.Services.Service
|
||||
//await _cache.AddExpensesListToCache(expenses: await expensesQuery.ToListAsync(), tenantId);
|
||||
|
||||
// Apply permission-based filtering BEFORE any other filters or pagination.
|
||||
if (hasViewAllPermissionTask.Result)
|
||||
if (hasViewAllPermission)
|
||||
{
|
||||
expensesQuery = expensesQuery.Where(e => e.CreatedById == loggedInEmployeeId || e.StatusId != Draft);
|
||||
}
|
||||
else if (hasViewSelfPermissionTask.Result)
|
||||
else if (hasViewSelfPermission)
|
||||
{
|
||||
// User only has 'View Self' permission, so restrict the query to their own expenses.
|
||||
_logger.LogInfo("User {EmployeeId} has 'View Self' permission. Restricting query to their expenses.", loggedInEmployeeId);
|
||||
@ -367,11 +360,7 @@ namespace Marco.Pms.Services.Service
|
||||
return ApiResponse<object>.ErrorResponse("Expense Not Found", "Expense Not Found", 404);
|
||||
}
|
||||
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
var hasManagePermission = await permissionService.HasPermission(PermissionsMaster.ExpenseManage, loggedInEmployee.Id);
|
||||
|
||||
expenseDetails = await GetAllExpnesRelatedTablesForSingle(expense, hasManagePermission, loggedInEmployee.Id, expense.TenantId);
|
||||
expenseDetails = await GetAllExpnesRelatedTablesForSingle(expense, loggedInEmployee.Id, expense.TenantId);
|
||||
}
|
||||
var vm = _mapper.Map<ExpenseDetailsVM>(expenseDetails);
|
||||
|
||||
@ -452,10 +441,13 @@ namespace Marco.Pms.Services.Service
|
||||
return ApiResponse<object>.ErrorResponse("Databsae Exception", ExceptionMapper(dbEx), 500);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<object>> GetFilterObjectAsync(Employee loggedInEmployee, Guid tenantId)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInfo("Fetching expenses for tenant: {TenantId}", tenantId);
|
||||
|
||||
var expenses = await _context.Expenses
|
||||
.Include(e => e.PaidBy)
|
||||
.Include(e => e.CreatedBy)
|
||||
@ -464,6 +456,8 @@ namespace Marco.Pms.Services.Service
|
||||
.Where(e => e.TenantId == tenantId)
|
||||
.ToListAsync();
|
||||
|
||||
_logger.LogInfo("Fetched {ExpenseCount} expenses", expenses.Count);
|
||||
|
||||
var projectIds = expenses.Select(e => e.ProjectId).ToList();
|
||||
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
@ -490,6 +484,8 @@ namespace Marco.Pms.Services.Service
|
||||
var projects = infraProjectTask.Result;
|
||||
projects.AddRange(serviceProjectTask.Result);
|
||||
|
||||
_logger.LogInfo("Fetched {ProjectCount} projects", projects.Count);
|
||||
|
||||
// Construct the final object from the results of the completed tasks.
|
||||
var response = new
|
||||
{
|
||||
@ -499,12 +495,15 @@ namespace Marco.Pms.Services.Service
|
||||
Status = expenses.Where(e => e.Status != null).Select(e => new { Id = e.Status!.Id, Name = e.Status.Name }).Distinct().ToList(),
|
||||
ExpenseCategory = expenses.Where(e => e.ExpenseCategory != null).Select(e => new { Id = e.ExpenseCategory!.Id, Name = e.ExpenseCategory.Name }).Distinct().ToList()
|
||||
};
|
||||
|
||||
_logger.LogInfo("Successfully fetched the filter list");
|
||||
|
||||
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 expenses");
|
||||
return ApiResponse<object>.ErrorResponse("Internal Exception Occured", ExceptionMapper(ex), 500);
|
||||
_logger.LogError(ex, "Exception occurred while fetching the list filters for expenses");
|
||||
return ApiResponse<object>.ErrorResponse("Internal Exception Occurred", ExceptionMapper(ex), 500);
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,13 +528,8 @@ namespace Marco.Pms.Services.Service
|
||||
{
|
||||
// 1. Authorization & Validation: Run all I/O-bound checks concurrently using factories for safety.
|
||||
|
||||
// PERMISSION CHECKS: Use IServiceScopeFactory for thread-safe access to scoped services.
|
||||
var hasUploadPermissionTask = Task.Run(async () => // Task.Run is acceptable here to create a new scope, but let's do it cleaner.
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseUpload, loggedInEmployee.Id);
|
||||
});
|
||||
// PERMISSION CHECKS
|
||||
var hasUploadPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseUpload, loggedInEmployee.Id);
|
||||
|
||||
// VALIDATION CHECKS: Use IDbContextFactory for thread-safe, parallel database queries.
|
||||
// Each task gets its own DbContext instance.
|
||||
@ -798,10 +792,9 @@ namespace Marco.Pms.Services.Service
|
||||
}
|
||||
else if (requiredPermissions.Any())
|
||||
{
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
foreach (var permission in requiredPermissions)
|
||||
{
|
||||
if (await permissionService.HasPermission(permission.PermissionId, loggedInEmployee.Id) && model.StatusId != Review)
|
||||
if (await HasPermissionAsync(permission.PermissionId, loggedInEmployee.Id) && model.StatusId != Review)
|
||||
{
|
||||
hasPermission = true;
|
||||
break;
|
||||
@ -1046,10 +1039,8 @@ namespace Marco.Pms.Services.Service
|
||||
"The employee Id in the path does not match the Id in the request body.", 400);
|
||||
}
|
||||
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
|
||||
var hasManagePermission = await permissionService.HasPermission(PermissionsMaster.ExpenseManage, loggedInEmployee.Id);
|
||||
// Check if the employee has the required permission
|
||||
var hasManagePermission = await HasPermissionAsync(PermissionsMaster.ExpenseManage, loggedInEmployee.Id);
|
||||
|
||||
var existingExpense = await _context.Expenses
|
||||
.Include(e => e.ExpenseCategory)
|
||||
@ -1242,12 +1233,7 @@ namespace Marco.Pms.Services.Service
|
||||
return await context.Expenses.Where(e => e.Id == id && e.StatusId == Draft && e.TenantId == tenantId).FirstOrDefaultAsync();
|
||||
});
|
||||
|
||||
var hasAprrovePermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseApprove, loggedInEmployee.Id);
|
||||
});
|
||||
var hasAprrovePermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseApprove, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(expenseTask, hasAprrovePermissionTask);
|
||||
|
||||
@ -1344,23 +1330,16 @@ namespace Marco.Pms.Services.Service
|
||||
|
||||
try
|
||||
{
|
||||
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);
|
||||
});
|
||||
// Check if the user has the required permission
|
||||
var hasViewSelfPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseViewSelf, loggedInEmployee.Id);
|
||||
var hasViewAllPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseViewAll, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(hasViewSelfPermissionTask, hasViewAllPermissionTask);
|
||||
|
||||
if (!hasViewAllPermissionTask.Result && !hasViewSelfPermissionTask.Result)
|
||||
var hasViewAllPermission = hasViewAllPermissionTask.Result;
|
||||
var hasViewSelfPermission = hasViewSelfPermissionTask.Result;
|
||||
|
||||
if (!hasViewAllPermission && !hasViewSelfPermission)
|
||||
{
|
||||
// User has neither required permission. Deny access.
|
||||
_logger.LogWarning("Access DENIED for employee {EmployeeId} attempting to get payment request list.", loggedInEmployee.Id);
|
||||
@ -1383,7 +1362,8 @@ namespace Marco.Pms.Services.Service
|
||||
pr.CreatedBy != null &&
|
||||
pr.CreatedBy.JobRole != null);
|
||||
|
||||
if (hasViewSelfPermissionTask.Result && !hasViewAllPermissionTask.Result)
|
||||
// Filter the query based on the user's permissions
|
||||
if (hasViewSelfPermission && !hasViewAllPermission)
|
||||
{
|
||||
paymentRequestQuery = paymentRequestQuery.Where(pr => pr.CreatedById == loggedInEmployee.Id);
|
||||
}
|
||||
@ -1393,6 +1373,7 @@ namespace Marco.Pms.Services.Service
|
||||
// Deserialize and apply advanced filter if provided
|
||||
PaymentRequestFilter? paymentRequestFilter = TryDeserializePaymentRequestFilter(filter);
|
||||
|
||||
// filter the query based on the advanced filter
|
||||
if (paymentRequestFilter != null)
|
||||
{
|
||||
if (paymentRequestFilter.ProjectIds?.Any() ?? false)
|
||||
@ -1456,10 +1437,11 @@ namespace Marco.Pms.Services.Service
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
// Calculate total pages
|
||||
var totalPages = (int)Math.Ceiling((double)totalEntities / pageSize);
|
||||
|
||||
// Fetch projects for each payment request
|
||||
var projectIds = paymentRequests.Select(pr => pr.ProjectId).ToList();
|
||||
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
@ -1477,6 +1459,7 @@ namespace Marco.Pms.Services.Service
|
||||
var projects = infraProjectTask.Result;
|
||||
projects.AddRange(serviceProjectTask.Result);
|
||||
|
||||
// mapping to view model
|
||||
var results = paymentRequests.Select(pr =>
|
||||
{
|
||||
var result = _mapper.Map<PaymentRequestVM>(pr);
|
||||
@ -1523,26 +1506,9 @@ namespace Marco.Pms.Services.Service
|
||||
}
|
||||
|
||||
// Check user permissions concurrently
|
||||
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 hasViewSelfPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseViewSelf, loggedInEmployee.Id);
|
||||
var hasViewAllPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseViewAll, loggedInEmployee.Id);
|
||||
var hasReviewPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseReview, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(hasViewSelfPermissionTask, hasViewAllPermissionTask, hasReviewPermissionTask);
|
||||
|
||||
@ -1550,26 +1516,9 @@ namespace Marco.Pms.Services.Service
|
||||
bool hasViewAllPermission = hasViewAllPermissionTask.Result;
|
||||
bool hasReviewPermission = hasReviewPermissionTask.Result;
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
var hasManagePermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseManage, loggedInEmployee.Id);
|
||||
});
|
||||
var hasApprovePermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseApprove, loggedInEmployee.Id);
|
||||
var hasProcessPermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseProcess, loggedInEmployee.Id);
|
||||
var hasManagePermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseManage, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(hasApprovePermissionTask, hasProcessPermissionTask, hasManagePermissionTask);
|
||||
|
||||
@ -1581,7 +1530,7 @@ namespace Marco.Pms.Services.Service
|
||||
if (!hasViewSelfPermission && !hasViewAllPermission && !hasReviewPermission && !hasApprovePermission && !hasProcessPermission)
|
||||
{
|
||||
_logger.LogWarning("Access DENIED: Employee {EmployeeId} has no permission to view payment requests.", loggedInEmployee.Id);
|
||||
return ApiResponse<object>.SuccessResponse(new { }, "You do not have permission to view any payment request.", 200);
|
||||
return ApiResponse<object>.ErrorResponse("You do not have permission to view payment requests.", "You do not have permission to view any payment request.", 403);
|
||||
}
|
||||
|
||||
// Query payment request with all necessary navigation properties and validation constraints
|
||||
@ -1864,9 +1813,7 @@ namespace Marco.Pms.Services.Service
|
||||
|
||||
try
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
var hasUploadPermission = await permissionService.HasPermission(PermissionsMaster.ExpenseUpload, loggedInEmployee.Id);
|
||||
var hasUploadPermission = await HasPermissionAsync(PermissionsMaster.ExpenseUpload, loggedInEmployee.Id);
|
||||
|
||||
if (!hasUploadPermission)
|
||||
{
|
||||
@ -1890,13 +1837,8 @@ namespace Marco.Pms.Services.Service
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.ExpensesStatusMaster.FirstOrDefaultAsync(es => es.Id == Draft && es.IsActive);
|
||||
});
|
||||
var projectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Projects.FirstOrDefaultAsync(P => model.ProjectId.HasValue && P.Id == model.ProjectId.Value);
|
||||
});
|
||||
|
||||
await Task.WhenAll(expenseCategoryTask, currencyTask, expenseStatusTask, projectTask);
|
||||
await Task.WhenAll(expenseCategoryTask, currencyTask, expenseStatusTask);
|
||||
|
||||
var expenseCategory = await expenseCategoryTask;
|
||||
if (expenseCategory == null)
|
||||
@ -1919,8 +1861,42 @@ namespace Marco.Pms.Services.Service
|
||||
return ApiResponse<object>.ErrorResponse("Expense Status (Draft) not found.", "Expense Status not found.", 404);
|
||||
}
|
||||
|
||||
var project = await projectTask;
|
||||
// Project is optional so no error if not found
|
||||
BasicProjectVM? project = null;
|
||||
|
||||
if (model.ProjectId.HasValue && model.ProjectId.Value != Guid.Empty)
|
||||
{
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Projects
|
||||
.AsNoTracking()
|
||||
.Where(p => p.Id == model.ProjectId && p.TenantId == tenantId)
|
||||
.Select(p => _mapper.Map<BasicProjectVM>(p))
|
||||
.FirstOrDefaultAsync();
|
||||
});
|
||||
var serviceProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.ServiceProjects
|
||||
.AsNoTracking()
|
||||
.Where(sp => sp.Id == model.ProjectId && sp.TenantId == tenantId)
|
||||
.Select(sp => _mapper.Map<BasicProjectVM>(sp))
|
||||
.FirstOrDefaultAsync();
|
||||
});
|
||||
|
||||
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
||||
|
||||
var infraProject = infraProjectTask.Result;
|
||||
var serviceProject = serviceProjectTask.Result;
|
||||
|
||||
if (infraProject == null && serviceProject == null)
|
||||
{
|
||||
_logger.LogWarning("Cannot proceed: Both infrastructure and service projects are not found.");
|
||||
return ApiResponse<object>.ErrorResponse("Cannot proceed: Both infrastructure and service projects are not found.",
|
||||
"Cannot proceed: Both infrastructure and service projects are not found.", 404);
|
||||
}
|
||||
project = infraProject ?? serviceProject;
|
||||
}
|
||||
|
||||
// Generate unique UID postfix based on existing requests for the current prefix
|
||||
var lastPR = await _context.PaymentRequests.Where(pr => pr.UIDPrefix == uIDPrefix)
|
||||
@ -1999,7 +1975,7 @@ namespace Marco.Pms.Services.Service
|
||||
response.Currency = currency;
|
||||
response.ExpenseCategory = _mapper.Map<ExpenseCategoryMasterVM>(expenseCategory);
|
||||
response.ExpenseStatus = _mapper.Map<ExpensesStatusMasterVM>(expenseStatus);
|
||||
response.Project = _mapper.Map<BasicProjectVM>(project);
|
||||
response.Project = project;
|
||||
response.CreatedBy = _mapper.Map<BasicEmployeeVM>(loggedInEmployee);
|
||||
|
||||
_logger.LogInfo("Payment request created successfully with UID: {PaymentRequestUID}", response.PaymentRequestUID);
|
||||
@ -2517,12 +2493,7 @@ namespace Marco.Pms.Services.Service
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.CurrencyMaster.FirstOrDefaultAsync(c => c.Id == model.CurrencyId);
|
||||
});
|
||||
var hasManagePermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseManage, loggedInEmployee.Id);
|
||||
});
|
||||
var hasManagePermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseManage, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(expenseCategoryTask, currencyTask, hasManagePermissionTask);
|
||||
|
||||
@ -2542,7 +2513,7 @@ namespace Marco.Pms.Services.Service
|
||||
|
||||
BasicProjectVM? project = null;
|
||||
|
||||
if (model.ProjectId.HasValue)
|
||||
if (model.ProjectId.HasValue && model.ProjectId.Value != Guid.Empty)
|
||||
{
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
{
|
||||
@ -2746,12 +2717,7 @@ namespace Marco.Pms.Services.Service
|
||||
return await context.PaymentRequests.AsNoTracking().Where(e => e.Id == id && e.ExpenseStatusId == Draft && e.TenantId == tenantId).FirstOrDefaultAsync();
|
||||
});
|
||||
|
||||
var hasAprrovePermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseApprove, loggedInEmployee.Id);
|
||||
});
|
||||
var hasAprrovePermissionTask = HasPermissionAsync(PermissionsMaster.ExpenseApprove, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(paymentRequestTask, hasAprrovePermissionTask);
|
||||
|
||||
@ -2849,19 +2815,8 @@ namespace Marco.Pms.Services.Service
|
||||
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);
|
||||
});
|
||||
var hasViewSelfPermissionTask = HasPermissionAsync(PermissionsMaster.ViewSelfRecurring, loggedInEmployee.Id);
|
||||
var hasViewAllPermissionTask = HasPermissionAsync(PermissionsMaster.ViewAllRecurring, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(hasViewSelfPermissionTask, hasViewAllPermissionTask);
|
||||
|
||||
@ -2880,7 +2835,6 @@ namespace Marco.Pms.Services.Service
|
||||
.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);
|
||||
|
||||
@ -2959,11 +2913,31 @@ namespace Marco.Pms.Services.Service
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
var projectIds = recurringPayments.Select(pr => pr.ProjectId).ToList();
|
||||
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).Select(p => _mapper.Map<BasicProjectVM>(p)).ToListAsync();
|
||||
});
|
||||
|
||||
var serviceProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.ServiceProjects.Where(sp => projectIds.Contains(sp.Id) && sp.TenantId == tenantId).Select(sp => _mapper.Map<BasicProjectVM>(sp)).ToListAsync();
|
||||
});
|
||||
|
||||
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
||||
|
||||
var projects = infraProjectTask.Result;
|
||||
projects.AddRange(serviceProjectTask.Result);
|
||||
|
||||
// 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}";
|
||||
vm.Project = projects.FirstOrDefault(p => p.Id == rp.ProjectId);
|
||||
return vm;
|
||||
}).ToList();
|
||||
|
||||
@ -3005,26 +2979,9 @@ namespace Marco.Pms.Services.Service
|
||||
}
|
||||
|
||||
// Concurrent permission checks for view-self, view-all, and manage 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);
|
||||
});
|
||||
|
||||
var hasManagePermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ManageRecurring, loggedInEmployee.Id);
|
||||
});
|
||||
var hasViewSelfPermissionTask = HasPermissionAsync(PermissionsMaster.ViewSelfRecurring, loggedInEmployee.Id);
|
||||
var hasViewAllPermissionTask = HasPermissionAsync(PermissionsMaster.ViewAllRecurring, loggedInEmployee.Id);
|
||||
var hasManagePermissionTask = HasPermissionAsync(PermissionsMaster.ManageRecurring, loggedInEmployee.Id);
|
||||
|
||||
await Task.WhenAll(hasViewSelfPermissionTask, hasViewAllPermissionTask, hasManagePermissionTask);
|
||||
|
||||
@ -3042,7 +2999,6 @@ namespace Marco.Pms.Services.Service
|
||||
// Query recurring payment by Id or UID with navigation and tenant checks
|
||||
var recurringPayment = await _context.RecurringPayments
|
||||
.Include(rp => rp.Currency)
|
||||
.Include(rp => rp.Project)
|
||||
.Include(rp => rp.ExpenseCategory)
|
||||
.Include(rp => rp.Status)
|
||||
.Include(rp => rp.CreatedBy).ThenInclude(e => e!.JobRole)
|
||||
@ -3100,9 +3056,34 @@ namespace Marco.Pms.Services.Service
|
||||
var employees = employeeTask.Result;
|
||||
var paymentRequests = paymentRequestTask.Result;
|
||||
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Projects
|
||||
.AsNoTracking()
|
||||
.Where(p => p.Id == recurringPayment.ProjectId && p.TenantId == tenantId)
|
||||
.Select(p => _mapper.Map<BasicProjectVM>(p))
|
||||
.FirstOrDefaultAsync();
|
||||
});
|
||||
var serviceProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.ServiceProjects
|
||||
.AsNoTracking()
|
||||
.Where(sp => sp.Id == recurringPayment.ProjectId && sp.TenantId == tenantId)
|
||||
.Select(sp => _mapper.Map<BasicProjectVM>(sp))
|
||||
.FirstOrDefaultAsync();
|
||||
});
|
||||
|
||||
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
||||
|
||||
var infraProject = infraProjectTask.Result;
|
||||
var serviceProject = serviceProjectTask.Result;
|
||||
|
||||
// Map main response DTO and enrich with notification employees and payment requests
|
||||
var response = _mapper.Map<RecurringPaymentDetailsVM>(recurringPayment);
|
||||
response.NotifyTo = _mapper.Map<List<BasicEmployeeVM>>(employees);
|
||||
response.Project = infraProject ?? serviceProject;
|
||||
response.PaymentRequests = paymentRequests;
|
||||
|
||||
_logger.LogInfo("Recurring payment details fetched successfully for RecurringPaymentId: {RecurringPaymentId} by EmployeeId: {EmployeeId}",
|
||||
@ -3135,9 +3116,7 @@ namespace Marco.Pms.Services.Service
|
||||
return ApiResponse<object>.ErrorResponse("End date cannot be earlier than today.", "End date cannot be earlier than today.", 400);
|
||||
}
|
||||
// Check if user has permission to create recurring payment templates
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
var hasPermission = await permissionService.HasPermission(PermissionsMaster.ManageRecurring, loggedInEmployee.Id);
|
||||
var hasPermission = await HasPermissionAsync(PermissionsMaster.ManageRecurring, loggedInEmployee.Id);
|
||||
|
||||
if (!hasPermission)
|
||||
{
|
||||
@ -3164,13 +3143,7 @@ namespace Marco.Pms.Services.Service
|
||||
return await context.CurrencyMaster.FirstOrDefaultAsync(c => c.Id == model.CurrencyId);
|
||||
});
|
||||
|
||||
var projectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return model.ProjectId.HasValue ? await context.Projects.FirstOrDefaultAsync(p => p.Id == model.ProjectId.Value) : null;
|
||||
});
|
||||
|
||||
await Task.WhenAll(expenseCategoryTask, recurringStatusTask, currencyTask, projectTask);
|
||||
await Task.WhenAll(expenseCategoryTask, recurringStatusTask, currencyTask);
|
||||
|
||||
var expenseCategory = await expenseCategoryTask;
|
||||
if (expenseCategory == null)
|
||||
@ -3193,7 +3166,42 @@ namespace Marco.Pms.Services.Service
|
||||
return ApiResponse<object>.ErrorResponse("Currency not found.", "Currency not found.", 404);
|
||||
}
|
||||
|
||||
var project = await projectTask; // Optional, can be null
|
||||
BasicProjectVM? project = null;
|
||||
|
||||
if (model.ProjectId.HasValue && model.ProjectId.Value != Guid.Empty)
|
||||
{
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Projects
|
||||
.AsNoTracking()
|
||||
.Where(p => p.Id == model.ProjectId && p.TenantId == tenantId)
|
||||
.Select(p => _mapper.Map<BasicProjectVM>(p))
|
||||
.FirstOrDefaultAsync();
|
||||
});
|
||||
var serviceProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.ServiceProjects
|
||||
.AsNoTracking()
|
||||
.Where(sp => sp.Id == model.ProjectId && sp.TenantId == tenantId)
|
||||
.Select(sp => _mapper.Map<BasicProjectVM>(sp))
|
||||
.FirstOrDefaultAsync();
|
||||
});
|
||||
|
||||
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
||||
|
||||
var infraProject = infraProjectTask.Result;
|
||||
var serviceProject = serviceProjectTask.Result;
|
||||
|
||||
if (infraProject == null && serviceProject == null)
|
||||
{
|
||||
_logger.LogWarning("Cannot proceed: Both infrastructure and service projects are not found.");
|
||||
return ApiResponse<object>.ErrorResponse("Cannot proceed: Both infrastructure and service projects are not found.",
|
||||
"Cannot proceed: Both infrastructure and service projects are not found.", 404);
|
||||
}
|
||||
project = infraProject ?? serviceProject;
|
||||
}
|
||||
|
||||
// Generate unique UID prefix and postfix per current month/year
|
||||
string uIDPrefix = $"RP/{DateTime.Now:MMyy}";
|
||||
@ -3224,7 +3232,7 @@ namespace Marco.Pms.Services.Service
|
||||
response.ExpenseCategory = _mapper.Map<ExpenseCategoryMasterVM>(expenseCategory);
|
||||
response.Status = recurringStatus;
|
||||
response.Currency = currency;
|
||||
response.Project = _mapper.Map<BasicProjectVM>(project);
|
||||
response.Project = project;
|
||||
|
||||
_logger.LogInfo("Recurring Payment Template created successfully with UID: {RecurringPaymentUId} by EmployeeId: {EmployeeId}", response.RecurringPaymentUId, loggedInEmployee.Id);
|
||||
|
||||
@ -3387,7 +3395,6 @@ namespace Marco.Pms.Services.Service
|
||||
.Include(rp => rp.Currency)
|
||||
.Include(rp => rp.ExpenseCategory)
|
||||
.Include(rp => rp.Status)
|
||||
.Include(rp => rp.Project)
|
||||
.AsNoTracking()
|
||||
.Where(rp => newRecurringTemplateIds.Contains(rp.Id))
|
||||
.ToListAsync();
|
||||
@ -3395,11 +3402,35 @@ namespace Marco.Pms.Services.Service
|
||||
_logger.LogInfo("{Count} payment requests created successfully from recurring payments by EmployeeId: {EmployeeId} for TenantId: {TenantId}",
|
||||
paymentRequests.Count, loggedInEmployee.Id, tenantId);
|
||||
|
||||
var response = newRecurringPayments.Select(rp => new
|
||||
var projectIds = recurringPayments.Select(pr => pr.ProjectId).ToList();
|
||||
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
{
|
||||
RecurringPayment = _mapper.Map<RecurringPaymentVM>(rp),
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).Select(p => _mapper.Map<BasicProjectVM>(p)).ToListAsync();
|
||||
});
|
||||
|
||||
var serviceProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.ServiceProjects.Where(sp => projectIds.Contains(sp.Id) && sp.TenantId == tenantId).Select(sp => _mapper.Map<BasicProjectVM>(sp)).ToListAsync();
|
||||
});
|
||||
|
||||
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
||||
|
||||
var projects = infraProjectTask.Result;
|
||||
projects.AddRange(serviceProjectTask.Result);
|
||||
|
||||
var response = newRecurringPayments.Select(rp =>
|
||||
{
|
||||
var result = _mapper.Map<RecurringPaymentVM>(rp);
|
||||
result.Project = projects.FirstOrDefault(p => p.Id == rp.ProjectId);
|
||||
return new
|
||||
{
|
||||
RecurringPayment = result,
|
||||
DueDate = DateTime.UtcNow.AddDays(rp.PaymentBufferDays),
|
||||
Emails = rp.NotifyTo.Split(",", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
};
|
||||
}).ToList();
|
||||
|
||||
return ApiResponse<object>.SuccessResponse(response, $"{paymentRequests.Count} conversion(s) to payment request completed successfully.", 201);
|
||||
@ -3450,9 +3481,7 @@ namespace Marco.Pms.Services.Service
|
||||
}
|
||||
|
||||
// Permission check for managing recurring payments
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
var hasPermission = await permissionService.HasPermission(PermissionsMaster.ManageRecurring, loggedInEmployee.Id);
|
||||
var hasPermission = await HasPermissionAsync(PermissionsMaster.ManageRecurring, loggedInEmployee.Id);
|
||||
|
||||
if (!hasPermission)
|
||||
{
|
||||
@ -3479,13 +3508,7 @@ namespace Marco.Pms.Services.Service
|
||||
return await context.CurrencyMaster.FirstOrDefaultAsync(c => c.Id == model.CurrencyId);
|
||||
});
|
||||
|
||||
var projectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return model.ProjectId.HasValue ? await context.Projects.FirstOrDefaultAsync(p => p.Id == model.ProjectId.Value) : null;
|
||||
});
|
||||
|
||||
await Task.WhenAll(expenseCategoryTask, recurringStatusTask, currencyTask, projectTask);
|
||||
await Task.WhenAll(expenseCategoryTask, recurringStatusTask, currencyTask);
|
||||
|
||||
var expenseCategory = await expenseCategoryTask;
|
||||
if (expenseCategory == null)
|
||||
@ -3508,7 +3531,42 @@ namespace Marco.Pms.Services.Service
|
||||
return ApiResponse<object>.ErrorResponse("Currency not found.", "Currency not found.", 404);
|
||||
}
|
||||
|
||||
var project = await projectTask; // Optional
|
||||
BasicProjectVM? project = null;
|
||||
|
||||
if (model.ProjectId.HasValue && model.ProjectId.Value != Guid.Empty)
|
||||
{
|
||||
var infraProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Projects
|
||||
.AsNoTracking()
|
||||
.Where(p => p.Id == model.ProjectId && p.TenantId == tenantId)
|
||||
.Select(p => _mapper.Map<BasicProjectVM>(p))
|
||||
.FirstOrDefaultAsync();
|
||||
});
|
||||
var serviceProjectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.ServiceProjects
|
||||
.AsNoTracking()
|
||||
.Where(sp => sp.Id == model.ProjectId && sp.TenantId == tenantId)
|
||||
.Select(sp => _mapper.Map<BasicProjectVM>(sp))
|
||||
.FirstOrDefaultAsync();
|
||||
});
|
||||
|
||||
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
||||
|
||||
var infraProject = infraProjectTask.Result;
|
||||
var serviceProject = serviceProjectTask.Result;
|
||||
|
||||
if (infraProject == null && serviceProject == null)
|
||||
{
|
||||
_logger.LogWarning("Cannot proceed: Both infrastructure and service projects are not found.");
|
||||
return ApiResponse<object>.ErrorResponse("Cannot proceed: Both infrastructure and service projects are not found.",
|
||||
"Cannot proceed: Both infrastructure and service projects are not found.", 404);
|
||||
}
|
||||
project = infraProject ?? serviceProject;
|
||||
}
|
||||
|
||||
// Retrieve the existing recurring payment record for update
|
||||
var recurringPayment = await _context.RecurringPayments
|
||||
@ -3535,7 +3593,7 @@ namespace Marco.Pms.Services.Service
|
||||
response.ExpenseCategory = _mapper.Map<ExpenseCategoryMasterVM>(expenseCategory);
|
||||
response.Status = recurringStatus;
|
||||
response.Currency = currency;
|
||||
response.Project = _mapper.Map<BasicProjectVM>(project);
|
||||
response.Project = project;
|
||||
|
||||
_logger.LogInfo("Recurring Payment Template updated successfully with UID: {RecurringPaymentUId} by EmployeeId: {EmployeeId}", response.RecurringPaymentUId, loggedInEmployee.Id);
|
||||
|
||||
@ -3665,6 +3723,12 @@ namespace Marco.Pms.Services.Service
|
||||
#endregion
|
||||
|
||||
#region =================================================================== Helper Functions ===================================================================
|
||||
private async Task<bool> HasPermissionAsync(Guid permission, Guid employeeId)
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(permission, employeeId);
|
||||
}
|
||||
private static object ExceptionMapper(Exception ex)
|
||||
{
|
||||
return new
|
||||
@ -3680,7 +3744,7 @@ namespace Marco.Pms.Services.Service
|
||||
}
|
||||
};
|
||||
}
|
||||
private async Task<ExpenseDetailsMongoDB> GetAllExpnesRelatedTablesForSingle(Expenses model, bool hasManagePermission, Guid loggedInEmployeeId, Guid tenantId)
|
||||
private async Task<ExpenseDetailsMongoDB> GetAllExpnesRelatedTablesForSingle(Expenses model, Guid loggedInEmployeeId, Guid tenantId)
|
||||
{
|
||||
var statusMappingTask = Task.Run(async () =>
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user