Compare commits

..

No commits in common. "Collection_Management" and "main" have entirely different histories.

42 changed files with 265 additions and 43164 deletions

View File

@ -1,7 +1,6 @@
using Marco.Pms.Model.Activities;
using Marco.Pms.Model.AttendanceModule;
using Marco.Pms.Model.Authentication;
using Marco.Pms.Model.Collection;
using Marco.Pms.Model.Directory;
using Marco.Pms.Model.DocumentManager;
using Marco.Pms.Model.Employees;
@ -134,13 +133,6 @@ namespace Marco.Pms.DataAccess.Data
public DbSet<ProjectServiceMapping> ProjectServiceMappings { get; set; }
public DbSet<ProjectOrgMapping> ProjectOrgMappings { get; set; }
// Collection
public DbSet<Invoice> Invoices { get; set; }
public DbSet<InvoiceComment> InvoiceComments { get; set; }
public DbSet<InvoiceAttachment> InvoiceAttachments { get; set; }
public DbSet<ReceivedInvoicePayment> ReceivedInvoicePayments { get; set; }
public DbSet<PaymentAdjustmentHead> PaymentAdjustmentHeads { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@ -783,65 +775,6 @@ namespace Marco.Pms.DataAccess.Data
}
);
modelBuilder.Entity<PaymentAdjustmentHead>().HasData(
new PaymentAdjustmentHead
{
Id = Guid.Parse("dbdc047f-a2d2-4db0-b0e6-b9d9f923a0f1"),
Name = "Advance payment",
Description = "An advance payment is a sum paid before receiving goods or services, often to secure a transaction or cover initial costs.",
IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
},
new PaymentAdjustmentHead
{
Id = Guid.Parse("66c3c241-8b52-4327-a5ad-c1faf102583e"),
Name = "Base Amount",
Description = "The base amount refers to the principal sum or original value used as a reference in financial calculations, excluding taxes, fees, or additional charges.",
IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
},
new PaymentAdjustmentHead
{
Id = Guid.Parse("0d70cb2e-827e-44fc-90a5-c2c55ba51ba9"),
Name = "Tax Deducted at Source (TDS)",
Description = "TDS, or Tax Deducted at Source, is a system under the Indian Income Tax Act where tax is deducted at the point of income generation—such as salary, interest, or rent—and remitted to the government to prevent tax evasion and ensure timely collection.",
IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
},
new PaymentAdjustmentHead
{
Id = Guid.Parse("95f35acd-d979-4177-91ea-fd03a00e49ff"),
Name = "Retention",
Description = "Retention refers to a company's ability to keep customers, employees, or profits over time, commonly measured as a percentage and critical for long-term business sustainability and growth.",
IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
},
new PaymentAdjustmentHead
{
Id = Guid.Parse("3f09b19a-8d45-4cf2-be27-f4f09b38b9f7"),
Name = "Tax",
Description = "Tax is a mandatory financial charge imposed by a government on individuals or entities to fund public services and government operations, without direct benefit to the taxpayer.",
IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
},
new PaymentAdjustmentHead
{
Id = Guid.Parse("ec5e6a5f-ce62-44e5-8911-8426bbb4dde8"),
Name = "Penalty",
Description = "A penalty in the context of taxation is a financial sanction imposed by the government on individuals or entities for non-compliance with tax laws, such as late filing, underreporting income, or failure to pay taxes, and is typically calculated as a percentage of the tax due or a fixed amount.",
IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
},
new PaymentAdjustmentHead
{
Id = Guid.Parse("50584332-1cb7-4359-9721-c8ea35040881"),
Name = "Utility fees",
Description = "Utility fees are recurring charges for essential services such as electricity, water, gas, sewage, waste disposal, internet, and telecommunications, typically based on usage and necessary for operating a home or business.",
IsActive = true,
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
}
);
modelBuilder.Entity<EntityTypeMaster>().HasData(
new EntityTypeMaster
{
@ -1106,7 +1039,6 @@ namespace Marco.Pms.DataAccess.Data
// Project Module
new Feature { Id = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), Description = "Manage Project", Name = "Project Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true },
new Feature { Id = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), Description = "Expense Management is the systematic process of tracking, controlling, and reporting business-related expenditures.", Name = "Expense Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true },
new Feature { Id = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), Description = "Collection Management is a feature that enables organizations to track, organize, and manage the status and recovery of receivables or assets efficiently throughout their lifecycle, supporting systematic follow-up and resolution of outstanding accounts.", Name = "Collection Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true },
new Feature { Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), Description = "Manage Tasks", Name = "Task Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true },
// Employee Module
@ -1178,13 +1110,6 @@ namespace Marco.Pms.DataAccess.Data
new FeaturePermission { Id = new Guid("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), IsEnabled = true, Name = "Process", Description = "Allows a user to handle post-approval actions such as recording payments, updating financial records, or marking expenses as reimbursed or settled." },
new FeaturePermission { Id = new Guid("bdee29a2-b73b-402d-8dd1-c4b1f81ccbc3"), FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), IsEnabled = true, Name = "Manage", Description = "Allows a user to configure and control system settings, such as managing expense types, payment modes, permissions, and overall workflow rules." },
// Collection Management Feature
new FeaturePermission { Id = new Guid("dbf17591-09fe-4c93-9e1a-12db8f5cc5de"), FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), IsEnabled = true, Name = "Collection Admin", Description = "Collection Admin is a permission that grants a user full administrative control over collections, including creating, editing, managing access, and deleting collections within a system." },
new FeaturePermission { Id = new Guid("c8d7eea5-4033-4aad-9ebe-76de49896830"), FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), IsEnabled = true, Name = "View Collection", Description = "View Collection is a permission that allows users to see and browse assets or items within a collection without making any modifications or edits to its contents." },
new FeaturePermission { Id = new Guid("b93141fd-dbd3-4051-8f57-bf25d18e3555"), FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), IsEnabled = true, Name = "Create Collection", Description = "Authorizes users to create new collections for organizing related resources and managing access" },
new FeaturePermission { Id = new Guid("455187b4-fef1-41f9-b3d0-025d0b6302c3"), FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), IsEnabled = true, Name = "Edit Collection", Description = "Ability to modify collection properties, content, and access rights." },
new FeaturePermission { Id = new Guid("061d9ccd-85b4-4cb0-be06-2f9f32cebb72"), FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), IsEnabled = true, Name = "Add Payment", Description = " Enables entry and processing of payment transactions." },
// Organization Management Feature
new FeaturePermission { Id = new Guid("068cb3c1-49c5-4746-9f29-1fce16e820ac"), FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), IsEnabled = true, Name = "Add Organization", Description = "Allow user to create new organization" },
new FeaturePermission { Id = new Guid("c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a"), FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), IsEnabled = true, Name = "Edit Organization", Description = "Allow the user to update the basic information of the organization" },

File diff suppressed because one or more lines are too long

View File

