Added proper logs to all Expesne APIs
This commit is contained in:
parent
ae1222bb96
commit
8b5b0aed4c
@ -56,6 +56,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region =================================================================== Get Functions ===================================================================
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves a paginated list of expenses based on user permissions and optional filters.
|
/// Retrieves a paginated list of expenses based on user permissions and optional filters.
|
||||||
@ -159,9 +160,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
{
|
{
|
||||||
expensesQuery = expensesQuery.Where(e => expenseFilter.CreatedByIds.Contains(e.CreatedById));
|
expensesQuery = expensesQuery.Where(e => expenseFilter.CreatedByIds.Contains(e.CreatedById));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. --- Apply Ordering and Pagination ---
|
// 4. --- Apply Ordering and Pagination ---
|
||||||
@ -247,11 +245,13 @@ namespace Marco.Pms.Services.Service
|
|||||||
expenseDetails = await _cache.AddExpenseByIdAsync(id, tenantId);
|
expenseDetails = await _cache.AddExpenseByIdAsync(id, tenantId);
|
||||||
if (expenseDetails == null)
|
if (expenseDetails == null)
|
||||||
{
|
{
|
||||||
|
_logger.LogWarning("User attempted to fetch expense details with ID {ExpenseId}, but not found in both database and cache", id);
|
||||||
return ApiResponse<object>.ErrorResponse("Expense Not Found", "Expense Not Found", 404);
|
return ApiResponse<object>.ErrorResponse("Expense Not Found", "Expense Not Found", 404);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var vm = await GetAllExpnesRelatedTablesFromMongoDB(expenseDetails);
|
var vm = await GetAllExpnesRelatedTablesFromMongoDB(expenseDetails);
|
||||||
|
|
||||||
|
_logger.LogInfo("Employee {EmployeeId} successfully fetched expense details with ID {ExpenseId}", loggedInEmployee.Id, vm.Id);
|
||||||
return ApiResponse<object>.SuccessResponse(vm, "Successfully fetched the details of expense", 200);
|
return ApiResponse<object>.SuccessResponse(vm, "Successfully fetched the details of expense", 200);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -272,13 +272,12 @@ namespace Marco.Pms.Services.Service
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ApiResponse<object>> GetSupplerNameListAsync(Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> GetSupplerNameListAsync(Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var supplerNameList = await _context.Expenses.Where(e => e.TenantId == tenantId).Select(e => e.SupplerName).Distinct().ToListAsync();
|
var supplerNameList = await _context.Expenses.Where(e => e.TenantId == tenantId).Select(e => e.SupplerName).Distinct().ToListAsync();
|
||||||
_logger.LogInfo("Employee {EmployeeId} fetched list of organizations in a tenant {TenantId}", loggedInEmployee.Id, tenantId);
|
_logger.LogInfo("Employee {EmployeeId} fetched list of suppler names from expenses in a tenant {TenantId}", loggedInEmployee.Id, tenantId);
|
||||||
return ApiResponse<object>.SuccessResponse(supplerNameList, $"{supplerNameList.Count} records of suppler names fetched from expense", 200);
|
return ApiResponse<object>.SuccessResponse(supplerNameList, $"{supplerNameList.Count} records of suppler names fetched from expense", 200);
|
||||||
}
|
}
|
||||||
catch (DbUpdateException dbEx)
|
catch (DbUpdateException dbEx)
|
||||||
@ -299,6 +298,10 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region =================================================================== Post Functions ===================================================================
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new expense entry along with its bill attachments.
|
/// Creates a new expense entry along with its bill attachments.
|
||||||
/// This operation is transactional and performs validations and file uploads concurrently for optimal performance
|
/// This operation is transactional and performs validations and file uploads concurrently for optimal performance
|
||||||
@ -633,6 +636,8 @@ namespace Marco.Pms.Services.Service
|
|||||||
UpdatedAt = DateTime.UtcNow
|
UpdatedAt = DateTime.UtcNow
|
||||||
}, Collection);
|
}, Collection);
|
||||||
|
|
||||||
|
var cacheUpdateTask = _cache.ReplaceExpenseAsync(existingExpense);
|
||||||
|
|
||||||
// Task to get all possible next statuses from the *new* current state to help the UI.
|
// Task to get all possible next statuses from the *new* current state to help the UI.
|
||||||
// NOTE: This now fetches a list of all possible next states, which is more useful for a UI.
|
// NOTE: This now fetches a list of all possible next states, which is more useful for a UI.
|
||||||
var getNextStatusesTask = _dbContextFactory.CreateDbContextAsync().ContinueWith(t =>
|
var getNextStatusesTask = _dbContextFactory.CreateDbContextAsync().ContinueWith(t =>
|
||||||
@ -650,7 +655,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
});
|
});
|
||||||
}).Unwrap();
|
}).Unwrap();
|
||||||
|
|
||||||
await Task.WhenAll(mongoDBTask, getNextStatusesTask);
|
await Task.WhenAll(mongoDBTask, getNextStatusesTask, cacheUpdateTask);
|
||||||
|
|
||||||
var nextPossibleStatuses = await getNextStatusesTask;
|
var nextPossibleStatuses = await getNextStatusesTask;
|
||||||
|
|
||||||
@ -677,6 +682,11 @@ namespace Marco.Pms.Services.Service
|
|||||||
return ApiResponse<object>.SuccessResponse(response, "Status updated, but a post-processing error occurred.");
|
return ApiResponse<object>.SuccessResponse(response, "Status updated, but a post-processing error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region =================================================================== Put Functions ===================================================================
|
||||||
|
|
||||||
public async Task<ApiResponse<object>> UpdateExpanseAsync(Guid id, UpdateExpensesDto model, Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> UpdateExpanseAsync(Guid id, UpdateExpensesDto model, Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
var existingExpense = await _context.Expenses
|
var existingExpense = await _context.Expenses
|
||||||
@ -696,6 +706,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
if (existingExpense == null)
|
if (existingExpense == null)
|
||||||
{
|
{
|
||||||
|
_logger.LogWarning("User attempted to update expense with ID {ExpenseId}, but not found in database", id);
|
||||||
return ApiResponse<object>.ErrorResponse("Expense not found", "Expense not found", 404);
|
return ApiResponse<object>.ErrorResponse("Expense not found", "Expense not found", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,14 +733,73 @@ namespace Marco.Pms.Services.Service
|
|||||||
if (newBillAttachments.Any())
|
if (newBillAttachments.Any())
|
||||||
{
|
{
|
||||||
await ProcessAndUploadAttachmentsAsync(newBillAttachments, existingExpense, loggedInEmployee.Id, tenantId);
|
await ProcessAndUploadAttachmentsAsync(newBillAttachments, existingExpense, loggedInEmployee.Id, tenantId);
|
||||||
await _context.SaveChangesAsync();
|
try
|
||||||
|
{
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
_logger.LogInfo("{Count} New attachments added while updating expense {ExpenseId} by employee {EmployeeId}",
|
||||||
|
newBillAttachments.Count, existingExpense.Id, loggedInEmployee.Id);
|
||||||
|
}
|
||||||
|
catch (DbUpdateException dbEx)
|
||||||
|
{
|
||||||
|
_logger.LogError(dbEx, "Databsae Exception occured while adding new attachments during updating expense");
|
||||||
|
return ApiResponse<object>.ErrorResponse("Databsae Exception", new
|
||||||
|
{
|
||||||
|
Message = dbEx.Message,
|
||||||
|
StackTrace = dbEx.StackTrace,
|
||||||
|
Source = dbEx.Source,
|
||||||
|
InnerException = new
|
||||||
|
{
|
||||||
|
Message = dbEx.InnerException?.Message,
|
||||||
|
StackTrace = dbEx.InnerException?.StackTrace,
|
||||||
|
Source = dbEx.InnerException?.Source,
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var deleteBillAttachments = model.BillAttachments.Where(ba => ba.DocumentId != null && !ba.IsActive).ToList();
|
var deleteBillAttachments = model.BillAttachments.Where(ba => ba.DocumentId != null && !ba.IsActive).ToList();
|
||||||
if (deleteBillAttachments.Any())
|
if (deleteBillAttachments.Any())
|
||||||
{
|
{
|
||||||
var documentIds = deleteBillAttachments.Select(d => d.DocumentId!.Value).ToList();
|
var documentIds = deleteBillAttachments.Select(d => d.DocumentId!.Value).ToList();
|
||||||
|
try
|
||||||
await DeleteAttachemnts(documentIds);
|
{
|
||||||
|
await DeleteAttachemnts(documentIds);
|
||||||
|
_logger.LogInfo("{Count} Attachments deleted while updating expense {ExpenseId} by employee {EmployeeId}",
|
||||||
|
deleteBillAttachments.Count, existingExpense.Id, loggedInEmployee.Id);
|
||||||
|
}
|
||||||
|
catch (DbUpdateException dbEx)
|
||||||
|
{
|
||||||
|
_logger.LogError(dbEx, "Databsae Exception occured while deleting attachments during updating expense");
|
||||||
|
return ApiResponse<object>.ErrorResponse("Databsae Exception", new
|
||||||
|
{
|
||||||
|
Message = dbEx.Message,
|
||||||
|
StackTrace = dbEx.StackTrace,
|
||||||
|
Source = dbEx.Source,
|
||||||
|
InnerException = new
|
||||||
|
{
|
||||||
|
Message = dbEx.InnerException?.Message,
|
||||||
|
StackTrace = dbEx.InnerException?.StackTrace,
|
||||||
|
Source = dbEx.InnerException?.Source,
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Exception occured while deleting attachments during updating expense");
|
||||||
|
return ApiResponse<object>.ErrorResponse("Exception occured while deleting attachments during updating expense ", new
|
||||||
|
{
|
||||||
|
Message = ex.Message,
|
||||||
|
StackTrace = ex.StackTrace,
|
||||||
|
Source = ex.Source,
|
||||||
|
InnerException = new
|
||||||
|
{
|
||||||
|
Message = ex.InnerException?.Message,
|
||||||
|
StackTrace = ex.InnerException?.StackTrace,
|
||||||
|
Source = ex.InnerException?.Source,
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,6 +861,11 @@ namespace Marco.Pms.Services.Service
|
|||||||
return ApiResponse<object>.SuccessResponse(response, "Status updated, but a post-processing error occurred.");
|
return ApiResponse<object>.SuccessResponse(response, "Status updated, but a post-processing error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region =================================================================== Delete Functions ===================================================================
|
||||||
|
|
||||||
public async Task<ApiResponse<object>> DeleteExpanseAsync(Guid id, Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> DeleteExpanseAsync(Guid id, Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
var expenseQuery = _context.Expenses.Where(e => e.Id == id && e.StatusId == Draft && e.CreatedById == loggedInEmployee.Id && e.TenantId == tenantId);
|
var expenseQuery = _context.Expenses.Where(e => e.Id == id && e.StatusId == Draft && e.CreatedById == loggedInEmployee.Id && e.TenantId == tenantId);
|
||||||
@ -811,7 +886,16 @@ namespace Marco.Pms.Services.Service
|
|||||||
var existingExpense = await expenseQuery.FirstOrDefaultAsync();
|
var existingExpense = await expenseQuery.FirstOrDefaultAsync();
|
||||||
if (existingExpense == null)
|
if (existingExpense == null)
|
||||||
{
|
{
|
||||||
return ApiResponse<object>.ErrorResponse("Expense cannot be deleted", "Expense cannot be deleted", 400);
|
var message = hasAprrovePermission ? "Expenses not found" : "Expense cannot be deleted";
|
||||||
|
if (hasAprrovePermission)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Employee {EmployeeId} attempted to delete expense {ExpenseId}, but not found in database", loggedInEmployee.Id, id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Employee {EmployeeId} attempted to delete expense {ExpenseId}, Which is created by another employee", loggedInEmployee.Id, id);
|
||||||
|
}
|
||||||
|
return ApiResponse<object>.ErrorResponse(message, message, 400);
|
||||||
}
|
}
|
||||||
var documentIds = await _context.BillAttachments
|
var documentIds = await _context.BillAttachments
|
||||||
.Where(ba => ba.ExpensesId == existingExpense.Id)
|
.Where(ba => ba.ExpensesId == existingExpense.Id)
|
||||||
@ -824,10 +908,11 @@ namespace Marco.Pms.Services.Service
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
_logger.LogInfo("Employeee {EmployeeId} successfully deleted the expense {EmpenseId}", loggedInEmployee.Id, id);
|
||||||
}
|
}
|
||||||
catch (DbUpdateException dbEx)
|
catch (DbUpdateException dbEx)
|
||||||
{
|
{
|
||||||
_logger.LogError(dbEx, "Databsae Exception occured while adding expense");
|
_logger.LogError(dbEx, "Databsae Exception occured while deleting expense");
|
||||||
return ApiResponse<object>.ErrorResponse("Databsae Exception", new
|
return ApiResponse<object>.ErrorResponse("Databsae Exception", new
|
||||||
{
|
{
|
||||||
Message = dbEx.Message,
|
Message = dbEx.Message,
|
||||||
@ -841,27 +926,64 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
var attachmentDeletionTask = Task.Run(async () =>
|
try
|
||||||
{
|
{
|
||||||
await DeleteAttachemnts(documentIds);
|
var attachmentDeletionTask = Task.Run(async () =>
|
||||||
});
|
{
|
||||||
|
await DeleteAttachemnts(documentIds);
|
||||||
|
});
|
||||||
|
|
||||||
var cacheTask = Task.Run(async () =>
|
var cacheTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await _cache.DeleteExpenseAsync(id, tenantId);
|
await _cache.DeleteExpenseAsync(id, tenantId);
|
||||||
});
|
});
|
||||||
var mongoDBTask = _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
|
var mongoDBTask = _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
|
||||||
{
|
{
|
||||||
EntityId = existingExpense.Id.ToString(),
|
EntityId = existingExpense.Id.ToString(),
|
||||||
UpdatedById = loggedInEmployee.Id.ToString(),
|
UpdatedById = loggedInEmployee.Id.ToString(),
|
||||||
OldObject = existingEntityBson,
|
OldObject = existingEntityBson,
|
||||||
UpdatedAt = DateTime.UtcNow
|
UpdatedAt = DateTime.UtcNow
|
||||||
}, Collection);
|
}, Collection);
|
||||||
|
|
||||||
await Task.WhenAll(attachmentDeletionTask, cacheTask, mongoDBTask);
|
await Task.WhenAll(attachmentDeletionTask, cacheTask, mongoDBTask);
|
||||||
|
}
|
||||||
|
catch (DbUpdateException dbEx)
|
||||||
|
{
|
||||||
|
_logger.LogError(dbEx, "Databsae Exception occured while deleting attachments during updating expense");
|
||||||
|
return ApiResponse<object>.ErrorResponse("Databsae Exception", new
|
||||||
|
{
|
||||||
|
Message = dbEx.Message,
|
||||||
|
StackTrace = dbEx.StackTrace,
|
||||||
|
Source = dbEx.Source,
|
||||||
|
InnerException = new
|
||||||
|
{
|
||||||
|
Message = dbEx.InnerException?.Message,
|
||||||
|
StackTrace = dbEx.InnerException?.StackTrace,
|
||||||
|
Source = dbEx.InnerException?.Source,
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Exception occured while deleting attachments during updating expense");
|
||||||
|
return ApiResponse<object>.ErrorResponse("Exception occured while deleting attachments during updating expense ", new
|
||||||
|
{
|
||||||
|
Message = ex.Message,
|
||||||
|
StackTrace = ex.StackTrace,
|
||||||
|
Source = ex.Source,
|
||||||
|
InnerException = new
|
||||||
|
{
|
||||||
|
Message = ex.InnerException?.Message,
|
||||||
|
StackTrace = ex.InnerException?.StackTrace,
|
||||||
|
Source = ex.InnerException?.Source,
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
return ApiResponse<object>.SuccessResponse("Success", "Expense Deleted Successfully", 200);
|
return ApiResponse<object>.SuccessResponse("Success", "Expense Deleted Successfully", 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Helper Functions ===================================================================
|
#region =================================================================== Helper Functions ===================================================================
|
||||||
|
|
||||||
private async Task<List<ExpenseList>> GetAllExpnesRelatedTables(List<Expenses> model)
|
private async Task<List<ExpenseList>> GetAllExpnesRelatedTables(List<Expenses> model)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user