Create API base for delete expense API
This commit is contained in:
parent
4370d5a350
commit
b6dfb30f92
@ -54,14 +54,6 @@ namespace Marco.Pms.Services.Controllers
|
||||
return StatusCode(response.StatusCode, response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new expense entry along with its bill attachments.
|
||||
/// This operation is transactional and performs validations and file uploads concurrently for optimal performance
|
||||
/// by leveraging async/await without unnecessary thread-pool switching via Task.Run.
|
||||
/// </summary>
|
||||
/// <param name="dto">The data transfer object containing expense details and attachments.</param>
|
||||
/// <returns>An IActionResult indicating the result of the creation operation.</returns>
|
||||
|
||||
[HttpPost("create")]
|
||||
public async Task<IActionResult> CreateExpense([FromBody] CreateExpensesDto model)
|
||||
{
|
||||
@ -92,8 +84,11 @@ namespace Marco.Pms.Services.Controllers
|
||||
}
|
||||
|
||||
[HttpDelete("delete/{id}")]
|
||||
public void Delete(int id)
|
||||
public async Task<IActionResult> DeleteExpanse(Guid id)
|
||||
{
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var response = await _expensesService.DeleteExpanseAsync(id, loggedInEmployee, tenantId);
|
||||
return StatusCode(response.StatusCode, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -702,47 +702,9 @@ namespace Marco.Pms.Services.Service
|
||||
var deleteBillAttachments = model.BillAttachments.Where(ba => ba.DocumentId != null && !ba.IsActive).ToList();
|
||||
if (deleteBillAttachments.Any())
|
||||
{
|
||||
var documentIds = deleteBillAttachments.Select(d => d.DocumentId).ToList();
|
||||
|
||||
var attachmentTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
var attachments = await dbContext.BillAttachments.AsNoTracking().Where(ba => documentIds.Contains(ba.DocumentId)).ToListAsync();
|
||||
|
||||
dbContext.BillAttachments.RemoveRange(attachments);
|
||||
await dbContext.SaveChangesAsync();
|
||||
});
|
||||
var documentsTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
var documents = await dbContext.Documents.AsNoTracking().Where(ba => documentIds.Contains(ba.Id)).ToListAsync();
|
||||
|
||||
if (documents.Any())
|
||||
{
|
||||
dbContext.Documents.RemoveRange(documents);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
List<S3DeletionObject> deletionObject = new List<S3DeletionObject>();
|
||||
foreach (var document in documents)
|
||||
{
|
||||
deletionObject.Add(new S3DeletionObject
|
||||
{
|
||||
Key = document.S3Key
|
||||
});
|
||||
if (!string.IsNullOrWhiteSpace(document.ThumbS3Key) && document.ThumbS3Key != document.S3Key)
|
||||
{
|
||||
deletionObject.Add(new S3DeletionObject
|
||||
{
|
||||
Key = document.ThumbS3Key
|
||||
});
|
||||
}
|
||||
}
|
||||
await _updateLogHelper.PushToS3DeletionAsync(deletionObject);
|
||||
}
|
||||
});
|
||||
|
||||
await Task.WhenAll(attachmentTask, documentsTask);
|
||||
var documentIds = deleteBillAttachments.Select(d => d.DocumentId!.Value).ToList();
|
||||
|
||||
await DeleteAttachemnts(documentIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -805,8 +767,75 @@ namespace Marco.Pms.Services.Service
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(int id)
|
||||
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 hasAprrovePermissionTask = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
return await permissionService.HasPermission(PermissionsMaster.ExpenseApprove, loggedInEmployee.Id);
|
||||
});
|
||||
|
||||
var hasAprrovePermission = await hasAprrovePermissionTask;
|
||||
if (!hasAprrovePermission)
|
||||
{
|
||||
expenseQuery = expenseQuery.Where(e => e.CreatedById == loggedInEmployee.Id);
|
||||
}
|
||||
|
||||
var existingExpense = await expenseQuery.FirstOrDefaultAsync();
|
||||
if (existingExpense == null)
|
||||
{
|
||||
return ApiResponse<object>.ErrorResponse("Expense cannot be deleted", "Expense cannot be deleted", 400);
|
||||
}
|
||||
var documentIds = await _context.BillAttachments
|
||||
.Where(ba => ba.ExpensesId == existingExpense.Id)
|
||||
.Select(ba => ba.DocumentId)
|
||||
.ToListAsync();
|
||||
|
||||
var existingEntityBson = _updateLogHelper.EntityToBsonDocument(existingExpense);
|
||||
|
||||
_context.Expenses.Remove(existingExpense);
|
||||
try
|
||||
{
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateException dbEx)
|
||||
{
|
||||
_logger.LogError(dbEx, "Databsae Exception occured while adding 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 attachmentDeletionTask = Task.Run(async () =>
|
||||
{
|
||||
await DeleteAttachemnts(documentIds);
|
||||
});
|
||||
|
||||
var cacheTask = Task.Run(async () =>
|
||||
{
|
||||
await _cache.DeleteExpenseAsync(id, tenantId);
|
||||
});
|
||||
var mongoDBTask = _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
|
||||
{
|
||||
EntityId = existingExpense.Id.ToString(),
|
||||
UpdatedById = loggedInEmployee.Id.ToString(),
|
||||
OldObject = existingEntityBson,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
}, Collection);
|
||||
|
||||
await Task.WhenAll(attachmentDeletionTask, cacheTask, mongoDBTask);
|
||||
return ApiResponse<object>.SuccessResponse("Success", "Expense Deleted Successfully", 200);
|
||||
}
|
||||
|
||||
#region =================================================================== Helper Functions ===================================================================
|
||||
@ -1085,6 +1114,48 @@ namespace Marco.Pms.Services.Service
|
||||
return (document, billAttachment);
|
||||
}
|
||||
|
||||
private async Task DeleteAttachemnts(List<Guid> documentIds)
|
||||
{
|
||||
var attachmentTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
var attachments = await dbContext.BillAttachments.AsNoTracking().Where(ba => documentIds.Contains(ba.DocumentId)).ToListAsync();
|
||||
|
||||
dbContext.BillAttachments.RemoveRange(attachments);
|
||||
await dbContext.SaveChangesAsync();
|
||||
});
|
||||
var documentsTask = Task.Run(async () =>
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
var documents = await dbContext.Documents.AsNoTracking().Where(ba => documentIds.Contains(ba.Id)).ToListAsync();
|
||||
|
||||
if (documents.Any())
|
||||
{
|
||||
dbContext.Documents.RemoveRange(documents);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
List<S3DeletionObject> deletionObject = new List<S3DeletionObject>();
|
||||
foreach (var document in documents)
|
||||
{
|
||||
deletionObject.Add(new S3DeletionObject
|
||||
{
|
||||
Key = document.S3Key
|
||||
});
|
||||
if (!string.IsNullOrWhiteSpace(document.ThumbS3Key) && document.ThumbS3Key != document.S3Key)
|
||||
{
|
||||
deletionObject.Add(new S3DeletionObject
|
||||
{
|
||||
Key = document.ThumbS3Key
|
||||
});
|
||||
}
|
||||
}
|
||||
await _updateLogHelper.PushToS3DeletionAsync(deletionObject);
|
||||
}
|
||||
});
|
||||
|
||||
await Task.WhenAll(attachmentTask, documentsTask);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,5 +11,6 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
||||
Task<ApiResponse<object>> CreateExpenseAsync(CreateExpensesDto dto, Employee loggedInEmployee, Guid tenantId);
|
||||
Task<ApiResponse<object>> ChangeStatusAsync(ExpenseRecordDto model, Employee loggedInEmployee, Guid tenantId);
|
||||
Task<ApiResponse<object>> UpdateExpanseAsync(Guid id, UpdateExpensesDto model, Employee loggedInEmployee, Guid tenantId);
|
||||
Task<ApiResponse<object>> DeleteExpanseAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user