Added the code to save reimbursement in database

This commit is contained in:
ashutosh.nehete 2025-07-29 18:11:33 +05:30
parent f4368ae4e3
commit 0c1cb98f5b
5 changed files with 59 additions and 1 deletions

View File

@ -5,5 +5,8 @@
public Guid ExpenseId { get; set; }
public Guid StatusId { get; set; }
public string? Comment { get; set; }
public string? ReimburseTransactionId { get; set; }
public DateTime? ReimburseDate { get; set; }
public Guid? ReimburseById { get; set; }
}
}

View File

@ -27,5 +27,6 @@ namespace Marco.Pms.Model.ViewModels.Expenses
public string? GSTNumber { get; set; }
public int? NoOfPersons { get; set; }
public bool IsActive { get; set; } = true;
public List<ExpensesReimburseVM> ExpensesReimburse { get; set; } = new List<ExpensesReimburseVM>();
}
}

View File

@ -0,0 +1,13 @@
using Marco.Pms.Model.ViewModels.Activities;
namespace Marco.Pms.Model.ViewModels.Expenses
{
public class ExpensesReimburseVM
{
public Guid Id { get; set; }
public string ReimburseTransactionId { get; set; } = string.Empty;
public DateTime ReimburseDate { get; set; }
public BasicEmployeeVM? ReimburseBy { get; set; }
public string ReimburseNote { get; set; } = string.Empty;
}
}

View File

@ -123,6 +123,8 @@ namespace Marco.Pms.Services.MappingProfiles
CreateMap<Expenses, ExpenseList>();
CreateMap<CreateExpensesDto, Expenses>();
CreateMap<UpdateExpensesDto, Expenses>();
CreateMap<ExpensesReimburse, ExpensesReimburseVM>();
CreateMap<Expenses, ExpenseDetailsMongoDB>()
.ForMember(
dest => dest.Id,

View File

@ -35,6 +35,7 @@ namespace Marco.Pms.Services.Service
private readonly IMapper _mapper;
private static readonly Guid Draft = Guid.Parse("297e0d8f-f668-41b5-bfea-e03b354251c8");
private static readonly Guid Rejected = Guid.Parse("d1ee5eec-24b6-4364-8673-a8f859c60729");
private static readonly Guid PaidStatus = Guid.Parse("61578360-3a49-4c34-8604-7b35a3787b95");
private static readonly string Collection = "ExpensesModificationLog";
public ExpensesService(
IDbContextFactory<ApplicationDbContext> dbContextFactory,
@ -490,6 +491,17 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("This status change is not allowed.", "Invalid Transition", 400);
}
if (statusMapping.NextStatusId == PaidStatus &&
(string.IsNullOrWhiteSpace(model.ReimburseTransactionId) ||
!model.ReimburseDate.HasValue ||
model.ReimburseById == null ||
model.ReimburseById == Guid.Empty))
{
_logger.LogWarning("Invalid status transition attempted for ExpenseId: {ExpenseId}. From StatusId: {FromStatusId} to {ToStatusId}",
existingExpense.Id, existingExpense.StatusId, model.StatusId);
return ApiResponse<object>.ErrorResponse("This status change is not allowed.", "Invalid Transition", 400);
}
// Check permissions. The logic is:
// 1. If the target status has specific permissions defined, the user must have at least one of them.
// 2. If no permissions are defined for the target status, only the original creator of the expense can change it.
@ -527,6 +539,23 @@ namespace Marco.Pms.Services.Service
existingExpense.StatusId = statusMapping.NextStatusId;
existingExpense.Status = statusMapping.NextStatus; // Assigning the included entity for the response mapping.
var expensesRemburse = new ExpensesReimburse
{
ReimburseTransactionId = model.ReimburseTransactionId!,
ReimburseDate = model.ReimburseDate!.Value,
ReimburseById = model.ReimburseById!.Value,
ReimburseNote = model.Comment ?? string.Empty,
TenantId = tenantId
};
_context.ExpensesReimburse.Add(expensesRemburse);
_context.ExpensesReimburseMapping.Add(new ExpensesReimburseMapping
{
ExpensesId = existingExpense.Id,
ExpensesReimburseId = expensesRemburse.Id,
TenantId = tenantId
});
_context.ExpenseLogs.Add(new ExpenseLog
{
ExpenseId = existingExpense.Id,
@ -1064,9 +1093,17 @@ namespace Marco.Pms.Services.Service
PermissionIds = g.Select(ps => ps.PermissionId).ToList()
}).ToListAsync();
});
var expenseReimburseTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.ExpensesReimburseMapping
.Include(er => er.ExpensesReimburse)
.Where(er => er.TenantId == tenantId && er.ExpensesId == Guid.Parse(model.Id))
.Select(er => er.ExpensesReimburse).ToListAsync();
});
// Await all prerequisite checks at once.
await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, statusTask, permissionStatusMappingTask);
await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, statusTask, permissionStatusMappingTask, expenseReimburseTask);
var project = projectTask.Result;
var expenseType = expenseTypeTask.Result;
@ -1075,6 +1112,7 @@ namespace Marco.Pms.Services.Service
var permissionStatusMappings = permissionStatusMappingTask.Result;
var paidBy = paidByTask.Result;
var createdBy = createdByTask.Result;
var expensesReimburse = expenseReimburseTask.Result;
var response = _mapper.Map<ExpenseDetailsVM>(model);
@ -1083,6 +1121,7 @@ namespace Marco.Pms.Services.Service
response.CreatedBy = _mapper.Map<BasicEmployeeVM>(createdBy);
response.PaymentMode = _mapper.Map<PaymentModeMatserVM>(paymentMode);
response.ExpensesType = _mapper.Map<ExpensesTypeMasterVM>(expenseType);
response.ExpensesReimburse = _mapper.Map<List<ExpensesReimburseVM>>(expensesReimburse);
if (statusMapping != null)
{
response.Status = _mapper.Map<ExpensesStatusMasterVM>(statusMapping.Status);