From e14468b1241cc0e15f4d518b4ba0c8796f393859 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Wed, 5 Nov 2025 15:55:39 +0530 Subject: [PATCH] Added the PaymentRequestUID and RecurringPaymentUID added in VMs --- .../Expenses/ExpenseDetailsMongoDB.cs | 1 + .../ViewModels/Expenses/ExpenseDetailsVM.cs | 1 + .../ViewModels/Expenses/ExpenseList.cs | 1 + .../Expenses/PaymentRequestDetailsVM.cs | 5 +- .../ViewModels/Expenses/PaymentRequestVM.cs | 5 +- Marco.Pms.Services/Service/ExpensesService.cs | 133 ++---------------- 6 files changed, 17 insertions(+), 129 deletions(-) diff --git a/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs b/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs index b363f58..93b63ba 100644 --- a/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs +++ b/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs @@ -24,6 +24,7 @@ namespace Marco.Pms.Model.MongoDBModels.Expenses public CurrencyMaster? Currency { get; set; } public double? BaseAmount { get; set; } public double? TaxAmount { get; set; } + public string? PaymentRequestUID { get; set; } public string? ExpenseUId { get; set; } public ExpensesStatusMasterMongoDB Status { get; set; } = new ExpensesStatusMasterMongoDB(); public List NextStatus { get; set; } = new List(); diff --git a/Marco.Pms.Model/ViewModels/Expenses/ExpenseDetailsVM.cs b/Marco.Pms.Model/ViewModels/Expenses/ExpenseDetailsVM.cs index 2da1c94..b117c64 100644 --- a/Marco.Pms.Model/ViewModels/Expenses/ExpenseDetailsVM.cs +++ b/Marco.Pms.Model/ViewModels/Expenses/ExpenseDetailsVM.cs @@ -30,6 +30,7 @@ namespace Marco.Pms.Model.ViewModels.Expenses public string? TransactionId { get; set; } public string Description { get; set; } = string.Empty; public string? Location { get; set; } + public string? PaymentRequestUID { get; set; } public string? ExpenseUId { get; set; } public List Documents { get; set; } = new List(); public List ExpenseLogs { get; set; } = new List(); diff --git a/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs b/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs index f7b0000..b610968 100644 --- a/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs +++ b/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs @@ -20,6 +20,7 @@ namespace Marco.Pms.Model.ViewModels.Expanses public DateTime CreatedAt { get; set; } public string SupplerName { get; set; } = string.Empty; public string? ExpenseUId { get; set; } + public string? PaymentRequestUID { get; set; } public string Description { get; set; } = string.Empty; public string TransactionId { get; set; } = string.Empty; public double Amount { get; set; } diff --git a/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestDetailsVM.cs b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestDetailsVM.cs index 4ffaec8..1766f03 100644 --- a/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestDetailsVM.cs +++ b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestDetailsVM.cs @@ -1,5 +1,4 @@ -using Marco.Pms.Model.Expenses; -using Marco.Pms.Model.Master; +using Marco.Pms.Model.Master; using Marco.Pms.Model.ViewModels.Activities; using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Projects; @@ -19,7 +18,7 @@ namespace Marco.Pms.Model.ViewModels.Expenses public double? TaxAmount { get; set; } public DateTime DueDate { get; set; } public BasicProjectVM? Project { get; set; } - public RecurringPayment? RecurringPayment { get; set; } + public string? RecurringPaymentUID { get; set; } public ExpensesCategoryMasterVM? ExpenseCategory { get; set; } public ExpensesStatusMasterVM? ExpenseStatus { get; set; } public string? PaidTransactionId { get; set; } diff --git a/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestVM.cs b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestVM.cs index a5253b0..06e4d11 100644 --- a/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestVM.cs +++ b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestVM.cs @@ -1,5 +1,4 @@ -using Marco.Pms.Model.Expenses; -using Marco.Pms.Model.Master; +using Marco.Pms.Model.Master; using Marco.Pms.Model.ViewModels.Activities; using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Projects; @@ -11,13 +10,13 @@ namespace Marco.Pms.Model.ViewModels.Expenses public Guid Id { get; set; } public string? Title { get; set; } public string? Description { get; set; } + public string? RecurringPaymentUID { get; set; } public string? PaymentRequestUID { get; set; } public string? Payee { get; set; } public CurrencyMaster? Currency { get; set; } public double Amount { get; set; } public DateTime DueDate { get; set; } public BasicProjectVM? Project { get; set; } - public RecurringPayment? RecurringPayment { get; set; } public ExpensesCategoryMasterVM? ExpenseCategory { get; set; } public ExpensesStatusMasterVM? ExpenseStatus { get; set; } public bool IsAdvancePayment { get; set; } diff --git a/Marco.Pms.Services/Service/ExpensesService.cs b/Marco.Pms.Services/Service/ExpensesService.cs index 9e62eef..62ca400 100644 --- a/Marco.Pms.Services/Service/ExpensesService.cs +++ b/Marco.Pms.Services/Service/ExpensesService.cs @@ -26,7 +26,6 @@ using MarcoBMS.Services.Service; using Microsoft.CodeAnalysis; using Microsoft.EntityFrameworkCore; using System.Text.Json; -using System.Text.RegularExpressions; using Document = Marco.Pms.Model.DocumentManager.Document; namespace Marco.Pms.Services.Service @@ -151,6 +150,7 @@ namespace Marco.Pms.Services.Service .Include(e => e.Project) .Include(e => e.PaymentMode) .Include(e => e.ExpenseCategory) + .Include(e => e.PaymentRequest) .Include(e => e.Status) .Include(e => e.Currency) .Where(e => e.TenantId == tenantId); // Always filter by TenantId first. @@ -244,6 +244,8 @@ namespace Marco.Pms.Services.Service { var result = _mapper.Map(e); result.ExpenseUId = $"{e.UIDPrefix}/{e.UIDPostfix:D5}"; + if (e.PaymentRequest != null) + result.PaymentRequestUID = $"{e.PaymentRequest.UIDPrefix}/{e.PaymentRequest.UIDPostfix:D5}"; return result; }).ToList(); totalPages = (int)Math.Ceiling((double)totalEntites / pageSize); @@ -324,6 +326,7 @@ namespace Marco.Pms.Services.Service .Include(e => e.ExpenseCategory) .Include(e => e.Status) .Include(e => e.Currency) + .Include(e => e.PaymentRequest) .AsNoTracking().FirstOrDefaultAsync(e => (e.Id == id || (e.UIDPrefix + "/" + e.UIDPostfix.ToString().PadLeft(5, '0')) == expenseUId) && e.TenantId == tenantId); if (expense == null) @@ -1311,6 +1314,8 @@ namespace Marco.Pms.Services.Service { var result = _mapper.Map(pr); result.PaymentRequestUID = $"{pr.UIDPrefix}/{pr.UIDPostfix:D5}"; + if (pr.RecurringPayment != null) + result.RecurringPaymentUID = $"{pr.RecurringPayment.UIDPrefix}/{pr.RecurringPayment.UIDPostfix:D5}"; return result; }).ToList(); @@ -1529,6 +1534,8 @@ namespace Marco.Pms.Services.Service // Map main response model and populate additional fields var response = _mapper.Map(paymentRequest); response.PaymentRequestUID = $"{paymentRequest.UIDPrefix}/{paymentRequest.UIDPostfix:D5}"; + if (paymentRequest.RecurringPayment != null) + response.RecurringPaymentUID = $"{paymentRequest.RecurringPayment.UIDPrefix}/{paymentRequest.RecurringPayment.UIDPostfix:D5}"; response.Attachments = attachmentVMs; response.NextStatus = nextStatuses; response.UpdateLogs = updateLogs.Select(ul => @@ -2872,13 +2879,6 @@ namespace Marco.Pms.Services.Service #endregion #region =================================================================== Helper Functions =================================================================== - - private int ExtractNumber(string id) - { - // Extract trailing number; handles EX_0001, EX-0001, EX0001 - var m = Regex.Match(id ?? string.Empty, @"(\d+)$"); - return m.Success ? int.Parse(m.Value) : int.MinValue; // put invalid IDs at the bottom - } private static object ExceptionMapper(Exception ex) { return new @@ -2894,121 +2894,6 @@ namespace Marco.Pms.Services.Service } }; } - private async Task> GetAllExpnesRelatedTables(List model, Guid tenantId) - { - List expenseList = new List(); - var projectIds = model.Select(m => m.ProjectId).ToList(); - var statusIds = model.Select(m => m.StatusId).ToList(); - var expenseCategoryIds = model.Select(m => m.ExpenseCategoryId).ToList(); - var paymentModeIds = model.Select(m => m.PaymentModeId).ToList(); - var createdByIds = model.Select(m => m.CreatedById).ToList(); - var paidByIds = model.Select(m => m.PaidById).ToList(); - - var projectTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Projects.AsNoTracking().Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).ToListAsync(); - }); - var paidByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.AsNoTracking().Where(e => paidByIds.Contains(e.Id) && e.TenantId == tenantId).ToListAsync(); - }); - var createdByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.AsNoTracking().Where(e => createdByIds.Contains(e.Id) && e.TenantId == tenantId).ToListAsync(); - }); - var expenseCategoriesTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpenseCategoryMasters.AsNoTracking().Where(ec => expenseCategoryIds.Contains(ec.Id) && ec.TenantId == tenantId).ToListAsync(); - }); - var paymentModeTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.PaymentModeMatser.AsNoTracking().Where(pm => paymentModeIds.Contains(pm.Id)).ToListAsync(); - }); - var statusMappingTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesStatusMapping - .Include(s => s.Status) - .Include(s => s.NextStatus) - .AsNoTracking() - .Where(es => statusIds.Contains(es.StatusId) && es.Status != null) - .GroupBy(s => s.StatusId) - .Select(g => new - { - StatusId = g.Key, - Status = g.Select(s => s.Status).FirstOrDefault(), - NextStatus = g.Select(s => s.NextStatus).OrderBy(s => s!.Name).ToList() - }).ToListAsync(); - }); - var statusTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesStatusMaster - .AsNoTracking() - .Where(es => statusIds.Contains(es.Id)) - .ToListAsync(); - }); - var permissionStatusMappingTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.StatusPermissionMapping - .GroupBy(ps => ps.StatusId) - .Select(g => new - { - StatusId = g.Key, - PermissionIds = g.Select(ps => ps.PermissionId).ToList() - }).ToListAsync(); - }); - - // Await all prerequisite checks at once. - await Task.WhenAll(projectTask, expenseCategoriesTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, statusTask, permissionStatusMappingTask); - - var projects = projectTask.Result; - var expenseCategories = expenseCategoriesTask.Result; - var paymentModes = paymentModeTask.Result; - var statusMappings = statusMappingTask.Result; - var permissionStatusMappings = permissionStatusMappingTask.Result; - var paidBys = paidByTask.Result; - var createdBys = createdByTask.Result; - - expenseList = model.Select(m => - { - var response = _mapper.Map(m); - - response.Project = projects.Where(p => p.Id == m.ProjectId).Select(p => _mapper.Map(p)).FirstOrDefault(); - response.PaidBy = paidBys.Where(p => p.Id == m.PaidById).Select(p => _mapper.Map(p)).FirstOrDefault(); - response.CreatedBy = createdBys.Where(e => e.Id == m.CreatedById).Select(e => _mapper.Map(e)).FirstOrDefault(); - response.Status = statusMappings.Where(s => s.StatusId == m.StatusId).Select(s => _mapper.Map(s.Status)).FirstOrDefault(); - if (response.Status == null) - { - var status = statusTask.Result; - response.Status = status.Where(s => s.Id == m.StatusId).Select(s => _mapper.Map(s)).FirstOrDefault(); - } - if (response.Status != null) - { - response.Status.PermissionIds = permissionStatusMappings.Where(ps => ps.StatusId == m.StatusId).Select(ps => ps.PermissionIds).FirstOrDefault(); - } - response.NextStatus = statusMappings.Where(s => s.StatusId == m.StatusId).Select(s => _mapper.Map>(s.NextStatus)).FirstOrDefault(); - if (response.NextStatus != null) - { - foreach (var status in response.NextStatus) - { - status.PermissionIds = permissionStatusMappings.Where(ps => ps.StatusId == status.Id).Select(ps => ps.PermissionIds).FirstOrDefault(); - } - } - response.PaymentMode = paymentModes.Where(pm => pm.Id == m.PaymentModeId).Select(pm => _mapper.Map(pm)).FirstOrDefault(); - response.ExpenseCategory = expenseCategories.Where(ec => ec.Id == m.ExpenseCategoryId).Select(ec => _mapper.Map(ec)).FirstOrDefault(); - - return response; - }).ToList(); - - return expenseList; - } private async Task GetAllExpnesRelatedTablesForSingle(Expenses model, Guid tenantId) { var statusMappingTask = Task.Run(async () => @@ -3068,6 +2953,8 @@ namespace Marco.Pms.Services.Service var response = _mapper.Map(model); response.ExpenseUId = $"{model.UIDPrefix}/{model.UIDPostfix:D5}"; + if (model.PaymentRequest != null) + response.PaymentRequestUID = $"{model.PaymentRequest.UIDPrefix}/{model.PaymentRequest.UIDPostfix:D5}"; response.Project = _mapper.Map(model.Project); response.PaidBy = _mapper.Map(model.PaidBy); response.CreatedBy = _mapper.Map(model.CreatedBy);