Changed theexpenses Vms
This commit is contained in:
parent
061512d501
commit
ca3e47c1e6
@ -248,6 +248,7 @@ namespace Marco.Pms.Services.MappingProfiles
|
||||
dest => dest.Id,
|
||||
opt => opt.MapFrom(src => Guid.Parse(src.Id)));
|
||||
|
||||
CreateMap<Expenses, ExpenseDetailsVM>();
|
||||
CreateMap<ExpenseDetailsMongoDB, ExpenseDetailsVM>()
|
||||
.ForMember(
|
||||
dest => dest.Id,
|
||||
|
@ -129,6 +129,16 @@ namespace Marco.Pms.Services.Service
|
||||
// 3. --- Build Base Query and Apply Permissions ---
|
||||
// Start with a base IQueryable. Filters will be chained onto this.
|
||||
var expensesQuery = _context.Expenses
|
||||
.Include(e => e.PaidBy)
|
||||
.Include(e => e.CreatedBy)
|
||||
.Include(e => e.ProcessedBy)
|
||||
.Include(e => e.ApprovedBy)
|
||||
.Include(e => e.ReviewedBy)
|
||||
.Include(e => e.PaymentMode)
|
||||
.Include(e => e.Project)
|
||||
.Include(e => e.PaymentMode)
|
||||
.Include(e => e.ExpensesType)
|
||||
.Include(e => e.Status)
|
||||
.Where(e => e.TenantId == tenantId); // Always filter by TenantId first.
|
||||
|
||||
if (cacheList == null)
|
||||
@ -213,7 +223,8 @@ namespace Marco.Pms.Services.Service
|
||||
return ApiResponse<object>.SuccessResponse(new List<ExpenseList>(), "No expenses found for the given criteria.", 200);
|
||||
}
|
||||
|
||||
expenseVM = await GetAllExpnesRelatedTables(expensesList, tenantId);
|
||||
//expenseVM = await GetAllExpnesRelatedTables(expensesList, tenantId);
|
||||
expenseVM = _mapper.Map<List<ExpenseList>>(expensesList);
|
||||
totalPages = (int)Math.Ceiling((double)totalEntites / pageSize);
|
||||
|
||||
}
|
||||
@ -276,7 +287,18 @@ namespace Marco.Pms.Services.Service
|
||||
ExpenseDetailsMongoDB? expenseDetails = null;
|
||||
if (expenseDetails == null)
|
||||
{
|
||||
var expense = await _context.Expenses.AsNoTracking().FirstOrDefaultAsync(e => e.Id == id && e.TenantId == tenantId);
|
||||
var expense = await _context.Expenses
|
||||
.Include(e => e.PaidBy)
|
||||
.Include(e => e.CreatedBy)
|
||||
.Include(e => e.ProcessedBy)
|
||||
.Include(e => e.ApprovedBy)
|
||||
.Include(e => e.ReviewedBy)
|
||||
.Include(e => e.PaymentMode)
|
||||
.Include(e => e.Project)
|
||||
.Include(e => e.PaymentMode)
|
||||
.Include(e => e.ExpensesType)
|
||||
.Include(e => e.Status)
|
||||
.AsNoTracking().FirstOrDefaultAsync(e => e.Id == id && e.TenantId == tenantId);
|
||||
|
||||
if (expense == null)
|
||||
{
|
||||
@ -458,13 +480,6 @@ namespace Marco.Pms.Services.Service
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseUpload, loggedInEmployee.Id);
|
||||
});
|
||||
|
||||
var hasProjectPermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasProjectPermission(loggedInEmployee, dto.ProjectId);
|
||||
});
|
||||
|
||||
// VALIDATION CHECKS: Use IDbContextFactory for thread-safe, parallel database queries.
|
||||
// Each task gets its own DbContext instance.
|
||||
var projectTask = Task.Run(async () =>
|
||||
@ -507,12 +522,12 @@ namespace Marco.Pms.Services.Service
|
||||
|
||||
// Await all prerequisite checks at once.
|
||||
await Task.WhenAll(
|
||||
hasUploadPermissionTask, hasProjectPermissionTask,
|
||||
hasUploadPermissionTask,
|
||||
projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask
|
||||
);
|
||||
|
||||
// 2. Aggregate and Check Results
|
||||
if (!await hasUploadPermissionTask || !await hasProjectPermissionTask)
|
||||
if (!await hasUploadPermissionTask)
|
||||
{
|
||||
_logger.LogWarning("Access DENIED for employee {EmployeeId} on project {ProjectId}.", loggedInEmployee.Id, dto.ProjectId);
|
||||
return ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to upload expenses for this project.", 403);
|
||||
@ -1217,46 +1232,6 @@ namespace Marco.Pms.Services.Service
|
||||
|
||||
private async Task<ExpenseDetailsMongoDB> GetAllExpnesRelatedTablesForSingle(Expenses model, Guid tenantId)
|
||||
{
|
||||
var projectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Id == model.ProjectId && p.TenantId == tenantId);
|
||||
});
|
||||
var paidByTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.PaidById && e.TenantId == tenantId);
|
||||
});
|
||||
var createdByTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.CreatedById && e.TenantId == tenantId);
|
||||
});
|
||||
var reviewedByTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.ReviewedById && e.TenantId == tenantId);
|
||||
});
|
||||
var approvedByTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.ApprovedById && e.TenantId == tenantId);
|
||||
});
|
||||
var processedByTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.ProcessedById && e.TenantId == tenantId);
|
||||
});
|
||||
var expenseTypeTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.ExpensesTypeMaster.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.ExpensesTypeId && et.TenantId == tenantId);
|
||||
});
|
||||
var paymentModeTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(pm => pm.Id == model.PaymentModeId && pm.TenantId == tenantId);
|
||||
});
|
||||
var statusMappingTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
@ -1304,29 +1279,20 @@ namespace Marco.Pms.Services.Service
|
||||
});
|
||||
|
||||
// Await all prerequisite checks at once.
|
||||
await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, reviewedByTask, approvedByTask,
|
||||
processedByTask, statusTask, billAttachmentsTask);
|
||||
await Task.WhenAll(statusTask, billAttachmentsTask);
|
||||
|
||||
var project = projectTask.Result;
|
||||
var expenseType = expenseTypeTask.Result;
|
||||
var paymentMode = paymentModeTask.Result;
|
||||
var statusMapping = statusMappingTask.Result;
|
||||
var paidBy = paidByTask.Result;
|
||||
var createdBy = createdByTask.Result;
|
||||
var reviewedBy = reviewedByTask.Result;
|
||||
var approvedBy = approvedByTask.Result;
|
||||
var processedBy = processedByTask.Result;
|
||||
var billAttachment = billAttachmentsTask.Result;
|
||||
|
||||
|
||||
var response = _mapper.Map<ExpenseDetailsMongoDB>(model);
|
||||
|
||||
response.Project = _mapper.Map<ProjectBasicMongoDB>(project);
|
||||
response.PaidBy = _mapper.Map<BasicEmployeeMongoDB>(paidBy);
|
||||
response.CreatedBy = _mapper.Map<BasicEmployeeMongoDB>(createdBy);
|
||||
response.ReviewedBy = _mapper.Map<BasicEmployeeMongoDB>(reviewedBy);
|
||||
response.ApprovedBy = _mapper.Map<BasicEmployeeMongoDB>(approvedBy);
|
||||
response.ProcessedBy = _mapper.Map<BasicEmployeeMongoDB>(processedBy);
|
||||
response.Project = _mapper.Map<ProjectBasicMongoDB>(model.Project);
|
||||
response.PaidBy = _mapper.Map<BasicEmployeeMongoDB>(model.PaidBy);
|
||||
response.CreatedBy = _mapper.Map<BasicEmployeeMongoDB>(model.CreatedBy);
|
||||
response.ReviewedBy = _mapper.Map<BasicEmployeeMongoDB>(model.ReviewedBy);
|
||||
response.ApprovedBy = _mapper.Map<BasicEmployeeMongoDB>(model.ApprovedBy);
|
||||
response.ProcessedBy = _mapper.Map<BasicEmployeeMongoDB>(model.ProcessedBy);
|
||||
if (statusMapping != null)
|
||||
{
|
||||
response.Status = _mapper.Map<ExpensesStatusMasterMongoDB>(statusMapping.Status);
|
||||
@ -1337,8 +1303,8 @@ namespace Marco.Pms.Services.Service
|
||||
var status = statusTask.Result;
|
||||
response.Status = _mapper.Map<ExpensesStatusMasterMongoDB>(status);
|
||||
}
|
||||
response.PaymentMode = _mapper.Map<PaymentModeMatserMongoDB>(paymentMode);
|
||||
response.ExpensesType = _mapper.Map<ExpensesTypeMasterMongoDB>(expenseType);
|
||||
response.PaymentMode = _mapper.Map<PaymentModeMatserMongoDB>(model.PaymentMode);
|
||||
response.ExpensesType = _mapper.Map<ExpensesTypeMasterMongoDB>(model.ExpensesType);
|
||||
if (billAttachment != null) response.Documents = billAttachment.Documents;
|
||||
|
||||
return response;
|
||||
|
@ -48,7 +48,7 @@
|
||||
},
|
||||
"MongoDB": {
|
||||
"SerilogDatabaseUrl": "mongodb://localhost:27017/DotNetLogs",
|
||||
"ConnectionString": "mongodb://localhost:27017/MarcoBMS_Caches?socketTimeoutMS=500&serverSelectionTimeoutMS=500&connectTimeoutMS=500",
|
||||
"ModificationConnectionString": "mongodb://devuser:DevPass123@147.93.98.152:27017/MarcoBMSLocalDev?authSource=admin&eplicaSet=rs01&directConnection=true"
|
||||
"ConnectionString": "mongodb://devuser:DevPass123@147.93.98.152:27017/MarcoBMSCacheLocalDev?authSource=admin&replicaSet=rs01",
|
||||
"ModificationConnectionString": "mongodb://devuser:DevPass123@147.93.98.152:27017/MarcoBMSLocalDev?authSource=admin&replicaSet=rs01&directConnection=true"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user