Made StatusId Nullable In StatusUpdateLog Table
This commit is contained in:
parent
72d03539ce
commit
dc267b8f61
7462
Marco.Pms.DataAccess/Migrations/20251108094424_Made_StatusId_Nullable_In_StatusUpdateLog_Table.Designer.cs
generated
Normal file
7462
Marco.Pms.DataAccess/Migrations/20251108094424_Made_StatusId_Nullable_In_StatusUpdateLog_Table.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Marco.Pms.DataAccess.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Made_StatusId_Nullable_In_StatusUpdateLog_Table : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<Guid>(
|
||||||
|
name: "StatusId",
|
||||||
|
table: "StatusUpdateLogs",
|
||||||
|
type: "char(36)",
|
||||||
|
nullable: true,
|
||||||
|
collation: "ascii_general_ci",
|
||||||
|
oldClrType: typeof(Guid),
|
||||||
|
oldType: "char(36)")
|
||||||
|
.OldAnnotation("Relational:Collation", "ascii_general_ci");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<Guid>(
|
||||||
|
name: "StatusId",
|
||||||
|
table: "StatusUpdateLogs",
|
||||||
|
type: "char(36)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||||
|
collation: "ascii_general_ci",
|
||||||
|
oldClrType: typeof(Guid),
|
||||||
|
oldType: "char(36)",
|
||||||
|
oldNullable: true)
|
||||||
|
.OldAnnotation("Relational:Collation", "ascii_general_ci");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3971,7 +3971,7 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
b.Property<Guid>("NextStatusId")
|
b.Property<Guid>("NextStatusId")
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<Guid>("StatusId")
|
b.Property<Guid?>("StatusId")
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<Guid>("TenantId")
|
b.Property<Guid>("TenantId")
|
||||||
|
|||||||
@ -8,7 +8,7 @@ namespace Marco.Pms.Model.Master
|
|||||||
public class StatusUpdateLog : TenantRelation
|
public class StatusUpdateLog : TenantRelation
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid StatusId { get; set; }
|
public Guid? StatusId { get; set; }
|
||||||
public Guid NextStatusId { get; set; }
|
public Guid NextStatusId { get; set; }
|
||||||
public Guid EntityId { get; set; }
|
public Guid EntityId { get; set; }
|
||||||
public string? Comment { get; set; }
|
public string? Comment { get; set; }
|
||||||
|
|||||||
@ -41,6 +41,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
private readonly CacheUpdateHelper _cache;
|
private readonly CacheUpdateHelper _cache;
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
//Expense Status
|
||||||
private static readonly Guid Draft = Guid.Parse("297e0d8f-f668-41b5-bfea-e03b354251c8");
|
private static readonly Guid Draft = Guid.Parse("297e0d8f-f668-41b5-bfea-e03b354251c8");
|
||||||
private static readonly Guid Review = Guid.Parse("6537018f-f4e9-4cb3-a210-6c3b2da999d7");
|
private static readonly Guid Review = Guid.Parse("6537018f-f4e9-4cb3-a210-6c3b2da999d7");
|
||||||
private static readonly Guid RejectedByReviewer = Guid.Parse("965eda62-7907-4963-b4a1-657fb0b2724b");
|
private static readonly Guid RejectedByReviewer = Guid.Parse("965eda62-7907-4963-b4a1-657fb0b2724b");
|
||||||
@ -48,9 +49,12 @@ namespace Marco.Pms.Services.Service
|
|||||||
private static readonly Guid RejectedByApprover = Guid.Parse("d1ee5eec-24b6-4364-8673-a8f859c60729");
|
private static readonly Guid RejectedByApprover = Guid.Parse("d1ee5eec-24b6-4364-8673-a8f859c60729");
|
||||||
private static readonly Guid ProcessPending = Guid.Parse("f18c5cfd-7815-4341-8da2-2c2d65778e27");
|
private static readonly Guid ProcessPending = Guid.Parse("f18c5cfd-7815-4341-8da2-2c2d65778e27");
|
||||||
private static readonly Guid Processed = Guid.Parse("61578360-3a49-4c34-8604-7b35a3787b95");
|
private static readonly Guid Processed = Guid.Parse("61578360-3a49-4c34-8604-7b35a3787b95");
|
||||||
|
private static readonly Guid Done = Guid.Parse("b8586f67-dc19-49c3-b4af-224149efe1d3");
|
||||||
|
|
||||||
|
// Payment mode
|
||||||
private static readonly Guid AdvancePayment = Guid.Parse("f67beee6-6763-4108-922c-03bd86b9178d");
|
private static readonly Guid AdvancePayment = Guid.Parse("f67beee6-6763-4108-922c-03bd86b9178d");
|
||||||
|
|
||||||
|
// Recurring payment status
|
||||||
private static readonly Guid ActiveTemplateStatus = Guid.Parse("da462422-13b2-45cc-a175-910a225f6fc8");
|
private static readonly Guid ActiveTemplateStatus = Guid.Parse("da462422-13b2-45cc-a175-910a225f6fc8");
|
||||||
|
|
||||||
|
|
||||||
@ -262,18 +266,18 @@ namespace Marco.Pms.Services.Service
|
|||||||
}).ToListAsync();
|
}).ToListAsync();
|
||||||
|
|
||||||
expenseVM = cacheList.Select(m =>
|
expenseVM = cacheList.Select(m =>
|
||||||
|
{
|
||||||
|
var response = _mapper.Map<ExpenseList>(m);
|
||||||
|
if (response.Status != null && (response.NextStatus?.Any() ?? false))
|
||||||
{
|
{
|
||||||
var response = _mapper.Map<ExpenseList>(m);
|
response.Status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == Guid.Parse(m.Status.Id)).Select(ps => ps.PermissionIds).FirstOrDefault();
|
||||||
if (response.Status != null && (response.NextStatus?.Any() ?? false))
|
foreach (var status in response.NextStatus)
|
||||||
{
|
{
|
||||||
response.Status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == Guid.Parse(m.Status.Id)).Select(ps => ps.PermissionIds).FirstOrDefault();
|
status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == status.Id).Select(ps => ps.PermissionIds).FirstOrDefault();
|
||||||
foreach (var status in response.NextStatus)
|
|
||||||
{
|
|
||||||
status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == status.Id).Select(ps => ps.PermissionIds).FirstOrDefault();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return response;
|
}
|
||||||
}).ToList();
|
return response;
|
||||||
|
}).ToList();
|
||||||
totalEntites = (int)totalCount;
|
totalEntites = (int)totalCount;
|
||||||
}
|
}
|
||||||
// 7. --- Return Final Success Response ---
|
// 7. --- Return Final Success Response ---
|
||||||
@ -351,16 +355,16 @@ namespace Marco.Pms.Services.Service
|
|||||||
var vm = _mapper.Map<ExpenseDetailsVM>(expenseDetails);
|
var vm = _mapper.Map<ExpenseDetailsVM>(expenseDetails);
|
||||||
|
|
||||||
var permissionStatusMappingTask = Task.Run(async () =>
|
var permissionStatusMappingTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
return await dbContext.StatusPermissionMapping
|
return await dbContext.StatusPermissionMapping
|
||||||
.GroupBy(ps => ps.StatusId)
|
.GroupBy(ps => ps.StatusId)
|
||||||
.Select(g => new
|
.Select(g => new
|
||||||
{
|
{
|
||||||
StatusId = g.Key,
|
StatusId = g.Key,
|
||||||
PermissionIds = g.Select(ps => ps.PermissionId).ToList()
|
PermissionIds = g.Select(ps => ps.PermissionId).ToList()
|
||||||
}).ToListAsync();
|
}).ToListAsync();
|
||||||
});
|
});
|
||||||
var expenseReimburseTask = Task.Run(async () =>
|
var expenseReimburseTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
@ -447,7 +451,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
PaidBy = expenses.Where(e => e.PaidBy != null).Select(e => new { Id = e.PaidBy!.Id, Name = $"{e.PaidBy.FirstName} {e.PaidBy.LastName}" }).Distinct().ToList(),
|
PaidBy = expenses.Where(e => e.PaidBy != null).Select(e => new { Id = e.PaidBy!.Id, Name = $"{e.PaidBy.FirstName} {e.PaidBy.LastName}" }).Distinct().ToList(),
|
||||||
CreatedBy = expenses.Where(e => e.CreatedBy != null).Select(e => new { Id = e.CreatedBy!.Id, Name = $"{e.CreatedBy.FirstName} {e.CreatedBy.LastName}" }).Distinct().ToList(),
|
CreatedBy = expenses.Where(e => e.CreatedBy != null).Select(e => new { Id = e.CreatedBy!.Id, Name = $"{e.CreatedBy.FirstName} {e.CreatedBy.LastName}" }).Distinct().ToList(),
|
||||||
Status = expenses.Where(e => e.Status != null).Select(e => new { Id = e.Status!.Id, Name = e.Status.Name }).Distinct().ToList(),
|
Status = expenses.Where(e => e.Status != null).Select(e => new { Id = e.Status!.Id, Name = e.Status.Name }).Distinct().ToList(),
|
||||||
ExpensesCategory = expenses.Where(e => e.ExpenseCategory != null).Select(e => new { Id = e.ExpenseCategory!.Id, Name = e.ExpenseCategory.Name }).Distinct().ToList()
|
ExpenseCategory = expenses.Where(e => e.ExpenseCategory != null).Select(e => new { Id = e.ExpenseCategory!.Id, Name = e.ExpenseCategory.Name }).Distinct().ToList()
|
||||||
};
|
};
|
||||||
return ApiResponse<object>.SuccessResponse(response, "Successfully fetched the filter list", 200);
|
return ApiResponse<object>.SuccessResponse(response, "Successfully fetched the filter list", 200);
|
||||||
}
|
}
|
||||||
@ -835,15 +839,22 @@ namespace Marco.Pms.Services.Service
|
|||||||
$"The sum of the base amount and tax amount ({totalAmount}) does not match the expected expense amount ({expense.Amount}).",
|
$"The sum of the base amount and tax amount ({totalAmount}) does not match the expected expense amount ({expense.Amount}).",
|
||||||
400);
|
400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var result = ValidateTdsPercentage(model.TDSPercentage);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
expense.ProcessedById = loggedInEmployee.Id;
|
expense.ProcessedById = loggedInEmployee.Id;
|
||||||
expense.BaseAmount = model.BaseAmount;
|
expense.BaseAmount = model.BaseAmount;
|
||||||
expense.TaxAmount = model.TaxAmount;
|
expense.TaxAmount = model.TaxAmount;
|
||||||
|
expense.TDSPercentage = model.TDSPercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Add Reimbursement if applicable
|
// 7. Add Reimbursement if applicable
|
||||||
if (model.StatusId == Processed)
|
if (model.StatusId == Processed)
|
||||||
{
|
{
|
||||||
expense.TDSPercentage = model.TDSPercentage;
|
|
||||||
var reimbursement = new ExpensesReimburse
|
var reimbursement = new ExpensesReimburse
|
||||||
{
|
{
|
||||||
ReimburseTransactionId = model.ReimburseTransactionId!,
|
ReimburseTransactionId = model.ReimburseTransactionId!,
|
||||||
@ -1339,8 +1350,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
{
|
{
|
||||||
var result = _mapper.Map<PaymentRequestVM>(pr);
|
var result = _mapper.Map<PaymentRequestVM>(pr);
|
||||||
result.PaymentRequestUID = $"{pr.UIDPrefix}/{pr.UIDPostfix:D5}";
|
result.PaymentRequestUID = $"{pr.UIDPrefix}/{pr.UIDPostfix:D5}";
|
||||||
//if (pr.RecurringPayment != null)
|
|
||||||
// result.RecurringPaymentUID = $"{pr.RecurringPayment.UIDPrefix}/{pr.RecurringPayment.UIDPostfix:D5}";
|
|
||||||
return result;
|
return result;
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
@ -1485,7 +1494,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
var nextStatuses = await context.ExpensesStatusMapping
|
var nextStatuses = await context.ExpensesStatusMapping
|
||||||
.Include(esm => esm.NextStatus)
|
.Include(esm => esm.NextStatus)
|
||||||
.Where(esm => esm.StatusId == paymentRequest.ExpenseStatusId && esm.NextStatus != null)
|
.Where(esm => esm.StatusId == paymentRequest.ExpenseStatusId && esm.NextStatus != null && !(esm.NextStatusId == Done && paymentRequest.IsAdvancePayment))
|
||||||
.Select(esm => esm.NextStatus!)
|
.Select(esm => esm.NextStatus!)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@ -1557,7 +1566,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
var attachmentVMs = documentTask.Result;
|
var attachmentVMs = documentTask.Result;
|
||||||
var updateLogs = updateLogsTask.Result;
|
var updateLogs = updateLogsTask.Result;
|
||||||
|
|
||||||
var statusIds = updateLogs.Select(sul => sul.StatusId).ToList();
|
var statusIds = updateLogs.Where(sul => sul.StatusId.HasValue).Select(sul => sul.StatusId!.Value).ToList();
|
||||||
statusIds.AddRange(updateLogs.Select(sul => sul.NextStatusId).ToList());
|
statusIds.AddRange(updateLogs.Select(sul => sul.NextStatusId).ToList());
|
||||||
|
|
||||||
statusIds = statusIds.Distinct().ToList();
|
statusIds = statusIds.Distinct().ToList();
|
||||||
@ -1746,7 +1755,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
{
|
{
|
||||||
Id = Guid.NewGuid(),
|
Id = Guid.NewGuid(),
|
||||||
EntityId = paymentRequest.Id,
|
EntityId = paymentRequest.Id,
|
||||||
StatusId = Draft,
|
//StatusId = Draft,
|
||||||
NextStatusId = Draft,
|
NextStatusId = Draft,
|
||||||
UpdatedById = loggedInEmployee.Id,
|
UpdatedById = loggedInEmployee.Id,
|
||||||
UpdatedAt = DateTime.UtcNow,
|
UpdatedAt = DateTime.UtcNow,
|
||||||
@ -2507,7 +2516,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Recurring Payment Functions ===================================================================
|
#region =================================================================== Recurring Payment Functions ===================================================================
|
||||||
|
|
||||||
public async Task<ApiResponse<object>> GetRecurringPaymentListAsync(string? searchString, string? filter, bool isActive, int pageSize, int pageNumber, Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> GetRecurringPaymentListAsync(string? searchString, string? filter, bool isActive, int pageSize, int pageNumber, Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
_logger.LogInfo("Start GetRecurringPaymentListAsync called by EmployeeId: {EmployeeId} for TenantId: {TenantId}, PageNumber: {PageNumber}, PageSize: {PageSize}",
|
_logger.LogInfo("Start GetRecurringPaymentListAsync called by EmployeeId: {EmployeeId} for TenantId: {TenantId}, PageNumber: {PageNumber}, PageSize: {PageSize}",
|
||||||
@ -2787,7 +2795,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
_logger.LogInfo("End GetRecurringPaymentDetailsAsync called by EmployeeId: {EmployeeId}", loggedInEmployee.Id);
|
_logger.LogInfo("End GetRecurringPaymentDetailsAsync called by EmployeeId: {EmployeeId}", loggedInEmployee.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ApiResponse<object>> CreateRecurringPaymentAsync(CreateRecurringTemplateDto model, Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> CreateRecurringPaymentAsync(CreateRecurringTemplateDto model, Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
_logger.LogInfo("Start CreateRecurringPaymentAsync called by EmployeeId: {EmployeeId} for TenantId: {TenantId}", loggedInEmployee.Id, tenantId);
|
_logger.LogInfo("Start CreateRecurringPaymentAsync called by EmployeeId: {EmployeeId} for TenantId: {TenantId}", loggedInEmployee.Id, tenantId);
|
||||||
@ -3148,7 +3155,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
_logger.LogInfo("End EditRecurringPaymentAsync called by EmployeeId: {EmployeeId}", loggedInEmployee.Id);
|
_logger.LogInfo("End EditRecurringPaymentAsync called by EmployeeId: {EmployeeId}", loggedInEmployee.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Advance Payment Functions ===================================================================
|
#region =================================================================== Advance Payment Functions ===================================================================
|
||||||
@ -3341,7 +3347,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
if ((!isRejected) || (isRejected && (loggedInEmployeeId == model.CreatedById || hasManagePermission)))
|
if ((!isRejected) || (isRejected && (loggedInEmployeeId == model.CreatedById || hasManagePermission)))
|
||||||
{
|
{
|
||||||
response.NextStatus = _mapper.Map<List<ExpensesStatusMasterMongoDB>>(statusMapping.NextStatus);
|
response.NextStatus = statusMapping.NextStatus.Where(ns => ns != null && ns.Id != Done).Select(ns => _mapper.Map<ExpensesStatusMasterMongoDB>(ns)).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (response.Status == null)
|
if (response.Status == null)
|
||||||
@ -3675,77 +3681,107 @@ namespace Marco.Pms.Services.Service
|
|||||||
await Task.WhenAll(attachmentTask, documentsTask);
|
await Task.WhenAll(attachmentTask, documentsTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if recurring payments are applicable based on frequency, iteration count, and date logic.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="numberOfIteration">Maximum allowed payment iterations.</param>
|
||||||
|
/// <param name="frequency">Frequency of recurring payments (e.g., Monthly, Quarterly).</param>
|
||||||
|
/// <param name="strikeDate">The starting date for recurring payments.</param>
|
||||||
|
/// <param name="latestPRGeneratedAt">The date of the latest payment receipt, if any.</param>
|
||||||
|
/// <returns>True if recurring payments are applicable; otherwise, false.</returns>
|
||||||
private static bool IsRecurringApplicable(int numberOfIteration, PLAN_FREQUENCY frequency, DateTime strikeDate, DateTime? latestPRGeneratedAt)
|
private static bool IsRecurringApplicable(int numberOfIteration, PLAN_FREQUENCY frequency, DateTime strikeDate, DateTime? latestPRGeneratedAt)
|
||||||
{
|
{
|
||||||
List<DateTime> dates = new List<DateTime>();
|
// Validate input parameters
|
||||||
DateTime currentDate = strikeDate;
|
if (numberOfIteration <= 0)
|
||||||
DateTime endDate = DateTime.UtcNow.Date;
|
|
||||||
|
|
||||||
switch (frequency)
|
|
||||||
{
|
{
|
||||||
case PLAN_FREQUENCY.MONTHLY:
|
return false;
|
||||||
while (currentDate <= endDate)
|
|
||||||
{
|
|
||||||
dates.Add(currentDate);
|
|
||||||
currentDate = currentDate.AddMonths(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PLAN_FREQUENCY.QUARTERLY:
|
|
||||||
while (currentDate <= endDate)
|
|
||||||
{
|
|
||||||
dates.Add(currentDate);
|
|
||||||
currentDate = currentDate.AddMonths(3);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PLAN_FREQUENCY.HALF_YEARLY:
|
|
||||||
while (currentDate <= endDate)
|
|
||||||
{
|
|
||||||
dates.Add(currentDate);
|
|
||||||
currentDate = currentDate.AddMonths(6);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PLAN_FREQUENCY.YEARLY:
|
|
||||||
while (currentDate <= endDate)
|
|
||||||
{
|
|
||||||
dates.Add(currentDate);
|
|
||||||
currentDate = currentDate.AddYears(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PLAN_FREQUENCY.DAILY:
|
|
||||||
while (currentDate <= endDate)
|
|
||||||
{
|
|
||||||
dates.Add(currentDate);
|
|
||||||
currentDate = currentDate.AddDays(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PLAN_FREQUENCY.WEEKLY:
|
|
||||||
while (currentDate <= endDate)
|
|
||||||
{
|
|
||||||
dates.Add(currentDate);
|
|
||||||
currentDate = currentDate.AddDays(7);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure strikeDate is in a consistent timezone (UTC or local as per your business logic)
|
||||||
|
var currentDate = strikeDate.Date;
|
||||||
|
var endDate = DateTime.UtcNow.Date;
|
||||||
|
|
||||||
|
// List to store generated dates for validation
|
||||||
|
var dates = new List<DateTime>();
|
||||||
|
|
||||||
|
// Define increment logic for each frequency
|
||||||
|
Func<DateTime, DateTime> incrementFunc = frequency switch
|
||||||
|
{
|
||||||
|
PLAN_FREQUENCY.MONTHLY => d => d.AddMonths(1),
|
||||||
|
PLAN_FREQUENCY.QUARTERLY => d => d.AddMonths(3),
|
||||||
|
PLAN_FREQUENCY.HALF_YEARLY => d => d.AddMonths(6),
|
||||||
|
PLAN_FREQUENCY.YEARLY => d => d.AddYears(1),
|
||||||
|
PLAN_FREQUENCY.DAILY => d => d.AddDays(1),
|
||||||
|
PLAN_FREQUENCY.WEEKLY => d => d.AddDays(7),
|
||||||
|
_ => d => d.AddDays(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return false if frequency is not supported
|
||||||
|
if (incrementFunc == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate dates based on frequency until endDate
|
||||||
|
while (currentDate <= endDate)
|
||||||
|
{
|
||||||
|
dates.Add(currentDate);
|
||||||
|
currentDate = incrementFunc(currentDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validation: Must have at least one date and not exceed iteration count
|
||||||
if (!dates.Any() || dates.Count > numberOfIteration)
|
if (!dates.Any() || dates.Count > numberOfIteration)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validation: Last generated date must match endDate
|
||||||
if (dates.Last() != endDate)
|
if (dates.Last() != endDate)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (latestPRGeneratedAt.HasValue && latestPRGeneratedAt.Value == endDate)
|
// Validation: Latest payment receipt should not be on endDate
|
||||||
|
if (latestPRGeneratedAt.HasValue && latestPRGeneratedAt.Value.Date == endDate)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates the TDS Percentage in the provided model.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">The input model containing TDS Percentage.</param>
|
||||||
|
/// <returns>Returns an error response if validation fails; otherwise, null.</returns>
|
||||||
|
private ApiResponse<object>? ValidateTdsPercentage(double? TDSPercentage)
|
||||||
|
{
|
||||||
|
// Check if TDSPercentage is present in the model
|
||||||
|
if (!TDSPercentage.HasValue)
|
||||||
|
{
|
||||||
|
return null; // No validation needed if TDSPercentage is not provided
|
||||||
|
}
|
||||||
|
|
||||||
|
var tdsValue = TDSPercentage.Value;
|
||||||
|
|
||||||
|
// Validate TDS Percentage range: must be between 0 and 100 inclusive
|
||||||
|
if (tdsValue < 0 || tdsValue > 100)
|
||||||
|
{
|
||||||
|
// Log a warning with structured logging for traceability
|
||||||
|
_logger.LogWarning("TDS Percentage validation failed. Provided value: {TdsValue} is outside the valid range (0 - 100).", tdsValue);
|
||||||
|
|
||||||
|
// Return a consistent and clear error response with HTTP status 400
|
||||||
|
return ApiResponse<object>.ErrorResponse(
|
||||||
|
"Invalid TDS Percentage value. Allowed range is 0 to 100 inclusive.",
|
||||||
|
"TDS Percentage value out of range.",
|
||||||
|
400);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // Validation successful, no error
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,18 +10,15 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
public interface IMasterService
|
public interface IMasterService
|
||||||
{
|
{
|
||||||
#region =================================================================== Recurring Payment Status APIs ===================================================================
|
#region =================================================================== Recurring Payment Status APIs ===================================================================
|
||||||
|
|
||||||
Task<ApiResponse<object>> GetRecurringPaymentStatusAsync(Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetRecurringPaymentStatusAsync(Employee loggedInEmployee, Guid tenantId);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Currency APIs ===================================================================
|
#region =================================================================== Currency APIs ===================================================================
|
||||||
|
|
||||||
Task<ApiResponse<object>> GetCurrencyAsync(Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetCurrencyAsync(Employee loggedInEmployee, Guid tenantId);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
#region =================================================================== Organization Type APIs ===================================================================
|
#region =================================================================== Organization Type APIs ===================================================================
|
||||||
|
|
||||||
Task<ApiResponse<object>> GetOrganizationTypesAsync(Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetOrganizationTypesAsync(Employee loggedInEmployee, Guid tenantId);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user