Added the payment request attachment in create payment request API
This commit is contained in:
parent
e821724e83
commit
e7edc2f45c
@ -106,6 +106,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
public DbSet<Expenses> Expenses { get; set; }
|
||||
public DbSet<ExpenseLog> ExpenseLogs { get; set; }
|
||||
public DbSet<ExpensesTypeMaster> ExpensesTypeMaster { get; set; }
|
||||
public DbSet<ExpenseCategoryMaster> ExpenseCategoryMasters { get; set; }
|
||||
public DbSet<PaymentModeMatser> PaymentModeMatser { get; set; }
|
||||
public DbSet<ExpensesStatusMaster> ExpensesStatusMaster { get; set; }
|
||||
public DbSet<BillAttachments> BillAttachments { get; set; }
|
||||
@ -114,6 +115,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
public DbSet<StatusPermissionMapping> StatusPermissionMapping { get; set; }
|
||||
public DbSet<ExpensesStatusMapping> ExpensesStatusMapping { get; set; }
|
||||
public DbSet<PaymentRequest> PaymentRequests { get; set; }
|
||||
public DbSet<PaymentRequestAttachment> PaymentRequestAttachments { get; set; }
|
||||
public DbSet<RecurringPayment> RecurringPayments { get; set; }
|
||||
public DbSet<AdvancePaymentTransaction> AdvancePaymentTransactions { get; set; }
|
||||
|
||||
@ -674,8 +676,8 @@ namespace Marco.Pms.DataAccess.Data
|
||||
StatusId = Guid.Parse("61578360-3a49-4c34-8604-7b35a3787b95")
|
||||
});
|
||||
|
||||
modelBuilder.Entity<ExpensesTypeMaster>().HasData(
|
||||
new ExpensesTypeMaster
|
||||
modelBuilder.Entity<ExpenseCategoryMaster>().HasData(
|
||||
new ExpenseCategoryMaster
|
||||
{
|
||||
Id = Guid.Parse("5e0c6227-d49d-41ff-9f1f-781f0aee2469"),
|
||||
Name = "Procurement",
|
||||
@ -685,7 +687,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
IsAttachmentRequried = true,
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new ExpensesTypeMaster
|
||||
new ExpenseCategoryMaster
|
||||
{
|
||||
Id = Guid.Parse("2de53163-0dbd-404b-8e60-1b02e6b4886a"),
|
||||
Name = "Transport",
|
||||
@ -695,7 +697,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
IsAttachmentRequried = false,
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new ExpensesTypeMaster
|
||||
new ExpenseCategoryMaster
|
||||
{
|
||||
Id = Guid.Parse("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"),
|
||||
Name = "Travelling",
|
||||
@ -705,7 +707,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
IsAttachmentRequried = false,
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new ExpensesTypeMaster
|
||||
new ExpenseCategoryMaster
|
||||
{
|
||||
Id = Guid.Parse("52484820-1b54-4865-8f0f-baa2b1d339b9"),
|
||||
Name = "Mobilization",
|
||||
@ -715,7 +717,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
IsAttachmentRequried = true,
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new ExpensesTypeMaster
|
||||
new ExpenseCategoryMaster
|
||||
{
|
||||
Id = Guid.Parse("fc59eb90-98ea-481c-b421-54bfa9e42d8f"),
|
||||
Name = "Employee Welfare",
|
||||
@ -725,7 +727,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
IsAttachmentRequried = true,
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new ExpensesTypeMaster
|
||||
new ExpenseCategoryMaster
|
||||
{
|
||||
Id = Guid.Parse("77013784-9324-4d8b-bd36-d6f928e68942"),
|
||||
Name = "Maintenance & Utilities",
|
||||
@ -735,7 +737,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
IsAttachmentRequried = true,
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new ExpensesTypeMaster
|
||||
new ExpenseCategoryMaster
|
||||
{
|
||||
Id = Guid.Parse("1e2d697a-76b4-4be8-bc66-87144561a1a0"),
|
||||
Name = "Vendor/Supplier Payments",
|
||||
@ -745,7 +747,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
IsAttachmentRequried = true,
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new ExpensesTypeMaster
|
||||
new ExpenseCategoryMaster
|
||||
{
|
||||
Id = Guid.Parse("4842fa61-64eb-4241-aebd-8282065af9f9"),
|
||||
Name = "Compliance & Safety",
|
||||
|
||||
7317
Marco.Pms.DataAccess/Migrations/20251101101344_Added_PaymentRequestAttachmnets_Table.Designer.cs
generated
Normal file
7317
Marco.Pms.DataAccess/Migrations/20251101101344_Added_PaymentRequestAttachmnets_Table.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_PaymentRequestAttachmnets_Table : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_PaymentRequests_ExpensesTypeMaster_ExpenseCategoryId",
|
||||
table: "PaymentRequests");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "ExpensesTypeMaster",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "ExpensesTypeMaster",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "ExpensesTypeMaster",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "ExpensesTypeMaster",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "ExpensesTypeMaster",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "ExpensesTypeMaster",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("77013784-9324-4d8b-bd36-d6f928e68942"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "ExpensesTypeMaster",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "ExpensesTypeMaster",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"));
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsAdvancePayment",
|
||||
table: "PaymentRequests",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ExpenseCategoryMasters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
NoOfPersonsRequired = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
IsAttachmentRequried = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ExpenseCategoryMasters", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ExpenseCategoryMasters_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PaymentRequestAttachments",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
PaymentRequestId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
DocumentId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PaymentRequestAttachments", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_PaymentRequestAttachments_Documents_DocumentId",
|
||||
column: x => x.DocumentId,
|
||||
principalTable: "Documents",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_PaymentRequestAttachments_PaymentRequests_PaymentRequestId",
|
||||
column: x => x.PaymentRequestId,
|
||||
principalTable: "PaymentRequests",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_PaymentRequestAttachments_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "ExpenseCategoryMasters",
|
||||
columns: new[] { "Id", "Description", "IsActive", "IsAttachmentRequried", "Name", "NoOfPersonsRequired", "TenantId" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"), "Scheduled payments for external services or goods.", true, true, "Vendor/Supplier Payments", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"), "Vehicle fuel, logistics services and delivery of goods or personnel.", true, false, "Transport", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"), "Government fees, insurance, inspections and safety-related expenditures.", true, true, "Compliance & Safety", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"), "Site setup costs including equipment deployment and temporary infrastructure.", true, true, "Mobilization", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), "Materials, equipment and supplies purchased for site operations.", true, true, "Procurement", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("77013784-9324-4d8b-bd36-d6f928e68942"), "Machinery servicing, electricity, water, and temporary office needs.", true, true, "Maintenance & Utilities", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"), "Delivery of personnel.", true, false, "Travelling", true, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"), " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.", true, true, "Employee Welfare", true, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExpenseCategoryMasters_TenantId",
|
||||
table: "ExpenseCategoryMasters",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PaymentRequestAttachments_DocumentId",
|
||||
table: "PaymentRequestAttachments",
|
||||
column: "DocumentId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PaymentRequestAttachments_PaymentRequestId",
|
||||
table: "PaymentRequestAttachments",
|
||||
column: "PaymentRequestId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PaymentRequestAttachments_TenantId",
|
||||
table: "PaymentRequestAttachments",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_PaymentRequests_ExpenseCategoryMasters_ExpenseCategoryId",
|
||||
table: "PaymentRequests",
|
||||
column: "ExpenseCategoryId",
|
||||
principalTable: "ExpenseCategoryMasters",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_PaymentRequests_ExpenseCategoryMasters_ExpenseCategoryId",
|
||||
table: "PaymentRequests");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ExpenseCategoryMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PaymentRequestAttachments");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsAdvancePayment",
|
||||
table: "PaymentRequests");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "ExpensesTypeMaster",
|
||||
columns: new[] { "Id", "Description", "IsActive", "IsAttachmentRequried", "Name", "NoOfPersonsRequired", "TenantId" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"), "Scheduled payments for external services or goods.", true, true, "Vendor/Supplier Payments", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"), "Vehicle fuel, logistics services and delivery of goods or personnel.", true, false, "Transport", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"), "Government fees, insurance, inspections and safety-related expenditures.", true, true, "Compliance & Safety", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"), "Site setup costs including equipment deployment and temporary infrastructure.", true, true, "Mobilization", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), "Materials, equipment and supplies purchased for site operations.", true, true, "Procurement", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("77013784-9324-4d8b-bd36-d6f928e68942"), "Machinery servicing, electricity, water, and temporary office needs.", true, true, "Maintenance & Utilities", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"), "Delivery of personnel.", true, false, "Travelling", true, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
|
||||
{ new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"), " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.", true, true, "Employee Welfare", true, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }
|
||||
});
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_PaymentRequests_ExpensesTypeMaster_ExpenseCategoryId",
|
||||
table: "PaymentRequests",
|
||||
column: "ExpenseCategoryId",
|
||||
principalTable: "ExpensesTypeMaster",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2137,6 +2137,121 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.ToTable("BillAttachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpenseCategoryMaster", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("IsAttachmentRequried")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("NoOfPersonsRequired")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<Guid>("TenantId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("ExpenseCategoryMasters");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"),
|
||||
Description = "Materials, equipment and supplies purchased for site operations.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Procurement",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"),
|
||||
Description = "Vehicle fuel, logistics services and delivery of goods or personnel.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = false,
|
||||
Name = "Transport",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"),
|
||||
Description = "Delivery of personnel.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = false,
|
||||
Name = "Travelling",
|
||||
NoOfPersonsRequired = true,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"),
|
||||
Description = "Site setup costs including equipment deployment and temporary infrastructure.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Mobilization",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"),
|
||||
Description = " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Employee Welfare",
|
||||
NoOfPersonsRequired = true,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("77013784-9324-4d8b-bd36-d6f928e68942"),
|
||||
Description = "Machinery servicing, electricity, water, and temporary office needs.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Maintenance & Utilities",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"),
|
||||
Description = "Scheduled payments for external services or goods.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Vendor/Supplier Payments",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"),
|
||||
Description = "Government fees, insurance, inspections and safety-related expenditures.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Compliance & Safety",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpenseLog", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@ -2436,6 +2551,9 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("IsAdvancePayment")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Payee")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
@ -2487,6 +2605,32 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.ToTable("PaymentRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequestAttachment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("DocumentId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("PaymentRequestId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("TenantId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DocumentId");
|
||||
|
||||
b.HasIndex("PaymentRequestId");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("PaymentRequestAttachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Expenses.RecurringPayment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@ -3244,88 +3388,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("ExpensesTypeMaster");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"),
|
||||
Description = "Materials, equipment and supplies purchased for site operations.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Procurement",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"),
|
||||
Description = "Vehicle fuel, logistics services and delivery of goods or personnel.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = false,
|
||||
Name = "Transport",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"),
|
||||
Description = "Delivery of personnel.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = false,
|
||||
Name = "Travelling",
|
||||
NoOfPersonsRequired = true,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"),
|
||||
Description = "Site setup costs including equipment deployment and temporary infrastructure.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Mobilization",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"),
|
||||
Description = " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Employee Welfare",
|
||||
NoOfPersonsRequired = true,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("77013784-9324-4d8b-bd36-d6f928e68942"),
|
||||
Description = "Machinery servicing, electricity, water, and temporary office needs.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Maintenance & Utilities",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"),
|
||||
Description = "Scheduled payments for external services or goods.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Vendor/Supplier Payments",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"),
|
||||
Description = "Government fees, insurance, inspections and safety-related expenditures.",
|
||||
IsActive = true,
|
||||
IsAttachmentRequried = true,
|
||||
Name = "Compliance & Safety",
|
||||
NoOfPersonsRequired = false,
|
||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Master.Feature", b =>
|
||||
@ -6186,6 +6248,17 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpenseCategoryMaster", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpenseLog", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Expenses.Expenses", "Expense")
|
||||
@ -6369,7 +6442,7 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Master.ExpensesTypeMaster", "ExpenseCategory")
|
||||
b.HasOne("Marco.Pms.Model.Expenses.ExpenseCategoryMaster", "ExpenseCategory")
|
||||
.WithMany()
|
||||
.HasForeignKey("ExpenseCategoryId");
|
||||
|
||||
@ -6414,6 +6487,33 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.Navigation("UpdatedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequestAttachment", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document")
|
||||
.WithMany()
|
||||
.HasForeignKey("DocumentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Expenses.PaymentRequest", "PaymentRequest")
|
||||
.WithMany()
|
||||
.HasForeignKey("PaymentRequestId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Document");
|
||||
|
||||
b.Navigation("PaymentRequest");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Expenses.RecurringPayment", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy")
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace Marco.Pms.Model.Dtos.Expenses
|
||||
using Marco.Pms.Model.Utilities;
|
||||
|
||||
namespace Marco.Pms.Model.Dtos.Expenses
|
||||
{
|
||||
public class PaymentRequestDto
|
||||
{
|
||||
@ -11,5 +13,7 @@
|
||||
public required DateTime DueDate { get; set; }
|
||||
public Guid? ProjectId { get; set; }
|
||||
public required Guid ExpenseCategoryId { get; set; }
|
||||
public bool IsAdvancePayment { get; set; }
|
||||
public List<FileUploadModel>? BillAttachments { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
14
Marco.Pms.Model/Expenses/ExpenseCategoryMaster.cs
Normal file
14
Marco.Pms.Model/Expenses/ExpenseCategoryMaster.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Marco.Pms.Model.Utilities;
|
||||
|
||||
namespace Marco.Pms.Model.Expenses
|
||||
{
|
||||
public class ExpenseCategoryMaster : TenantRelation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public bool NoOfPersonsRequired { get; set; }
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsAttachmentRequried { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,7 @@ namespace Marco.Pms.Model.Expenses
|
||||
public string UIDPrefix { get; set; } = default!;
|
||||
public int UIDPostfix { get; set; }
|
||||
public string Payee { get; set; } = default!;
|
||||
public bool IsAdvancePayment { get; set; }
|
||||
public Guid CurrencyId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
@ -36,7 +37,7 @@ namespace Marco.Pms.Model.Expenses
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ExpenseCategoryId")]
|
||||
public ExpensesTypeMaster? ExpenseCategory { get; set; }
|
||||
public ExpenseCategoryMaster? ExpenseCategory { get; set; }
|
||||
public Guid ExpenseStatusId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
|
||||
22
Marco.Pms.Model/Expenses/PaymentRequestAttachment.cs
Normal file
22
Marco.Pms.Model/Expenses/PaymentRequestAttachment.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Marco.Pms.Model.DocumentManager;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.Expenses
|
||||
{
|
||||
public class PaymentRequestAttachment : TenantRelation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid PaymentRequestId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("PaymentRequestId")]
|
||||
public PaymentRequest? PaymentRequest { get; set; }
|
||||
public Guid DocumentId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("DocumentId")]
|
||||
public Document? Document { get; set; }
|
||||
}
|
||||
}
|
||||
@ -20,6 +20,7 @@ namespace Marco.Pms.Model.ViewModels.Expenses
|
||||
public RecurringPayment? RecurringPayment { get; set; }
|
||||
public ExpensesTypeMasterVM? ExpenseCategory { get; set; }
|
||||
public ExpensesStatusMasterVM? ExpenseStatus { get; set; }
|
||||
public bool IsAdvancePayment { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public BasicEmployeeVM? CreatedBy { get; set; }
|
||||
|
||||
@ -339,6 +339,7 @@ namespace Marco.Pms.Services.MappingProfiles
|
||||
opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
|
||||
);
|
||||
CreateMap<ExpensesTypeMaster, ExpensesTypeMasterVM>();
|
||||
CreateMap<ExpenseCategoryMaster, ExpensesTypeMasterVM>();
|
||||
|
||||
CreateMap<ExpensesTypeMaster, ExpensesTypeMasterMongoDB>()
|
||||
.ForMember(
|
||||
|
||||
@ -1147,6 +1147,42 @@ namespace Marco.Pms.Services.Service
|
||||
paymentRequest.CreatedById = loggedInEmployee.Id;
|
||||
paymentRequest.TenantId = tenantId;
|
||||
|
||||
_context.PaymentRequests.Add(paymentRequest);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// 4. Process Attachments
|
||||
if (model.BillAttachments?.Any() ?? false)
|
||||
{
|
||||
var attachments = model.BillAttachments;
|
||||
// Pre-validate all attachments to fail fast before any uploads.
|
||||
foreach (var attachment in attachments)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(attachment.Base64Data) || !_s3Service.IsBase64String(attachment.Base64Data))
|
||||
{
|
||||
throw new ArgumentException($"Invalid or missing Base64 data for attachment: {attachment.FileName ?? "N/A"}");
|
||||
}
|
||||
}
|
||||
|
||||
var batchId = Guid.NewGuid();
|
||||
|
||||
// Create a list of tasks to be executed concurrently.
|
||||
var processingTasks = attachments.Select(attachment =>
|
||||
ProcessSinglePaymentRequestAttachmentAsync(attachment, paymentRequest, loggedInEmployee.Id, tenantId, batchId)
|
||||
).ToList();
|
||||
|
||||
var results = await Task.WhenAll(processingTasks);
|
||||
|
||||
// This part is thread-safe as it runs after all concurrent tasks are complete.
|
||||
foreach (var (document, paymentRequestAttachment) in results)
|
||||
{
|
||||
_context.Documents.Add(document);
|
||||
_context.PaymentRequestAttachments.Add(paymentRequestAttachment);
|
||||
}
|
||||
_logger.LogInfo("{AttachmentCount} attachments processed and staged for saving.", results.Length);
|
||||
}
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var response = _mapper.Map<PaymentRequestVM>(paymentRequest);
|
||||
response.PaymentRequestUID = $"{paymentRequest.UIDPrefix}/{paymentRequest.UIDPostfix.ToString("D5")}";
|
||||
response.Currency = currency;
|
||||
@ -1304,7 +1340,6 @@ namespace Marco.Pms.Services.Service
|
||||
|
||||
return expenseList;
|
||||
}
|
||||
|
||||
private async Task<ExpenseDetailsMongoDB> GetAllExpnesRelatedTablesForSingle(Expenses model, Guid tenantId)
|
||||
{
|
||||
var statusMappingTask = Task.Run(async () =>
|
||||
@ -1386,7 +1421,6 @@ namespace Marco.Pms.Services.Service
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the filter string, handling multiple potential formats (e.g., direct JSON vs. escaped JSON string).
|
||||
/// </summary>
|
||||
@ -1449,7 +1483,7 @@ namespace Marco.Pms.Services.Service
|
||||
|
||||
// Create a list of tasks to be executed concurrently.
|
||||
var processingTasks = attachments.Select(attachment =>
|
||||
ProcessSingleAttachmentAsync(attachment, expense, employeeId, tenantId, batchId)
|
||||
ProcessSingleExpenseAttachmentAsync(attachment, expense, employeeId, tenantId, batchId)
|
||||
).ToList();
|
||||
|
||||
var results = await Task.WhenAll(processingTasks);
|
||||
@ -1466,7 +1500,7 @@ namespace Marco.Pms.Services.Service
|
||||
/// <summary>
|
||||
/// Handles the logic for a single attachment: upload to S3 and create corresponding entities.
|
||||
/// </summary>
|
||||
private async Task<(Document document, BillAttachments billAttachment)> ProcessSingleAttachmentAsync(
|
||||
private async Task<(Document document, BillAttachments billAttachment)> ProcessSingleExpenseAttachmentAsync(
|
||||
FileUploadModel attachment, Expenses expense, Guid employeeId, Guid tenantId, Guid batchId)
|
||||
{
|
||||
var base64Data = attachment.Base64Data!.Contains(',') ? attachment.Base64Data[(attachment.Base64Data.IndexOf(",") + 1)..] : attachment.Base64Data;
|
||||
@ -1478,7 +1512,7 @@ namespace Marco.Pms.Services.Service
|
||||
await _s3Service.UploadFileAsync(base64Data, fileType, objectKey);
|
||||
_logger.LogInfo("Uploaded file to S3 with key: {ObjectKey}", objectKey);
|
||||
|
||||
return CreateAttachmentEntities(batchId, expense.Id, employeeId, tenantId, objectKey, attachment);
|
||||
return CreateExpenseAttachmentEntities(batchId, expense.Id, employeeId, tenantId, objectKey, attachment);
|
||||
}
|
||||
|
||||
|
||||
@ -1486,7 +1520,7 @@ namespace Marco.Pms.Services.Service
|
||||
/// A private static helper method to create Document and BillAttachment entities.
|
||||
/// This remains unchanged as it's a pure data-shaping method.
|
||||
/// </summary>
|
||||
private static (Document document, BillAttachments billAttachment) CreateAttachmentEntities(
|
||||
private static (Document document, BillAttachments billAttachment) CreateExpenseAttachmentEntities(
|
||||
Guid batchId, Guid expenseId, Guid uploadedById, Guid tenantId, string s3Key, FileUploadModel attachmentDto)
|
||||
{
|
||||
var document = new Document
|
||||
@ -1504,6 +1538,54 @@ namespace Marco.Pms.Services.Service
|
||||
return (document, billAttachment);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the logic for a single attachment: upload to S3 and create corresponding entities.
|
||||
/// </summary>
|
||||
private async Task<(Document document, PaymentRequestAttachment billAttachment)> ProcessSinglePaymentRequestAttachmentAsync(
|
||||
FileUploadModel attachment, PaymentRequest paymentRequest, Guid employeeId, Guid tenantId, Guid batchId)
|
||||
{
|
||||
var base64Data = attachment.Base64Data!.Contains(',') ? attachment.Base64Data[(attachment.Base64Data.IndexOf(",") + 1)..] : attachment.Base64Data;
|
||||
var fileType = _s3Service.GetContentTypeFromBase64(base64Data);
|
||||
var fileName = _s3Service.GenerateFileName(fileType, paymentRequest.Id, "PaymentRequest");
|
||||
string objectKey;
|
||||
if (paymentRequest.ProjectId.HasValue)
|
||||
{
|
||||
objectKey = $"tenant-{tenantId}/project-{paymentRequest.ProjectId}/PaymentRequest/{fileName}";
|
||||
}
|
||||
else
|
||||
{
|
||||
objectKey = $"tenant-{tenantId}/PaymentRequest/{fileName}";
|
||||
}
|
||||
|
||||
// Await the I/O-bound upload operation directly.
|
||||
await _s3Service.UploadFileAsync(base64Data, fileType, objectKey);
|
||||
_logger.LogInfo("Uploaded file to S3 with key: {ObjectKey}", objectKey);
|
||||
|
||||
return CreatePaymentRequestAttachmentEntities(batchId, paymentRequest.Id, employeeId, tenantId, objectKey, attachment);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A private static helper method to create Document and BillAttachment entities.
|
||||
/// This remains unchanged as it's a pure data-shaping method.
|
||||
/// </summary>
|
||||
private static (Document document, PaymentRequestAttachment paymentRequestAttachment) CreatePaymentRequestAttachmentEntities(
|
||||
Guid batchId, Guid paymentRequestId, Guid uploadedById, Guid tenantId, string s3Key, FileUploadModel attachmentDto)
|
||||
{
|
||||
var document = new Document
|
||||
{
|
||||
BatchId = batchId,
|
||||
UploadedById = uploadedById,
|
||||
FileName = attachmentDto.FileName ?? "",
|
||||
ContentType = attachmentDto.ContentType ?? "",
|
||||
S3Key = s3Key,
|
||||
FileSize = attachmentDto.FileSize,
|
||||
UploadedAt = DateTime.UtcNow,
|
||||
TenantId = tenantId
|
||||
};
|
||||
var paymentRequestAttachment = new PaymentRequestAttachment { Document = document, PaymentRequestId = paymentRequestId, TenantId = tenantId };
|
||||
return (document, paymentRequestAttachment);
|
||||
}
|
||||
|
||||
private async Task DeleteAttachemnts(List<Guid> documentIds)
|
||||
{
|
||||
var attachmentTask = Task.Run(async () =>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user