Added the ExpenseUId in expenses tables
This commit is contained in:
parent
f94a7de4ab
commit
04223578ad
6209
Marco.Pms.DataAccess/Migrations/20251004112239_Added_ExpenceUID_In_Expense_Table.Designer.cs
generated
Normal file
6209
Marco.Pms.DataAccess/Migrations/20251004112239_Added_ExpenceUID_In_Expense_Table.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Marco.Pms.DataAccess.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Added_ExpenceUID_In_Expense_Table : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "ExpenseUId",
|
||||||
|
table: "Expenses",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ExpenseUId",
|
||||||
|
table: "Expenses");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1832,6 +1832,10 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("ExpenseUId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<Guid>("ExpensesTypeId")
|
b.Property<Guid>("ExpensesTypeId")
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ namespace Marco.Pms.Model.Expenses
|
|||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
public string? TransactionId { get; set; }
|
public string? TransactionId { get; set; }
|
||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; } = string.Empty;
|
||||||
|
public string ExpenseUId { get; set; } = string.Empty;
|
||||||
public string? Location { get; set; }
|
public string? Location { get; set; }
|
||||||
public string? GSTNumber { get; set; }
|
public string? GSTNumber { get; set; }
|
||||||
public string SupplerName { get; set; } = string.Empty;
|
public string SupplerName { get; set; } = string.Empty;
|
||||||
|
@ -19,6 +19,7 @@ namespace Marco.Pms.Model.MongoDBModels.Expenses
|
|||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
public DateTime ExpireAt { get; set; } = DateTime.UtcNow.Date.AddDays(1);
|
public DateTime ExpireAt { get; set; } = DateTime.UtcNow.Date.AddDays(1);
|
||||||
public string SupplerName { get; set; } = string.Empty;
|
public string SupplerName { get; set; } = string.Empty;
|
||||||
|
public string? ExpenseUId { get; set; }
|
||||||
public double Amount { get; set; }
|
public double Amount { get; set; }
|
||||||
public ExpensesStatusMasterMongoDB Status { get; set; } = new ExpensesStatusMasterMongoDB();
|
public ExpensesStatusMasterMongoDB Status { get; set; } = new ExpensesStatusMasterMongoDB();
|
||||||
public List<ExpensesStatusMasterMongoDB> NextStatus { get; set; } = new List<ExpensesStatusMasterMongoDB>();
|
public List<ExpensesStatusMasterMongoDB> NextStatus { get; set; } = new List<ExpensesStatusMasterMongoDB>();
|
||||||
|
@ -19,6 +19,7 @@ namespace Marco.Pms.Model.ViewModels.Expenses
|
|||||||
public DateTime TransactionDate { get; set; }
|
public DateTime TransactionDate { get; set; }
|
||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
public string SupplerName { get; set; } = string.Empty;
|
public string SupplerName { get; set; } = string.Empty;
|
||||||
|
public string? ExpenseUId { get; set; }
|
||||||
public double Amount { get; set; }
|
public double Amount { get; set; }
|
||||||
public ExpensesStatusMasterVM? Status { get; set; }
|
public ExpensesStatusMasterVM? Status { get; set; }
|
||||||
public List<ExpensesStatusMasterVM>? NextStatus { get; set; }
|
public List<ExpensesStatusMasterVM>? NextStatus { get; set; }
|
||||||
|
@ -18,6 +18,7 @@ namespace Marco.Pms.Model.ViewModels.Expanses
|
|||||||
public DateTime TransactionDate { get; set; }
|
public DateTime TransactionDate { get; set; }
|
||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
public string SupplerName { get; set; } = string.Empty;
|
public string SupplerName { get; set; } = string.Empty;
|
||||||
|
public string? ExpenseUId { get; set; }
|
||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; } = string.Empty;
|
||||||
public string TransactionId { get; set; } = string.Empty;
|
public string TransactionId { get; set; } = string.Empty;
|
||||||
public double Amount { get; set; }
|
public double Amount { get; set; }
|
||||||
|
@ -33,11 +33,11 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
#region =================================================================== Contact Get APIs ===================================================================
|
#region =================================================================== Contact Get APIs ===================================================================
|
||||||
|
|
||||||
[HttpGet("list")]
|
[HttpGet("list")]
|
||||||
public async Task<IActionResult> GetContactList([FromQuery] string? search, [FromQuery] string? filter, [FromQuery] Guid? projectId, [FromQuery] bool active = true,
|
public async Task<IActionResult> GetContactList([FromQuery] string? searchString, [FromQuery] string? filter, [FromQuery] Guid? projectId, [FromQuery] bool active = true,
|
||||||
[FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20)
|
[FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20)
|
||||||
{
|
{
|
||||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _directoryService.GetListOfContactsAsync(search: search, filter: filter, projectId: projectId, active: active, pageSize: pageSize, pageNumber: pageNumber, tenantId, loggedInEmployee);
|
var response = await _directoryService.GetListOfContactsAsync(search: searchString, filter: filter, projectId: projectId, active: active, pageSize: pageSize, pageNumber: pageNumber, tenantId, loggedInEmployee);
|
||||||
|
|
||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
|
|
||||||
|
@ -625,10 +625,10 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
if (model.Id.HasValue && model.Id.Value != Guid.Empty)
|
if (model.Id.HasValue && model.Id.Value != Guid.Empty)
|
||||||
{
|
{
|
||||||
existingEmployee = await _context.Employees
|
existingEmployee = await _context.Employees
|
||||||
.FirstOrDefaultAsync(e => e.Id == model.Id && e.OrganizationId == model.OrganizationId);
|
.FirstOrDefaultAsync(e => e.Id == model.Id);
|
||||||
if (existingEmployee == null)
|
if (existingEmployee == null)
|
||||||
{
|
{
|
||||||
_logger.LogInfo("Employee not found for update. Id={EmployeeId}, Org={OrgId}", model.Id, model.OrganizationId);
|
_logger.LogInfo("Employee not found for update. Id={EmployeeId}", model.Id);
|
||||||
return NotFound(ApiResponse<object>.ErrorResponse("Employee not found", "Employee not found in database", 404));
|
return NotFound(ApiResponse<object>.ErrorResponse("Employee not found", "Employee not found in database", 404));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -986,7 +986,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
// Update path: fetch scoped to tenant
|
// Update path: fetch scoped to tenant
|
||||||
var employeeId = model.Id.Value;
|
var employeeId = model.Id.Value;
|
||||||
var existingEmployee = await _context.Employees
|
var existingEmployee = await _context.Employees
|
||||||
.FirstOrDefaultAsync(e => e.Id == employeeId && e.TenantId == tenantId); // tenant-safe lookup
|
.FirstOrDefaultAsync(e => e.Id == employeeId); // tenant-safe lookup
|
||||||
|
|
||||||
if (existingEmployee is null)
|
if (existingEmployee is null)
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
using MarcoBMS.Services.Service;
|
using MarcoBMS.Services.Service;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
|
||||||
namespace Marco.Pms.Services.Hubs
|
namespace Marco.Pms.Services.Hubs
|
||||||
{
|
{
|
||||||
[Authorize]
|
|
||||||
public class MarcoHub : Hub
|
public class MarcoHub : Hub
|
||||||
{
|
{
|
||||||
private readonly ILoggingService _logger;
|
private readonly ILoggingService _logger;
|
||||||
|
@ -23,6 +23,7 @@ using MarcoBMS.Services.Service;
|
|||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using Document = Marco.Pms.Model.DocumentManager.Document;
|
using Document = Marco.Pms.Model.DocumentManager.Document;
|
||||||
|
|
||||||
namespace Marco.Pms.Services.Service
|
namespace Marco.Pms.Services.Service
|
||||||
@ -487,6 +488,15 @@ namespace Marco.Pms.Services.Service
|
|||||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
return await dbContext.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(pm => pm.Id == dto.PaymentModeId);
|
return await dbContext.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(pm => pm.Id == dto.PaymentModeId);
|
||||||
});
|
});
|
||||||
|
var expenseUIdTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
var result = await dbContext.Expenses
|
||||||
|
.Where(e => !string.IsNullOrWhiteSpace(e.ExpenseUId)).ToListAsync();
|
||||||
|
return result
|
||||||
|
.Select(e => ExtractNumber(e.ExpenseUId))
|
||||||
|
.OrderByDescending(id => id).FirstOrDefault();
|
||||||
|
});
|
||||||
var statusMappingTask = Task.Run(async () =>
|
var statusMappingTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
@ -506,10 +516,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
|
|
||||||
// Await all prerequisite checks at once.
|
// Await all prerequisite checks at once.
|
||||||
await Task.WhenAll(
|
await Task.WhenAll(hasUploadPermissionTask, hasProjectPermissionTask, projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, expenseUIdTask);
|
||||||
hasUploadPermissionTask, hasProjectPermissionTask,
|
|
||||||
projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask
|
|
||||||
);
|
|
||||||
|
|
||||||
// 2. Aggregate and Check Results
|
// 2. Aggregate and Check Results
|
||||||
if (!await hasUploadPermissionTask || !await hasProjectPermissionTask)
|
if (!await hasUploadPermissionTask || !await hasProjectPermissionTask)
|
||||||
@ -519,11 +526,12 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
var validationErrors = new List<string>();
|
var validationErrors = new List<string>();
|
||||||
var project = await projectTask;
|
var project = projectTask.Result;
|
||||||
var expenseType = await expenseTypeTask;
|
var expenseType = expenseTypeTask.Result;
|
||||||
var paymentMode = await paymentModeTask;
|
var paymentMode = paymentModeTask.Result;
|
||||||
var statusMapping = await statusMappingTask;
|
var statusMapping = statusMappingTask.Result;
|
||||||
var paidBy = await paidByTask;
|
var paidBy = paidByTask.Result;
|
||||||
|
var lastExpenseUId = expenseUIdTask.Result;
|
||||||
|
|
||||||
if (project == null) validationErrors.Add("Project not found.");
|
if (project == null) validationErrors.Add("Project not found.");
|
||||||
if (paidBy == null) validationErrors.Add("Paid by employee not found");
|
if (paidBy == null) validationErrors.Add("Paid by employee not found");
|
||||||
@ -539,9 +547,10 @@ namespace Marco.Pms.Services.Service
|
|||||||
_logger.LogWarning("Expense creation failed due to validation errors: {ValidationErrors}", errorMessage);
|
_logger.LogWarning("Expense creation failed due to validation errors: {ValidationErrors}", errorMessage);
|
||||||
return ApiResponse<object>.ErrorResponse("Invalid input data.", errorMessage, 400);
|
return ApiResponse<object>.ErrorResponse("Invalid input data.", errorMessage, 400);
|
||||||
}
|
}
|
||||||
|
var currentexpenseUId = (lastExpenseUId + 1).ToString("D5");
|
||||||
// 3. Entity Creation
|
// 3. Entity Creation
|
||||||
var expense = _mapper.Map<Expenses>(dto);
|
var expense = _mapper.Map<Expenses>(dto);
|
||||||
|
expense.ExpenseUId = $"EX-{currentexpenseUId}";
|
||||||
expense.CreatedById = loggedInEmployee.Id;
|
expense.CreatedById = loggedInEmployee.Id;
|
||||||
expense.CreatedAt = DateTime.UtcNow;
|
expense.CreatedAt = DateTime.UtcNow;
|
||||||
expense.TenantId = tenantId;
|
expense.TenantId = tenantId;
|
||||||
@ -1084,6 +1093,13 @@ namespace Marco.Pms.Services.Service
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Helper Functions ===================================================================
|
#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)
|
private static object ExceptionMapper(Exception ex)
|
||||||
{
|
{
|
||||||
return new
|
return new
|
||||||
|
Loading…
x
Reference in New Issue
Block a user