diff --git a/Marco.Pms.Services/Controllers/ExpenseController.cs b/Marco.Pms.Services/Controllers/ExpenseController.cs index fe29841..45bc37d 100644 --- a/Marco.Pms.Services/Controllers/ExpenseController.cs +++ b/Marco.Pms.Services/Controllers/ExpenseController.cs @@ -210,6 +210,19 @@ namespace Marco.Pms.Services.Controllers } return StatusCode(response.StatusCode, response); } + + [HttpDelete("payment-request/delete/{id}")] + public async Task DeletePaymentRequestAsync(Guid id) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _expensesService.DeleteExpanseAsync(id, loggedInEmployee, tenantId); + if (response.Success) + { + var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Payment_Request", Response = response.Data }; + await _signalR.SendNotificationAsync(notification); + } + return StatusCode(response.StatusCode, response); + } #endregion #region =================================================================== Recurring Payment Functions =================================================================== diff --git a/Marco.Pms.Services/Service/ExpensesService.cs b/Marco.Pms.Services/Service/ExpensesService.cs index 57e7187..de93e6b 100644 --- a/Marco.Pms.Services/Service/ExpensesService.cs +++ b/Marco.Pms.Services/Service/ExpensesService.cs @@ -157,7 +157,7 @@ namespace Marco.Pms.Services.Service if (cacheList == null) { - await _cache.AddExpensesListToCache(expenses: await expensesQuery.ToListAsync(), tenantId); + //await _cache.AddExpensesListToCache(expenses: await expensesQuery.ToListAsync(), tenantId); // Apply permission-based filtering BEFORE any other filters or pagination. if (hasViewAllPermissionTask.Result) @@ -2327,6 +2327,106 @@ namespace Marco.Pms.Services.Service _logger.LogInfo("End EditPaymentRequestAsync for PaymentRequestId: {PaymentRequestId}", id); } } + + public async Task> DeletePaymentRequestAsync(Guid id, Employee loggedInEmployee, Guid tenantId) + { + var paymentRequestTask = Task.Run(async () => + { + await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.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(); + return await permissionService.HasPermission(PermissionsMaster.ExpenseApprove, loggedInEmployee.Id); + }); + + await Task.WhenAll(paymentRequestTask, hasAprrovePermissionTask); + + var hasAprrovePermission = hasAprrovePermissionTask.Result; + var paymentRequest = paymentRequestTask.Result; + + if (paymentRequest == null) + { + var message = hasAprrovePermission ? "Payment Request not found" : "Payment Request cannot be deleted"; + if (hasAprrovePermission) + { + _logger.LogWarning("Employee {EmployeeId} attempted to delete payment request {PaymentRequestId}, but not found in database", loggedInEmployee.Id, id); + } + else + { + _logger.LogWarning("Employee {EmployeeId} attempted to delete payment request {PaymentRequestId}, Which is created by another employee", loggedInEmployee.Id, id); + } + return ApiResponse.ErrorResponse(message, message, 400); + } + if (paymentRequest.ExpenseStatusId != Draft) + { + _logger.LogWarning("User attempted to delete payment request with ID {PaymentRequestId}, but donot have status of DRAFT or REJECTED", loggedInEmployee.Id); + return ApiResponse.ErrorResponse("Payment Request connot be deleted", "Payment Request connot be deleted", 400); + } + + if (!hasAprrovePermission && paymentRequest.CreatedById != loggedInEmployee.Id) + { + _logger.LogWarning("User attempted to delete payment request with ID {PaymentRequestId} which not created by them", loggedInEmployee.Id); + return ApiResponse.ErrorResponse("You donot have access to delete this payment request", "You donot have access to delete this payment request", 400); + + } + + var documentIds = await _context.PaymentRequestAttachments + .Where(ba => ba.PaymentRequestId == paymentRequest.Id) + .Select(ba => ba.DocumentId) + .ToListAsync(); + + var existingEntityBson = _updateLogHelper.EntityToBsonDocument(paymentRequest); + paymentRequest.IsActive = false; + + _context.PaymentRequests.Update(paymentRequest); + + try + { + await _context.SaveChangesAsync(); + _logger.LogInfo("Employeee {EmployeeId} successfully deleted the payment request {EmpenseId}", loggedInEmployee.Id, id); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Databsae Exception occured while deleting payment request"); + return ApiResponse.ErrorResponse("Databsae Exception", ExceptionMapper(dbEx), 500); + } + try + { + var attachmentDeletionTask = Task.Run(async () => + { + await DeletePaymentRequestAttachemnts(documentIds); + }); + + var cacheTask = Task.Run(async () => + { + await _cache.DeleteExpenseAsync(id, tenantId); + }); + var mongoDBTask = _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject + { + EntityId = paymentRequest.Id.ToString(), + UpdatedById = loggedInEmployee.Id.ToString(), + OldObject = existingEntityBson, + UpdatedAt = DateTime.UtcNow + }, "PaymentRequestModificationLog"); + + await Task.WhenAll(attachmentDeletionTask, cacheTask, mongoDBTask); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Databsae Exception occured while deleting attachments during updating payment request"); + return ApiResponse.ErrorResponse("Databsae Exception", ExceptionMapper(dbEx), 500); + } + catch (Exception ex) + { + _logger.LogError(ex, "Exception occured while deleting attachments during updating payment request"); + return ApiResponse.ErrorResponse("Exception occured while deleting attachments during updating payment request ", ExceptionMapper(ex), 500); + } + return ApiResponse.SuccessResponse("Success", "Payment Request Deleted Successfully", 200); + } #endregion #region =================================================================== Advance Payment Functions =================================================================== diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IExpensesService.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IExpensesService.cs index f2ce9b5..d9c79b1 100644 --- a/Marco.Pms.Services/Service/ServiceInterfaces/IExpensesService.cs +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IExpensesService.cs @@ -26,6 +26,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces Task> ChangePaymentRequestStatusAsync(PaymentRequestRecordDto model, Employee loggedInEmployee, Guid tenantId); Task> ChangeToExpanseFromPaymentRequestAsync(ExpenseConversionDto model, Employee loggedInEmployee, Guid tenantId); Task> EditPaymentRequestAsync(Guid id, PaymentRequestDto model, Employee loggedInEmployee, Guid tenantId); + Task> DeletePaymentRequestAsync(Guid id, Employee loggedInEmployee, Guid tenantId); #endregion #region =================================================================== Recurring Payment Functions ===================================================================