@ -1,256 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class Added_Collection_Related_Tables : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Invoices",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Title = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
InvoiceNumber = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ProjectId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
InvoiceDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
ClientSubmitedDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
ExceptedPaymentDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
Amount = table.Column<double>(type: "double", nullable: false),
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatedById = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
UpdatedById = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_Invoices", x => x.Id);
table.ForeignKey(
name: "FK_Invoices_Employees_CreatedById",
column: x => x.CreatedById,
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Invoices_Employees_UpdatedById",
column: x => x.UpdatedById,
principalTable: "Employees",
principalColumn: "Id");
table.ForeignKey(
name: "FK_Invoices_Projects_ProjectId",
column: x => x.ProjectId,
principalTable: "Projects",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Invoices_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "InvoiceAttachments",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
InvoiceId = 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_InvoiceAttachments", x => x.Id);
table.ForeignKey(
name: "FK_InvoiceAttachments_Documents_DocumentId",
column: x => x.DocumentId,
principalTable: "Documents",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InvoiceAttachments_Invoices_InvoiceId",
column: x => x.InvoiceId,
principalTable: "Invoices",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InvoiceAttachments_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "InvoiceComments",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Comment = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatedById = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
InvoiceId = 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_InvoiceComments", x => x.Id);
table.ForeignKey(
name: "FK_InvoiceComments_Employees_CreatedById",
column: x => x.CreatedById,
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InvoiceComments_Invoices_InvoiceId",
column: x => x.InvoiceId,
principalTable: "Invoices",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InvoiceComments_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "ReceivedInvoicePayments",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
InvoiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
PaymentReceivedDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
TransactionId = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Amount = table.Column<double>(type: "double", nullable: false),
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatedById = 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_ReceivedInvoicePayments", x => x.Id);
table.ForeignKey(
name: "FK_ReceivedInvoicePayments_Employees_CreatedById",
column: x => x.CreatedById,
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ReceivedInvoicePayments_Invoices_InvoiceId",
column: x => x.InvoiceId,
principalTable: "Invoices",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ReceivedInvoicePayments_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_InvoiceAttachments_DocumentId",
table: "InvoiceAttachments",
column: "DocumentId");
migrationBuilder.CreateIndex(
name: "IX_InvoiceAttachments_InvoiceId",
table: "InvoiceAttachments",
column: "InvoiceId");
migrationBuilder.CreateIndex(
name: "IX_InvoiceAttachments_TenantId",
table: "InvoiceAttachments",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_InvoiceComments_CreatedById",
table: "InvoiceComments",
column: "CreatedById");
migrationBuilder.CreateIndex(
name: "IX_InvoiceComments_InvoiceId",
table: "InvoiceComments",
column: "InvoiceId");
migrationBuilder.CreateIndex(
name: "IX_InvoiceComments_TenantId",
table: "InvoiceComments",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_Invoices_CreatedById",
table: "Invoices",
column: "CreatedById");
migrationBuilder.CreateIndex(
name: "IX_Invoices_ProjectId",
table: "Invoices",
column: "ProjectId");
migrationBuilder.CreateIndex(
name: "IX_Invoices_TenantId",
table: "Invoices",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_Invoices_UpdatedById",
table: "Invoices",
column: "UpdatedById");
migrationBuilder.CreateIndex(
name: "IX_ReceivedInvoicePayments_CreatedById",
table: "ReceivedInvoicePayments",
column: "CreatedById");
migrationBuilder.CreateIndex(
name: "IX_ReceivedInvoicePayments_InvoiceId",
table: "ReceivedInvoicePayments",
column: "InvoiceId");
migrationBuilder.CreateIndex(
name: "IX_ReceivedInvoicePayments_TenantId",
table: "ReceivedInvoicePayments",
column: "TenantId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "InvoiceAttachments");
migrationBuilder.DropTable(
name: "InvoiceComments");
migrationBuilder.DropTable(
name: "ReceivedInvoicePayments");
migrationBuilder.DropTable(
name: "Invoices");
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,61 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class Added_EInvoiceNumber_In_Invoice_Table : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "Amount",
table: "Invoices",
newName: "TaxAmount");
migrationBuilder.AddColumn<double>(
name: "BasicAmount",
table: "Invoices",
type: "double",
nullable: false,
defaultValue: 0.0);
migrationBuilder.AddColumn<string>(
name: "EInvoiceNumber",
table: "Invoices",
type: "longtext",
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<bool>(
name: "MarkAsCompleted",
table: "Invoices",
type: "tinyint(1)",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "BasicAmount",
table: "Invoices");
migrationBuilder.DropColumn(
name: "EInvoiceNumber",
table: "Invoices");
migrationBuilder.DropColumn(
name: "MarkAsCompleted",
table: "Invoices");
migrationBuilder.RenameColumn(
name: "TaxAmount",
table: "Invoices",
newName: "Amount");
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,29 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class Added_Comment_In_ReceivedInvoicePayment_Table : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Comment",
table: "ReceivedInvoicePayments",
type: "longtext",
nullable: false)
.Annotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Comment",
table: "ReceivedInvoicePayments");
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,67 +0,0 @@
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_PaymentAdjustmentHead_Master_Table : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "PaymentAdjustmentHeads",
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"),
Description = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IsActive = 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_PaymentAdjustmentHeads", x => x.Id);
table.ForeignKey(
name: "FK_PaymentAdjustmentHeads_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.InsertData(
table: "PaymentAdjustmentHeads",
columns: new[] { "Id", "Description", "IsActive", "Name", "TenantId" },
values: new object[,]
{
{ new Guid("0d70cb2e-827e-44fc-90a5-c2c55ba51ba9"), "TDS, or Tax Deducted at Source, is a system under the Indian Income Tax Act where tax is deducted at the point of income generation—such as salary, interest, or rent—and remitted to the government to prevent tax evasion and ensure timely collection.", true, "Tax Deducted at Source (TDS)", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("3f09b19a-8d45-4cf2-be27-f4f09b38b9f7"), "Tax is a mandatory financial charge imposed by a government on individuals or entities to fund public services and government operations, without direct benefit to the taxpayer.", true, "Tax", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("50584332-1cb7-4359-9721-c8ea35040881"), "Utility fees are recurring charges for essential services such as electricity, water, gas, sewage, waste disposal, internet, and telecommunications, typically based on usage and necessary for operating a home or business.", true, "Utility fees", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("66c3c241-8b52-4327-a5ad-c1faf102583e"), "The base amount refers to the principal sum or original value used as a reference in financial calculations, excluding taxes, fees, or additional charges.", true, "Base Amount", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("95f35acd-d979-4177-91ea-fd03a00e49ff"), "Retention refers to a company's ability to keep customers, employees, or profits over time, commonly measured as a percentage and critical for long-term business sustainability and growth.", true, "Retention", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("dbdc047f-a2d2-4db0-b0e6-b9d9f923a0f1"), "An advance payment is a sum paid before receiving goods or services, often to secure a transaction or cover initial costs.", true, "Advance payment", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") },
{ new Guid("ec5e6a5f-ce62-44e5-8911-8426bbb4dde8"), "A penalty in the context of taxation is a financial sanction imposed by the government on individuals or entities for non-compliance with tax laws, such as late filing, underreporting income, or failure to pay taxes, and is typically calculated as a percentage of the tax due or a fixed amount.", true, "Penalty", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }
});
migrationBuilder.CreateIndex(
name: "IX_PaymentAdjustmentHeads_TenantId",
table: "PaymentAdjustmentHeads",
column: "TenantId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "PaymentAdjustmentHeads");
}
}
}

View File

@ -1,51 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class Added_PaymentAdjustmentHead_ForignKey_In_ReceivedInvoicePayment_Table : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "PaymentAdjustmentHeadId",
table: "ReceivedInvoicePayments",
type: "char(36)",
nullable: false,
defaultValue: new Guid("66c3c241-8b52-4327-a5ad-c1faf102583e"),
collation: "ascii_general_ci");
migrationBuilder.CreateIndex(
name: "IX_ReceivedInvoicePayments_PaymentAdjustmentHeadId",
table: "ReceivedInvoicePayments",
column: "PaymentAdjustmentHeadId");
migrationBuilder.AddForeignKey(
name: "FK_ReceivedInvoicePayments_PaymentAdjustmentHeads_PaymentAdjust~",
table: "ReceivedInvoicePayments",
column: "PaymentAdjustmentHeadId",
principalTable: "PaymentAdjustmentHeads",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_ReceivedInvoicePayments_PaymentAdjustmentHeads_PaymentAdjust~",
table: "ReceivedInvoicePayments");
migrationBuilder.DropIndex(
name: "IX_ReceivedInvoicePayments_PaymentAdjustmentHeadId",
table: "ReceivedInvoicePayments");
migrationBuilder.DropColumn(
name: "PaymentAdjustmentHeadId",
table: "ReceivedInvoicePayments");
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,68 +0,0 @@
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_Collection_Related_Permissions : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.InsertData(
table: "Features",
columns: new[] { "Id", "Description", "IsActive", "ModuleId", "Name" },
values: new object[] { new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), "Collection Management is a feature that enables organizations to track, organize, and manage the status and recovery of receivables or assets efficiently throughout their lifecycle, supporting systematic follow-up and resolution of outstanding accounts.", true, new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), "Collection Management" });
migrationBuilder.InsertData(
table: "FeaturePermissions",
columns: new[] { "Id", "Description", "FeatureId", "IsEnabled", "Name" },
values: new object[,]
{
{ new Guid("061d9ccd-85b4-4cb0-be06-2f9f32cebb72"), " Enables entry and processing of payment transactions.", new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), true, "Add Payment" },
{ new Guid("455187b4-fef1-41f9-b3d0-025d0b6302c3"), "Ability to modify collection properties, content, and access rights.", new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), true, "Edit Collection" },
{ new Guid("b93141fd-dbd3-4051-8f57-bf25d18e3555"), "Authorizes users to create new collections for organizing related resources and managing access", new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), true, "Create Collection" },
{ new Guid("c8d7eea5-4033-4aad-9ebe-76de49896830"), "View Collection is a permission that allows users to see and browse assets or items within a collection without making any modifications or edits to its contents.", new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), true, "View Collection" },
{ new Guid("dbf17591-09fe-4c93-9e1a-12db8f5cc5de"), "Collection Admin is a permission that grants a user full administrative control over collections, including creating, editing, managing access, and deleting collections within a system.", new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), true, "Collection Admin" }
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "FeaturePermissions",
keyColumn: "Id",
keyValue: new Guid("061d9ccd-85b4-4cb0-be06-2f9f32cebb72"));
migrationBuilder.DeleteData(
table: "FeaturePermissions",
keyColumn: "Id",
keyValue: new Guid("455187b4-fef1-41f9-b3d0-025d0b6302c3"));
migrationBuilder.DeleteData(
table: "FeaturePermissions",
keyColumn: "Id",
keyValue: new Guid("b93141fd-dbd3-4051-8f57-bf25d18e3555"));
migrationBuilder.DeleteData(
table: "FeaturePermissions",
keyColumn: "Id",
keyValue: new Guid("c8d7eea5-4033-4aad-9ebe-76de49896830"));
migrationBuilder.DeleteData(
table: "FeaturePermissions",
keyColumn: "Id",
keyValue: new Guid("dbf17591-09fe-4c93-9e1a-12db8f5cc5de"));
migrationBuilder.DeleteData(
table: "Features",
keyColumn: "Id",
keyValue: new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"));
}
}
}

View File

@ -369,273 +369,6 @@ namespace Marco.Pms.DataAccess.Migrations
b.ToTable("RefreshTokens");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.Invoice", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<double>("BasicAmount")
.HasColumnType("double");
b.Property<DateTime>("ClientSubmitedDate")
.HasColumnType("datetime(6)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid>("CreatedById")
.HasColumnType("char(36)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("EInvoiceNumber")
.HasColumnType("longtext");
b.Property<DateTime>("ExceptedPaymentDate")
.HasColumnType("datetime(6)");
b.Property<DateTime>("InvoiceDate")
.HasColumnType("datetime(6)");
b.Property<string>("InvoiceNumber")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<bool>("MarkAsCompleted")
.HasColumnType("tinyint(1)");
b.Property<Guid>("ProjectId")
.HasColumnType("char(36)");
b.Property<double>("TaxAmount")
.HasColumnType("double");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid?>("UpdatedById")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("CreatedById");
b.HasIndex("ProjectId");
b.HasIndex("TenantId");
b.HasIndex("UpdatedById");
b.ToTable("Invoices");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.InvoiceAttachment", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("DocumentId")
.HasColumnType("char(36)");
b.Property<Guid>("InvoiceId")
.HasColumnType("char(36)");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("DocumentId");
b.HasIndex("InvoiceId");
b.HasIndex("TenantId");
b.ToTable("InvoiceAttachments");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.InvoiceComment", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Comment")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid>("CreatedById")
.HasColumnType("char(36)");
b.Property<Guid>("InvoiceId")
.HasColumnType("char(36)");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("CreatedById");
b.HasIndex("InvoiceId");
b.HasIndex("TenantId");
b.ToTable("InvoiceComments");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.PaymentAdjustmentHead", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("PaymentAdjustmentHeads");
b.HasData(
new
{
Id = new Guid("dbdc047f-a2d2-4db0-b0e6-b9d9f923a0f1"),
Description = "An advance payment is a sum paid before receiving goods or services, often to secure a transaction or cover initial costs.",
IsActive = true,
Name = "Advance payment",
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
},
new
{
Id = new Guid("66c3c241-8b52-4327-a5ad-c1faf102583e"),
Description = "The base amount refers to the principal sum or original value used as a reference in financial calculations, excluding taxes, fees, or additional charges.",
IsActive = true,
Name = "Base Amount",
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
},
new
{
Id = new Guid("0d70cb2e-827e-44fc-90a5-c2c55ba51ba9"),
Description = "TDS, or Tax Deducted at Source, is a system under the Indian Income Tax Act where tax is deducted at the point of income generation—such as salary, interest, or rent—and remitted to the government to prevent tax evasion and ensure timely collection.",
IsActive = true,
Name = "Tax Deducted at Source (TDS)",
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
},
new
{
Id = new Guid("95f35acd-d979-4177-91ea-fd03a00e49ff"),
Description = "Retention refers to a company's ability to keep customers, employees, or profits over time, commonly measured as a percentage and critical for long-term business sustainability and growth.",
IsActive = true,
Name = "Retention",
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
},
new
{
Id = new Guid("3f09b19a-8d45-4cf2-be27-f4f09b38b9f7"),
Description = "Tax is a mandatory financial charge imposed by a government on individuals or entities to fund public services and government operations, without direct benefit to the taxpayer.",
IsActive = true,
Name = "Tax",
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
},
new
{
Id = new Guid("ec5e6a5f-ce62-44e5-8911-8426bbb4dde8"),
Description = "A penalty in the context of taxation is a financial sanction imposed by the government on individuals or entities for non-compliance with tax laws, such as late filing, underreporting income, or failure to pay taxes, and is typically calculated as a percentage of the tax due or a fixed amount.",
IsActive = true,
Name = "Penalty",
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
},
new
{
Id = new Guid("50584332-1cb7-4359-9721-c8ea35040881"),
Description = "Utility fees are recurring charges for essential services such as electricity, water, gas, sewage, waste disposal, internet, and telecommunications, typically based on usage and necessary for operating a home or business.",
IsActive = true,
Name = "Utility fees",
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
});
});
modelBuilder.Entity("Marco.Pms.Model.Collection.ReceivedInvoicePayment", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<double>("Amount")
.HasColumnType("double");
b.Property<string>("Comment")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid>("CreatedById")
.HasColumnType("char(36)");
b.Property<Guid>("InvoiceId")
.HasColumnType("char(36)");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<Guid>("PaymentAdjustmentHeadId")
.HasColumnType("char(36)");
b.Property<DateTime>("PaymentReceivedDate")
.HasColumnType("datetime(6)");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.Property<string>("TransactionId")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("CreatedById");
b.HasIndex("InvoiceId");
b.HasIndex("PaymentAdjustmentHeadId");
b.HasIndex("TenantId");
b.ToTable("ReceivedInvoicePayments");
});
modelBuilder.Entity("Marco.Pms.Model.Directory.Bucket", b =>
{
b.Property<Guid>("Id")
@ -1955,46 +1688,6 @@ namespace Marco.Pms.DataAccess.Migrations
Name = "Manage"
},
new
{
Id = new Guid("dbf17591-09fe-4c93-9e1a-12db8f5cc5de"),
Description = "Collection Admin is a permission that grants a user full administrative control over collections, including creating, editing, managing access, and deleting collections within a system.",
FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"),
IsEnabled = true,
Name = "Collection Admin"
},
new
{
Id = new Guid("c8d7eea5-4033-4aad-9ebe-76de49896830"),
Description = "View Collection is a permission that allows users to see and browse assets or items within a collection without making any modifications or edits to its contents.",
FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"),
IsEnabled = true,
Name = "View Collection"
},
new
{
Id = new Guid("b93141fd-dbd3-4051-8f57-bf25d18e3555"),
Description = "Authorizes users to create new collections for organizing related resources and managing access",
FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"),
IsEnabled = true,
Name = "Create Collection"
},
new
{
Id = new Guid("455187b4-fef1-41f9-b3d0-025d0b6302c3"),
Description = "Ability to modify collection properties, content, and access rights.",
FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"),
IsEnabled = true,
Name = "Edit Collection"
},
new
{
Id = new Guid("061d9ccd-85b4-4cb0-be06-2f9f32cebb72"),
Description = " Enables entry and processing of payment transactions.",
FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"),
IsEnabled = true,
Name = "Add Payment"
},
new
{
Id = new Guid("068cb3c1-49c5-4746-9f29-1fce16e820ac"),
Description = "Allow user to create new organization",
@ -3136,14 +2829,6 @@ namespace Marco.Pms.DataAccess.Migrations
Name = "Expense Management"
},
new
{
Id = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"),
Description = "Collection Management is a feature that enables organizations to track, organize, and manage the status and recovery of receivables or assets efficiently throughout their lifecycle, supporting systematic follow-up and resolution of outstanding accounts.",
IsActive = true,
ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"),
Name = "Collection Management"
},
new
{
Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"),
Description = "Manage Tasks",
@ -5109,139 +4794,6 @@ namespace Marco.Pms.DataAccess.Migrations
b.Navigation("User");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.Invoice", b =>
{
b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy")
.WithMany()
.HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.Projects.Project", "Project")
.WithMany()
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy")
.WithMany()
.HasForeignKey("UpdatedById");
b.Navigation("CreatedBy");
b.Navigation("Project");
b.Navigation("Tenant");
b.Navigation("UpdatedBy");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.InvoiceAttachment", b =>
{
b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document")
.WithMany()
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.Collection.Invoice", "Invoice")
.WithMany()
.HasForeignKey("InvoiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Document");
b.Navigation("Invoice");
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.InvoiceComment", b =>
{
b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy")
.WithMany()
.HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.Collection.Invoice", "Invoice")
.WithMany()
.HasForeignKey("InvoiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreatedBy");
b.Navigation("Invoice");
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.PaymentAdjustmentHead", b =>
{
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.Collection.ReceivedInvoicePayment", b =>
{
b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy")
.WithMany()
.HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.Collection.Invoice", "Invoice")
.WithMany()
.HasForeignKey("InvoiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.Collection.PaymentAdjustmentHead", "PaymentAdjustmentHead")
.WithMany()
.HasForeignKey("PaymentAdjustmentHeadId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreatedBy");
b.Navigation("Invoice");
b.Navigation("PaymentAdjustmentHead");
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.Directory.Bucket", b =>
{
b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy")

View File

@ -1,41 +0,0 @@
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.Collection
{
public class Invoice : TenantRelation
{
public Guid Id { get; set; }
public string Title { get; set; } = default!;
public string Description { get; set; } = default!;
public string InvoiceNumber { get; set; } = default!;
public string? EInvoiceNumber { get; set; }
public Guid ProjectId { get; set; }
[ValidateNever]
[ForeignKey("ProjectId")]
public Project? Project { get; set; }
public DateTime InvoiceDate { get; set; }
public DateTime ClientSubmitedDate { get; set; }
public DateTime ExceptedPaymentDate { get; set; }
public double BasicAmount { get; set; }
public double TaxAmount { get; set; }
public bool IsActive { get; set; } = true;
public bool MarkAsCompleted { get; set; } = true;
public DateTime CreatedAt { get; set; }
public Guid CreatedById { get; set; }
[ValidateNever]
[ForeignKey("CreatedById")]
public Employee? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public Guid? UpdatedById { get; set; }
[ValidateNever]
[ForeignKey("UpdatedById")]
public Employee? UpdatedBy { get; set; }
}
}

View File

@ -1,22 +0,0 @@
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.Collection
{
public class InvoiceAttachment : TenantRelation
{
public Guid Id { get; set; }
public Guid InvoiceId { get; set; }
[ValidateNever]
[ForeignKey("InvoiceId")]
public Invoice? Invoice { get; set; }
public Guid DocumentId { get; set; }
[ValidateNever]
[ForeignKey("DocumentId")]
public Document? Document { get; set; }
}
}

View File

@ -1,24 +0,0 @@
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.Collection
{
public class InvoiceComment : TenantRelation
{
public Guid Id { get; set; }
public string Comment { get; set; } = default!;
public DateTime CreatedAt { get; set; }
public Guid CreatedById { get; set; }
[ValidateNever]
[ForeignKey("CreatedById")]
public Employee? CreatedBy { get; set; }
public Guid InvoiceId { get; set; }
[ValidateNever]
[ForeignKey("InvoiceId")]
public Invoice? Invoice { get; set; }
}
}

View File

@ -1,12 +0,0 @@
using Marco.Pms.Model.Utilities;
namespace Marco.Pms.Model.Collection
{
public class PaymentAdjustmentHead : TenantRelation
{
public Guid Id { get; set; }
public string Name { get; set; } = default!;
public string? Description { get; set; }
public bool IsActive { get; set; } = true;
}
}

View File

@ -1,33 +0,0 @@
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.Collection
{
public class ReceivedInvoicePayment : TenantRelation
{
public Guid Id { get; set; }
public Guid InvoiceId { get; set; }
[ValidateNever]
[ForeignKey("InvoiceId")]
public Invoice? Invoice { get; set; }
public DateTime PaymentReceivedDate { get; set; }
public string TransactionId { get; set; } = default!;
public double Amount { get; set; }
public string Comment { get; set; } = default!;
public bool IsActive { get; set; } = true;
public Guid PaymentAdjustmentHeadId { get; set; }
[ValidateNever]
[ForeignKey("PaymentAdjustmentHeadId")]
public PaymentAdjustmentHead? PaymentAdjustmentHead { get; set; }
public DateTime CreatedAt { get; set; }
public Guid CreatedById { get; set; }
[ValidateNever]
[ForeignKey("CreatedById")]
public Employee? CreatedBy { get; set; }
}
}

View File

@ -1,8 +0,0 @@
namespace Marco.Pms.Model.Dtos.Collection
{
public class InvoiceCommentDto
{
public required string Comment { get; set; }
public required Guid InvoiceId { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using Marco.Pms.Model.Utilities;
namespace Marco.Pms.Model.Dtos.Collection
{
public class InvoiceDto
{
public Guid? Id { get; set; }
public required string Title { get; set; }
public string? Description { get; set; }
public required string InvoiceNumber { get; set; }
public string? EInvoiceNumber { get; set; }
public required Guid ProjectId { get; set; }
public required DateTime InvoiceDate { get; set; }
public required DateTime ClientSubmitedDate { get; set; }
public required DateTime ExceptedPaymentDate { get; set; }
public double BasicAmount { get; set; }
public double TaxAmount { get; set; }
public List<FileUploadModel>? Attachments { get; set; }
}
}

View File

@ -1,9 +0,0 @@
namespace Marco.Pms.Model.Dtos.Collection
{
public class PaymentAdjustmentHeadDto
{
public Guid? Id { get; set; }
public required string Name { get; set; }
public string? Description { get; set; }
}
}

View File

@ -1,13 +0,0 @@
namespace Marco.Pms.Model.Dtos.Collection
{
public class ReceivedInvoicePaymentDto
{
public Guid? Id { get; set; }
public required Guid InvoiceId { get; set; }
public required DateTime PaymentReceivedDate { get; set; }
public required string TransactionId { get; set; }
public required Guid PaymentAdjustmentHeadId { get; set; }
public required double Amount { get; set; }
public required string Comment { get; set; }
}
}

View File

@ -47,12 +47,6 @@
public static readonly Guid DownloadDocument = Guid.Parse("404373d0-860f-490e-a575-1c086ffbce1d");
public static readonly Guid VerifyDocument = Guid.Parse("13a1f30f-38d1-41bf-8e7a-b75189aab8e0");
public static readonly Guid CollectionAdmin = Guid.Parse("dbf17591-09fe-4c93-9e1a-12db8f5cc5de");
public static readonly Guid ViewCollection = Guid.Parse("c8d7eea5-4033-4aad-9ebe-76de49896830");
public static readonly Guid CreateCollection = Guid.Parse("b93141fd-dbd3-4051-8f57-bf25d18e3555");
public static readonly Guid EditCollection = Guid.Parse("455187b4-fef1-41f9-b3d0-025d0b6302c3");
public static readonly Guid AddPayment = Guid.Parse("061d9ccd-85b4-4cb0-be06-2f9f32cebb72");
public static readonly Guid AddOrganization = Guid.Parse("068cb3c1-49c5-4746-9f29-1fce16e820ac");
public static readonly Guid EditOrganization = Guid.Parse("c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a");
public static readonly Guid ViewOrganization = Guid.Parse("7a6cf830-0008-4e03-b31d-0d050cb634f4");

View File

@ -1,16 +0,0 @@
using Marco.Pms.Model.ViewModels.Activities;
namespace Marco.Pms.Model.ViewModels.Collection
{
public class InvoiceAttachmentVM
{
public Guid Id { get; set; }
public Guid InvoiceId { get; set; }
public Guid DocumentId { get; set; }
public string? FileName { get; set; }
public string? ContentType { get; set; }
public string? PreSignedUrl { get; set; }
public BasicEmployeeVM? UploadedBy { get; set; }
}
}

View File

@ -1,13 +0,0 @@
using Marco.Pms.Model.ViewModels.Activities;
namespace Marco.Pms.Model.ViewModels.Collection
{
public class InvoiceCommentVM
{
public Guid Id { get; set; }
public string Comment { get; set; } = default!;
public DateTime CreatedAt { get; set; }
public BasicEmployeeVM? CreatedBy { get; set; }
public Guid InvoiceId { get; set; }
}
}

View File

@ -1,31 +0,0 @@
using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Projects;
namespace Marco.Pms.Model.ViewModels.Collection
{
public class InvoiceDetailsVM
{
public Guid Id { get; set; }
public string Title { get; set; } = default!;
public string Description { get; set; } = default!;
public string InvoiceNumber { get; set; } = default!;
public string? EInvoiceNumber { get; set; }
public BasicProjectVM? Project { get; set; }
public DateTime InvoiceDate { get; set; }
public DateTime ClientSubmitedDate { get; set; }
public DateTime ExceptedPaymentDate { get; set; }
public double BasicAmount { get; set; }
public double TaxAmount { get; set; }
public double BalanceAmount { get; set; }
public bool IsActive { get; set; } = true;
public bool MarkAsCompleted { get; set; } = true;
public DateTime CreatedAt { get; set; }
public BasicEmployeeVM? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public BasicEmployeeVM? UpdatedBy { get; set; }
public List<InvoiceAttachmentVM>? Attachments { get; set; }
public List<ReceivedInvoicePaymentVM>? ReceivedInvoicePayments { get; set; }
public List<InvoiceCommentVM>? Comments { get; set; }
}
}

View File

@ -1,27 +0,0 @@
using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Projects;
namespace Marco.Pms.Model.ViewModels.Collection
{
public class InvoiceListVM
{
public Guid Id { get; set; }
public string Title { get; set; } = default!;
public string Description { get; set; } = default!;
public string InvoiceNumber { get; set; } = default!;
public string? EInvoiceNumber { get; set; }
public BasicProjectVM? Project { get; set; }
public DateTime InvoiceDate { get; set; }
public DateTime ClientSubmitedDate { get; set; }
public DateTime ExceptedPaymentDate { get; set; }
public double BasicAmount { get; set; }
public double TaxAmount { get; set; }
public double BalanceAmount { get; set; }
public bool IsActive { get; set; }
public bool MarkAsCompleted { get; set; }
public DateTime CreatedAt { get; set; }
public BasicEmployeeVM? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public BasicEmployeeVM? UpdatedBy { get; set; }
}
}

View File

@ -1,10 +0,0 @@
namespace Marco.Pms.Model.ViewModels.Collection
{
public class PaymentAdjustmentHeadVM
{
public Guid Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public bool IsActive { get; set; } = true;
}
}

View File

@ -1,18 +0,0 @@
using Marco.Pms.Model.ViewModels.Activities;
namespace Marco.Pms.Model.ViewModels.Collection
{
public class ReceivedInvoicePaymentVM
{
public Guid Id { get; set; }
public Guid InvoiceId { get; set; }
public DateTime PaymentReceivedDate { get; set; }
public PaymentAdjustmentHeadVM? PaymentAdjustmentHead { get; set; }
public string TransactionId { get; set; } = default!;
public double Amount { get; set; }
public string? Comment { get; set; }
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; }
public BasicEmployeeVM? CreatedBy { get; set; }
}
}

View File

@ -577,6 +577,7 @@ namespace Marco.Pms.Services.Controllers
{
new MasterMenuVM { Id = 3, Name = "Work Category" },
new MasterMenuVM { Id = 8, Name = "Services" }
//new MasterMenuVM { Id = 10, Name = "Payment Mode" }
}
},
{
@ -590,8 +591,7 @@ namespace Marco.Pms.Services.Controllers
ExpenseManagement, new List<MasterMenuVM>
{
new MasterMenuVM { Id = 6, Name = "Expense Type" },
new MasterMenuVM { Id = 7, Name = "Payment Mode" },
new MasterMenuVM { Id = 10, Name = "Payment Adjustment Head" }
new MasterMenuVM { Id = 7, Name = "Payment Mode" }
}
}
};
@ -665,46 +665,6 @@ namespace Marco.Pms.Services.Controllers
Available = true
};
response.Add(menuVM);
if (item.Submenu?.Any() == true)
{
var allowedSubmenus = new List<SubMenuItem>();
foreach (var subItem in item.Submenu)
{
if (!subItem.PermissionIds.Any())
{
MenuSectionApplicationVM subMenuVM = new MenuSectionApplicationVM
{
Id = subItem.Id,
Name = subItem.Text,
Available = true
};
response.Add(subMenuVM);
continue;
}
var subMenuPermissionIds = subItem.PermissionIds
.Select(Guid.Parse)
.ToList();
bool isSubItemAllowed = await _permissions.HasPermissionAny(subMenuPermissionIds, employeeId);
if (isSubItemAllowed)
{
MenuSectionApplicationVM subMenuVM = new MenuSectionApplicationVM
{
Id = subItem.Id,
Name = subItem.Text,
Available = true
};
response.Add(subMenuVM);
}
}
// Replace with filtered submenus
item.Submenu = allowedSubmenus;
}
}
else
{

View File

@ -321,6 +321,7 @@ namespace MarcoBMS.Services.Controllers
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
}
[HttpGet("project/team")]
/// <summary>
/// Retrieves employee attendance records for a specified project and date.
/// The result is filtered based on the logged-in employee's permissions (Team or Self).
@ -330,8 +331,6 @@ namespace MarcoBMS.Services.Controllers
/// <param name="includeInactive">Optional. Includes inactive employees in the team list if true.</param>
/// <param name="date">Optional. The date for which to fetch attendance, in "yyyy-MM-dd" format. Defaults to the current UTC date.</param>
/// <returns>An IActionResult containing a list of employee attendance records or an error response.</returns>
[HttpGet("project/team")]
public async Task<IActionResult> EmployeeAttendanceByProjectAsync([FromQuery] Guid projectId, [FromQuery] Guid? organizationId, [FromQuery] bool includeInactive, [FromQuery] string? date = null)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
@ -391,6 +390,7 @@ namespace MarcoBMS.Services.Controllers
}
}
[HttpGet("regularize")]
public async Task<IActionResult> GetRequestRegularizeAttendance([FromQuery] Guid projectId, [FromQuery] Guid? organizationId, [FromQuery] bool IncludeInActive)
{
@ -456,7 +456,8 @@ namespace MarcoBMS.Services.Controllers
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
}
[HttpPost("record")]
[HttpPost]
[Route("record")]
public async Task<IActionResult> RecordAttendance([FromBody] RecordAttendanceDot recordAttendanceDot)
{
if (!ModelState.IsValid)
@ -611,8 +612,7 @@ namespace MarcoBMS.Services.Controllers
LastName = employee.LastName,
Id = attendance.Id,
Activity = attendance.Activity,
JobRoleName = employee.JobRole.Name,
OrganizationName = employee.Organization?.Name
JobRoleName = employee.JobRole.Name
};
var sendActivity = 0;
if (recordAttendanceDot.Id == Guid.Empty)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Dtos.Activities;
using Marco.Pms.Model.Dtos.Collection;
using Marco.Pms.Model.Dtos.DocumentManager;
using Marco.Pms.Model.Dtos.Master;
using Marco.Pms.Model.Forum;
@ -976,38 +975,5 @@ namespace Marco.Pms.Services.Controllers
}
#endregion
#region =================================================================== Payment Adjustment Head APIs ===================================================================
[HttpGet("payment-adjustment-head/list")]
public async Task<IActionResult> GetpaymentAdjustmentHeadsList([FromQuery] bool isActive = true)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.GetPaymentAdjustmentHeadListAsync(isActive, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpPost("payment-adjustment-head")]
public async Task<IActionResult> CreatePaymentAdjustmentHead([FromBody] PaymentAdjustmentHeadDto dto)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.CreatePaymentAdjustmentHeadAsync(dto, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpPut("payment-adjustment-head/edit/{id}")]
public async Task<IActionResult> UpdatePaymentAdjustmentHead(Guid id, [FromBody] PaymentAdjustmentHeadDto dto)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.UpdatePaymentAdjustmentHeadAsync(id, dto, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpDelete("payment-adjustment-head/delete/{id}")]
public async Task<IActionResult> DeletePaymentAdjustmentHead(Guid id, [FromQuery] bool isActive = false)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.DeletePaymentAdjustmentHeadAsync(id, isActive, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
#endregion
}
}

View File

@ -41,11 +41,11 @@ namespace MarcoBMS.Services.Controllers
#region =================================================================== Project Get APIs ===================================================================
[HttpGet("list/basic")]
public async Task<IActionResult> GetAllProjectsBasic([FromQuery] bool provideAll = false)
public async Task<IActionResult> GetAllProjectsBasic()
{
// Get the current user
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetAllProjectsBasicAsync(provideAll, tenantId, loggedInEmployee);
var response = await _projectServices.GetAllProjectsBasicAsync(tenantId, loggedInEmployee);
return StatusCode(response.StatusCode, response);
}

View File

@ -24,7 +24,7 @@ namespace MarcoBMS.Services.Helpers
public async Task<Employee> GetEmployeeByID(Guid EmployeeID)
{
return await _context.Employees.Include(e => e.JobRole).Include(e => e.Organization).FirstOrDefaultAsync(e => e.Id == EmployeeID) ?? new Employee { };
return await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.Id == EmployeeID) ?? new Employee { };
}
public async Task<Employee> GetEmployeeByApplicationUserID(string ApplicationUserID)

View File

@ -1,11 +1,9 @@
using AutoMapper;
using Marco.Pms.Model.AppMenu;
using Marco.Pms.Model.Collection;
using Marco.Pms.Model.Directory;
using Marco.Pms.Model.DocumentManager;
using Marco.Pms.Model.Dtos.Activities;
using Marco.Pms.Model.Dtos.AppMenu;
using Marco.Pms.Model.Dtos.Collection;
using Marco.Pms.Model.Dtos.Directory;
using Marco.Pms.Model.Dtos.DocumentManager;
using Marco.Pms.Model.Dtos.Employees;
@ -28,7 +26,6 @@ using Marco.Pms.Model.Projects;
using Marco.Pms.Model.TenantModels;
using Marco.Pms.Model.TenantModels.MongoDBModel;
using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Collection;
using Marco.Pms.Model.ViewModels.Directory;
using Marco.Pms.Model.ViewModels.DocumentManager;
using Marco.Pms.Model.ViewModels.Employee;
@ -258,19 +255,6 @@ namespace Marco.Pms.Services.MappingProfiles
#endregion
#region ======================================================= Collection =======================================================
CreateMap<InvoiceDto, Invoice>();
CreateMap<Invoice, InvoiceListVM>();
CreateMap<Invoice, InvoiceDetailsVM>();
CreateMap<ReceivedInvoicePaymentDto, ReceivedInvoicePayment>();
CreateMap<ReceivedInvoicePayment, ReceivedInvoicePaymentVM>();
CreateMap<InvoiceComment, InvoiceCommentVM>();
CreateMap<InvoiceAttachment, InvoiceAttachmentVM>();
#endregion
#region ======================================================= Master =======================================================
CreateMap<FeaturePermission, FeaturePermissionVM>();
@ -400,27 +384,19 @@ namespace Marco.Pms.Services.MappingProfiles
CreateMap<UpdateContactCategoryDto, ContactCategoryMaster>();
CreateMap<ContactCategoryMaster, ContactCategoryVM>();
#endregion
#region ======================================================= Contact Tag Master =======================================================
CreateMap<CreateContactTagDto, ContactTagMaster>();
CreateMap<UpdateContactTagDto, ContactTagMaster>();
CreateMap<ContactTagMaster, ContactTagVM>();
#endregion
#region ======================================================= Payment Adjustment Head Master =======================================================
CreateMap<PaymentAdjustmentHeadDto, PaymentAdjustmentHead>();
CreateMap<PaymentAdjustmentHead, PaymentAdjustmentHeadVM>();
#endregion
#region ======================================================= Expenses Status Master =======================================================
#endregion
#region ======================================================= Expenses Status Master =======================================================
#endregion
#region ======================================================= Expenses Status Master =======================================================
#endregion
#region ======================================================= Expenses Status Master =======================================================
#endregion
#region ======================================================= Expenses Status Master =======================================================
#endregion

View File

@ -1,11 +1,9 @@
using AutoMapper;
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Helpers.Utility;
using Marco.Pms.Model.Collection;
using Marco.Pms.Model.Directory;
using Marco.Pms.Model.DocumentManager;
using Marco.Pms.Model.Dtos.Activities;
using Marco.Pms.Model.Dtos.Collection;
using Marco.Pms.Model.Dtos.DocumentManager;
using Marco.Pms.Model.Dtos.Master;
using Marco.Pms.Model.Employees;
@ -14,7 +12,6 @@ using Marco.Pms.Model.Master;
using Marco.Pms.Model.MongoDBModels.Utility;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Collection;
using Marco.Pms.Model.ViewModels.DocumentManager;
using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Services.Service.ServiceInterfaces;
@ -2655,6 +2652,8 @@ namespace Marco.Pms.Services.Service
#endregion
#region =================================================================== Document Type APIs ===================================================================
public async Task<ApiResponse<object>> GetDocumentTypeMasterListAsync(Guid? documentCategoryId, Employee loggedInEmployee, Guid tenantId)
{
try
@ -2882,248 +2881,6 @@ namespace Marco.Pms.Services.Service
#endregion
#region =================================================================== Payment Adjustment Head APIs ===================================================================
/// <summary>
/// Retrieves a list of payment adjustment heads for a specific tenant with optional active status filtering.
/// </summary>
/// <param name="isActive">Filter for active/inactive payment adjustment heads</param>
/// <param name="loggedInEmployee">The employee making the request (for auditing/authorization)</param>
/// <param name="tenantId">The tenant identifier to scope the data</param>
/// <returns>An API response containing the list of payment adjustment head view models</returns>
/// <remarks>
/// This method performs database-level filtering and uses projection to minimize data transfer.
/// Consider implementing pagination for tenants with large numbers of payment adjustment heads.
/// </remarks>
public async Task<ApiResponse<object>> GetPaymentAdjustmentHeadListAsync(bool isActive, Employee loggedInEmployee, Guid tenantId)
{
try
{
// Log the request details for auditing and troubleshooting
_logger.LogInfo("Fetching payment adjustment heads for tenant {TenantId} with IsActive={IsActive}", tenantId, isActive);
var paymentAdjustmentHeads = await _context.PaymentAdjustmentHeads
.AsNoTracking() // Improve performance by disabling change tracking for read-only operations
.Where(pah => pah.TenantId == tenantId && pah.IsActive == isActive)
.Select(pah => _mapper.Map<PaymentAdjustmentHeadVM>(pah))
.ToListAsync();
_logger.LogInfo("Successfully retrieved {Count} payment adjustment heads for tenant {TenantId}", paymentAdjustmentHeads.Count, tenantId);
return ApiResponse<object>.SuccessResponse(
paymentAdjustmentHeads.OrderBy(pah => pah.Name).ToList(),
$"Payment Adjustment Heads fetched successfully. Count: {paymentAdjustmentHeads.Count}",
200);
}
catch (Exception ex)
{
// Log the full exception with context for better troubleshooting
_logger.LogError(ex, "Error occurred while fetching payment adjustment heads for tenant {TenantId}. IsActive: {IsActive}", tenantId, isActive);
return ApiResponse<object>.ErrorResponse("An error occurred", "Unable to fetch payment adjustment heads", 500);
}
}
/// <summary>
/// Creates a new payment adjustment head for the specified tenant after permission and uniqueness checks.
/// </summary>
/// <param name="model">DTO containing payment adjustment head data</param>
/// <param name="loggedInEmployee">The employee performing the action</param>
/// <param name="tenantId">The tenant identifier</param>
/// <returns>API response with status and context</returns>
public async Task<ApiResponse<object>> CreatePaymentAdjustmentHeadAsync(PaymentAdjustmentHeadDto model, Employee loggedInEmployee, Guid tenantId)
{
try
{
// Permission validation
var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasManagePermission)
{
_logger.LogWarning("Access denied for employee {EmployeeId} attempting to create payment adjustment head for tenant {TenantId}.", loggedInEmployee.Id, tenantId);
return ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to manage masters.", 403);
}
// Uniqueness check for payment adjustment head name
var nameExists = await _context.PaymentAdjustmentHeads
.AnyAsync(pah => pah.Name == model.Name && pah.TenantId == tenantId);
if (nameExists)
{
_logger.LogInfo("Duplicate payment adjustment head name '{Name}' detected for tenant {TenantId}.", model.Name, tenantId);
return ApiResponse<object>.ErrorResponse("A payment adjustment head with this name already exists.", "Name of payment adjustment head already exists.", 409);
}
// Create and persist new entity
var paymentAdjustmentHead = _mapper.Map<PaymentAdjustmentHead>(model);
paymentAdjustmentHead.IsActive = true;
paymentAdjustmentHead.TenantId = tenantId;
_context.PaymentAdjustmentHeads.Add(paymentAdjustmentHead);
await _context.SaveChangesAsync();
var response = _mapper.Map<PaymentAdjustmentHeadVM>(paymentAdjustmentHead);
_logger.LogInfo("Payment adjustment head '{Name}' created successfully by employee {EmployeeId} for tenant {TenantId}.", paymentAdjustmentHead.Name, loggedInEmployee.Id, tenantId);
return ApiResponse<object>.SuccessResponse(response, "Payment adjustment head created successfully.", 201);
}
catch (Exception ex)
{
// Log full context with exception for easier debugging
_logger.LogError(ex, "Exception while creating payment adjustment head. Employee: {EmployeeId}, Tenant: {TenantId}, Data: {@Model}", loggedInEmployee.Id, tenantId, model);
return ApiResponse<object>.ErrorResponse("An error occurred.", "Unable to create payment adjustment head at this moment.", 500);
}
}
/// <summary>
/// Updates an existing payment adjustment head for a specified tenant after performing
/// necessary validation, permission, and uniqueness checks.
/// </summary>
/// <param name="id">Unique identifier of the payment adjustment head to update</param>
/// <param name="model">DTO containing updated payment adjustment head data</param>
/// <param name="loggedInEmployee">The employee performing the action</param>
/// <param name="tenantId">The tenant identifier</param>
/// <returns>API response object with update result and status message</returns>
public async Task<ApiResponse<object>> UpdatePaymentAdjustmentHeadAsync(Guid id, PaymentAdjustmentHeadDto model, Employee loggedInEmployee, Guid tenantId)
{
try
{
// --- Step 1: Validate request payload correctness ---
if (!model.Id.HasValue || model.Id != id)
{
_logger.LogWarning("Invalid ID provided in request. Model ID: {ModelId}, Route ID: {RouteId}, TenantId: {TenantId}", model.Id ?? Guid.Empty, id, tenantId);
return ApiResponse<object>.ErrorResponse("Invalid request.", "Provided invalid ID.", 400);
}
// --- Step 2: Validate permissions ---
var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasManagePermission)
{
_logger.LogWarning("Access denied for employee {EmployeeId} attempting to update payment adjustment head for tenant {TenantId}.", loggedInEmployee.Id, tenantId);
return ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to manage masters.", 403);
}
// --- Step 3: Validate uniqueness constraint for name ---
var nameExists = await _context.PaymentAdjustmentHeads
.AnyAsync(pah => pah.Name == model.Name && pah.Id != id && pah.TenantId == tenantId);
if (nameExists)
{
_logger.LogInfo("Duplicate payment adjustment head name '{Name}' detected during update for tenant {TenantId}.", model.Name, tenantId);
return ApiResponse<object>.ErrorResponse("Conflict detected.", "A payment adjustment head with this name already exists.", 409);
}
// --- Step 4: Retrieve and validate existing entity ---
var paymentAdjustmentHead = await _context.PaymentAdjustmentHeads
.FirstOrDefaultAsync(pah => pah.Id == id && pah.TenantId == tenantId);
if (paymentAdjustmentHead == null)
{
_logger.LogWarning("Payment adjustment head with ID {Id} not found for tenant {TenantId}.", id, tenantId);
return ApiResponse<object>.ErrorResponse("Not Found.", "Payment adjustment head not found.", 404);
}
// Mapping PaymentAdjustmentHead to BsonDocument
var existingEntityBson = _updateLogHelper.EntityToBsonDocument(paymentAdjustmentHead);
// --- Step 5: Map changes and update entity ---
_mapper.Map(model, paymentAdjustmentHead);
await _context.SaveChangesAsync();
await _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
{
EntityId = paymentAdjustmentHead.Id.ToString(),
UpdatedById = loggedInEmployee.Id.ToString(),
OldObject = existingEntityBson,
UpdatedAt = DateTime.UtcNow
}, "PaymentAdjustmentHeadModificationLog");
_logger.LogInfo("Payment adjustment head '{Name}' updated successfully by employee {EmployeeId} for tenant {TenantId}.", paymentAdjustmentHead.Name, loggedInEmployee.Id, tenantId);
var response = _mapper.Map<PaymentAdjustmentHeadVM>(paymentAdjustmentHead);
// --- Step 6: Return structured success response ---
return ApiResponse<object>.SuccessResponse(response, "Payment adjustment head updated successfully.", 200);
}
catch (Exception ex)
{
// --- Step 7: Handle and log exceptions with full context ---
_logger.LogError(ex, "Exception while updating payment adjustment head. Employee: {EmployeeId}, Tenant: {TenantId}, Model: {@Model}", loggedInEmployee.Id, tenantId, model);
return ApiResponse<object>.ErrorResponse("An unexpected error occurred.", "Unable to update payment adjustment head at this moment.", 500);
}
}
/// <summary>
/// Activates or deactivates a payment adjustment head (soft delete/restore) for a tenant,
/// including audit logging and permission validation.
/// </summary>
/// <param name="id">Unique identifier of the payment adjustment head</param>
/// <param name="isActive">Flag indicating activation (restore) or deactivation (delete)</param>
/// <param name="loggedInEmployee">Employee requesting the operation</param>
/// <param name="tenantId">The tenant identifier</param>
/// <returns>API response object with operation status</returns>
public async Task<ApiResponse<object>> DeletePaymentAdjustmentHeadAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId)
{
// Dynamically select operation word for logs and messages
var operation = isActive ? "restore" : "delete";
try
{
// Step 1: Permission check
var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasManagePermission)
{
_logger.LogWarning("Access denied: Employee {EmployeeId} attempted to {Operation} payment adjustment head for tenant {TenantId}.",
loggedInEmployee.Id, operation, tenantId);
return ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to manage masters.", 403);
}
// Step 2: Entity existence check
var paymentAdjustmentHead = await _context.PaymentAdjustmentHeads
.FirstOrDefaultAsync(pah => pah.Id == id && pah.TenantId == tenantId);
if (paymentAdjustmentHead == null)
{
_logger.LogWarning("Payment adjustment head with ID {Id} not found for tenant {TenantId} (attempted {Operation}).",
id, tenantId, operation);
return ApiResponse<object>.ErrorResponse("Not Found.", "Payment adjustment head not found.", 404);
}
// Step 3: Save pre-update state for audit log
var existingEntityBson = _updateLogHelper.EntityToBsonDocument(paymentAdjustmentHead);
// Step 4: Update IsActive status
paymentAdjustmentHead.IsActive = isActive;
await _context.SaveChangesAsync();
// Step 5: Push update action to audit log
await _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
{
EntityId = paymentAdjustmentHead.Id.ToString(),
UpdatedById = loggedInEmployee.Id.ToString(),
OldObject = existingEntityBson,
UpdatedAt = DateTime.UtcNow
}, "PaymentAdjustmentHeadModificationLog");
_logger.LogInfo(
"Payment adjustment head (ID: {Id}, Name: {Name}) successfully {Operation}d by employee {EmployeeId} for tenant {TenantId}.",
paymentAdjustmentHead.Id, paymentAdjustmentHead.Name, operation, loggedInEmployee.Id, tenantId);
return ApiResponse<object>.SuccessResponse(new { }, $"Payment adjustment head {operation}d successfully.", 200);
}
catch (Exception ex)
{
_logger.LogError(ex,
"Exception occurred while performing {Operation} on payment adjustment head (ID: {Id}) for tenant {TenantId}.",
operation, id, tenantId);
return ApiResponse<object>.ErrorResponse("An error occurred.", $"Exception occurred while trying to {operation} payment adjustment head.", 500);
}
}
#endregion
#region =================================================================== Helper Function ===================================================================
private static object ExceptionMapper(Exception ex)
{

View File

@ -54,7 +54,7 @@ namespace Marco.Pms.Services.Service
#region =================================================================== Project Get APIs ===================================================================
public async Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetAllProjectsBasicAsync(Guid tenantId, Employee loggedInEmployee)
{
try
{
@ -67,15 +67,7 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("Basic project list requested by EmployeeId {EmployeeId}", loggedInEmployee.Id);
// Step 2: Get the list of project IDs the user has access to
List<Guid> accessibleProjectIds = new List<Guid>();
if (provideAll)
{
accessibleProjectIds = await _context.Projects.Where(p => p.TenantId == tenantId).Select(p => p.Id).ToListAsync();
}
else
{
accessibleProjectIds = await GetMyProjects(tenantId, loggedInEmployee);
}
List<Guid> accessibleProjectIds = await GetMyProjects(tenantId, loggedInEmployee);
if (accessibleProjectIds == null || !accessibleProjectIds.Any())
{

View File

@ -1,5 +1,4 @@
using Marco.Pms.Model.Dtos.Activities;
using Marco.Pms.Model.Dtos.Collection;
using Marco.Pms.Model.Dtos.DocumentManager;
using Marco.Pms.Model.Dtos.Master;
using Marco.Pms.Model.Employees;
@ -47,7 +46,6 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
Task<ApiResponse<object>> DeleteActivityGroupAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId);
#endregion
#region =================================================================== Contact Category APIs ===================================================================
Task<ApiResponse<object>> CreateContactCategory(CreateContactCategoryDto contactCategoryDto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> UpdateContactCategory(Guid id, UpdateContactCategoryDto contactCategoryDto, Employee loggedInEmployee, Guid tenantId);
@ -106,12 +104,5 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
Task<ApiResponse<object>> UpdateDocumentTypeMasterAsync(Guid id, CreateDocumentTypeDto model, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> DeleteDocumentTypeMasterAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId);
#endregion
#region =================================================================== Payment Adjustment Head APIs ===================================================================
Task<ApiResponse<object>> GetPaymentAdjustmentHeadListAsync(bool isActive, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreatePaymentAdjustmentHeadAsync(PaymentAdjustmentHeadDto model, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> UpdatePaymentAdjustmentHeadAsync(Guid id, PaymentAdjustmentHeadDto model, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> DeletePaymentAdjustmentHeadAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId);
#endregion
}
}

View File

@ -10,7 +10,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
{
public interface IProjectServices
{
Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetAllProjectsBasicAsync(Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetAllProjectsAsync(Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetProjectAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetProjectDetailsAsync(Guid id, Guid tenantId, Employee loggedInEmployee);