diff --git a/Backend/ERPCore/Migrations/ErpDbContextModelSnapshot.cs b/Backend/ERPCore/Infra/Persistence/Migrations/20260803105635_SyncCurrentModel.Designer.cs
similarity index 84%
rename from Backend/ERPCore/Migrations/ErpDbContextModelSnapshot.cs
rename to Backend/ERPCore/Infra/Persistence/Migrations/20260803105635_SyncCurrentModel.Designer.cs
index 67ed7ed..b574913 100644
--- a/Backend/ERPCore/Migrations/ErpDbContextModelSnapshot.cs
+++ b/Backend/ERPCore/Infra/Persistence/Migrations/20260803105635_SyncCurrentModel.Designer.cs
@@ -3,21 +3,24 @@ using System;
using ERPCore.Infra.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
-namespace ERPCore.Migrations
+namespace ERPCore.Infra.Persistence.Migrations
{
[DbContext(typeof(ErpDbContext))]
- partial class ErpDbContextModelSnapshot : ModelSnapshot
+ [Migration("20260803105635_SyncCurrentModel")]
+ partial class SyncCurrentModel
{
- protected override void BuildModel(ModelBuilder modelBuilder)
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "10.0.9")
+ .HasAnnotation("ProductVersion", "9.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@@ -1932,6 +1935,24 @@ namespace ERPCore.Migrations
Label = "Help",
SortOrder = 10,
Status = "Active"
+ },
+ new
+ {
+ NavItemId = 11,
+ Code = "ledgers",
+ Href = "/dashboard/ledgers",
+ Label = "Ledgers",
+ SortOrder = 11,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 12,
+ Code = "accounts",
+ Href = "/dashboard/accounts",
+ Label = "Accounts",
+ SortOrder = 12,
+ Status = "Active"
});
});
@@ -2385,27 +2406,99 @@ namespace ERPCore.Migrations
},
new
{
- PermissionId = 19,
+ PermissionId = 28,
Code = "NAV:procurement.requisitions",
- SubNavItemId = 9
+ SubNavItemId = 17
+ },
+ new
+ {
+ PermissionId = 29,
+ Code = "NAV:procurement.rfqs",
+ SubNavItemId = 18
+ },
+ new
+ {
+ PermissionId = 30,
+ Code = "NAV:procurement.purchase-orders",
+ SubNavItemId = 19
+ },
+ new
+ {
+ PermissionId = 31,
+ Code = "NAV:procurement.purchase-returns",
+ SubNavItemId = 20
+ },
+ new
+ {
+ PermissionId = 19,
+ Code = "NAV:ledgers",
+ NavItemId = 11
},
new
{
PermissionId = 20,
- Code = "NAV:procurement.rfqs",
- SubNavItemId = 10
+ Code = "NAV:ledgers.trial-balance",
+ SubNavItemId = 9
},
new
{
PermissionId = 21,
- Code = "NAV:procurement.purchase-orders",
- SubNavItemId = 11
+ Code = "NAV:ledgers.balance-sheet",
+ SubNavItemId = 10
},
new
{
PermissionId = 22,
- Code = "NAV:procurement.purchase-returns",
+ Code = "NAV:ledgers.general-ledger",
+ SubNavItemId = 11
+ },
+ new
+ {
+ PermissionId = 23,
+ Code = "NAV:ledgers.profit-and-loss",
SubNavItemId = 12
+ },
+ new
+ {
+ PermissionId = 24,
+ Code = "NAV:ledgers.cash-flow",
+ SubNavItemId = 13
+ },
+ new
+ {
+ PermissionId = 25,
+ Code = "NAV:ledgers.budget-vs-actual",
+ SubNavItemId = 14
+ },
+ new
+ {
+ PermissionId = 27,
+ Code = "NAV:ledgers.tax-report",
+ SubNavItemId = 16
+ },
+ new
+ {
+ PermissionId = 26,
+ Code = "NAV:accounts.bank-accounts",
+ SubNavItemId = 15
+ },
+ new
+ {
+ PermissionId = 32,
+ Code = "NAV:accounts",
+ NavItemId = 12
+ },
+ new
+ {
+ PermissionId = 33,
+ Code = "NAV:accounts.cheque-books",
+ SubNavItemId = 21
+ },
+ new
+ {
+ PermissionId = 34,
+ Code = "NAV:accounts.received-cheques",
+ SubNavItemId = 22
});
});
@@ -2458,102 +2551,6 @@ namespace ERPCore.Migrations
b.ToTable("po_lines", (string)null);
});
- modelBuilder.Entity("ERPCore.Domain.Entities.CompanyProfile", b =>
- {
- b.Property("CompanyProfileId")
- .HasColumnType("integer");
-
- b.Property("AccountName")
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("AccountNumber")
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.Property("AddressLine1")
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("AddressLine2")
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("BankBranch")
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("BankName")
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("City")
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.Property("Country")
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.Property("Email")
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("FooterNote")
- .HasMaxLength(500)
- .HasColumnType("character varying(500)");
-
- b.Property("LegalName")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("LogoUrl")
- .HasMaxLength(500)
- .HasColumnType("character varying(500)");
-
- b.Property("Phone")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("SwiftCode")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("TaxRegistrationNo")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("TradeName")
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("VatRegistrationNo")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("UpdatedBy")
- .HasColumnType("integer");
-
- b.Property("RowVersion")
- .IsConcurrencyToken()
- .ValueGeneratedOnAddOrUpdate()
- .HasColumnType("xid")
- .HasColumnName("xmin");
-
- b.HasKey("CompanyProfileId");
-
- b.HasIndex("UpdatedBy");
-
- b.ToTable("company_profile", (string)null, t =>
- {
- t.HasCheckConstraint("ck_company_profile_singleton", "\"CompanyProfileId\" = 1");
- });
- });
-
modelBuilder.Entity("ERPCore.Domain.Entities.ProductConfig", b =>
{
b.Property("ConfigId")
@@ -2596,6 +2593,136 @@ namespace ERPCore.Migrations
});
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.ProductionRun", b =>
+ {
+ b.Property("RunId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RunId"));
+
+ b.Property("CancelReasonCodeId")
+ .HasColumnType("integer");
+
+ b.Property("CompletedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedBy")
+ .HasColumnType("integer");
+
+ b.Property("DocNo")
+ .IsRequired()
+ .HasMaxLength(30)
+ .HasColumnType("character varying(30)");
+
+ b.Property("OutputBinId")
+ .HasColumnType("integer");
+
+ b.Property("ReworkCount")
+ .HasColumnType("integer");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("ScaleFactor")
+ .HasPrecision(18, 6)
+ .HasColumnType("numeric(18,6)");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("TargetQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("TemplateId")
+ .HasColumnType("integer");
+
+ b.Property("WarehouseId")
+ .HasColumnType("integer");
+
+ b.HasKey("RunId");
+
+ b.HasIndex("CancelReasonCodeId");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DocNo")
+ .IsUnique();
+
+ b.HasIndex("OutputBinId");
+
+ b.HasIndex("Status");
+
+ b.HasIndex("WarehouseId");
+
+ b.HasIndex("TemplateId", "Status");
+
+ b.ToTable("production_runs", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.ProductionTemplate", b =>
+ {
+ b.Property("TemplateId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("TemplateId"));
+
+ b.Property("Annotations")
+ .HasColumnType("jsonb");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(30)
+ .HasColumnType("character varying(30)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedBy")
+ .HasColumnType("integer");
+
+ b.Property("Description")
+ .HasMaxLength(500)
+ .HasColumnType("character varying(500)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(150)
+ .HasColumnType("character varying(150)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.HasKey("TemplateId");
+
+ b.HasIndex("Code")
+ .IsUnique();
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("Status");
+
+ b.ToTable("production_templates", (string)null);
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b =>
{
b.Property("PoId")
@@ -2965,6 +3092,261 @@ namespace ERPCore.Migrations
b.ToTable("role_permissions", (string)null);
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunEdge", b =>
+ {
+ b.Property("RunEdgeId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RunEdgeId"));
+
+ b.Property("ChildRunStageId")
+ .HasColumnType("integer");
+
+ b.Property("ParentRunStageId")
+ .HasColumnType("integer");
+
+ b.Property("RunId")
+ .HasColumnType("integer");
+
+ b.HasKey("RunEdgeId");
+
+ b.HasIndex("ChildRunStageId");
+
+ b.HasIndex("RunId");
+
+ b.HasIndex("ParentRunStageId", "ChildRunStageId")
+ .IsUnique();
+
+ b.ToTable("run_edges", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStage", b =>
+ {
+ b.Property("RunStageId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RunStageId"));
+
+ b.Property("ActualEndAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ActualStartAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EstimatedMinutes")
+ .HasColumnType("integer");
+
+ b.Property("FieldDefs")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("FieldValues")
+ .HasColumnType("jsonb");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(150)
+ .HasColumnType("character varying(150)");
+
+ b.Property("PosX")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("PosY")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("RoleLabel")
+ .HasMaxLength(60)
+ .HasColumnType("character varying(60)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("RunId")
+ .HasColumnType("integer");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("TemplateStageId")
+ .HasColumnType("integer");
+
+ b.HasKey("RunStageId");
+
+ b.HasIndex("TemplateStageId");
+
+ b.HasIndex("RunId", "Status");
+
+ b.ToTable("run_stages", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStageEvent", b =>
+ {
+ b.Property("EventId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EventId"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EventType")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("Note")
+ .HasMaxLength(500)
+ .HasColumnType("character varying(500)");
+
+ b.Property("Payload")
+ .HasColumnType("jsonb");
+
+ b.Property("RunId")
+ .HasColumnType("integer");
+
+ b.Property("RunStageId")
+ .HasColumnType("integer");
+
+ b.Property("UserId")
+ .HasColumnType("integer");
+
+ b.HasKey("EventId");
+
+ b.HasIndex("RunStageId");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("RunId", "EventId");
+
+ b.ToTable("run_stage_events", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStageInput", b =>
+ {
+ b.Property("RunInputId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RunInputId"));
+
+ b.Property("ConsumedQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ConsumedValue")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("DeliveredQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("FromRunOutputId")
+ .HasColumnType("integer");
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("PlannedQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ReturnedQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ReturnedValue")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("RunStageId")
+ .HasColumnType("integer");
+
+ b.Property("Source")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("UomId")
+ .HasColumnType("integer");
+
+ b.HasKey("RunInputId");
+
+ b.HasIndex("FromRunOutputId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("RunStageId");
+
+ b.HasIndex("UomId");
+
+ b.ToTable("run_stage_inputs", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStageOutput", b =>
+ {
+ b.Property("RunOutputId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RunOutputId"));
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(150)
+ .HasColumnType("character varying(150)");
+
+ b.Property("PlannedQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ProducedQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("RunStageId")
+ .HasColumnType("integer");
+
+ b.Property("ScrapReasonCodeId")
+ .HasColumnType("integer");
+
+ b.Property("ScrappedQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("TransferredQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("UomId")
+ .HasColumnType("integer");
+
+ b.HasKey("RunOutputId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("RunStageId");
+
+ b.HasIndex("ScrapReasonCodeId");
+
+ b.HasIndex("UomId");
+
+ b.ToTable("run_stage_outputs", (string)null);
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.SalaryComponent", b =>
{
b.Property("SalaryComponentId")
@@ -3452,6 +3834,114 @@ namespace ERPCore.Migrations
b.ToTable("serials", (string)null);
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.StageEdge", b =>
+ {
+ b.Property("EdgeId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EdgeId"));
+
+ b.Property("ChildStageId")
+ .HasColumnType("integer");
+
+ b.Property("ParentStageId")
+ .HasColumnType("integer");
+
+ b.Property("TemplateId")
+ .HasColumnType("integer");
+
+ b.HasKey("EdgeId");
+
+ b.HasIndex("ChildStageId");
+
+ b.HasIndex("TemplateId");
+
+ b.HasIndex("ParentStageId", "ChildStageId")
+ .IsUnique();
+
+ b.ToTable("stage_edges", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StageInput", b =>
+ {
+ b.Property("InputId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("InputId"));
+
+ b.Property("FromOutputId")
+ .HasColumnType("integer");
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("QtyPerBatch")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("Source")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("StageId")
+ .HasColumnType("integer");
+
+ b.Property("UomId")
+ .HasColumnType("integer");
+
+ b.HasKey("InputId");
+
+ b.HasIndex("FromOutputId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("StageId");
+
+ b.HasIndex("UomId");
+
+ b.ToTable("stage_inputs", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StageOutput", b =>
+ {
+ b.Property("OutputId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("OutputId"));
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(150)
+ .HasColumnType("character varying(150)");
+
+ b.Property("QtyPerBatch")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("StageId")
+ .HasColumnType("integer");
+
+ b.Property("UomId")
+ .HasColumnType("integer");
+
+ b.HasKey("OutputId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("StageId");
+
+ b.HasIndex("UomId");
+
+ b.ToTable("stage_outputs", (string)null);
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustment", b =>
{
b.Property("AdjustmentId")
@@ -4051,7 +4541,7 @@ namespace ERPCore.Migrations
},
new
{
- SubNavItemId = 9,
+ SubNavItemId = 17,
Code = "procurement.requisitions",
Href = "/dashboard/procurement/requisitions",
Label = "Requisitions",
@@ -4061,7 +4551,7 @@ namespace ERPCore.Migrations
},
new
{
- SubNavItemId = 10,
+ SubNavItemId = 18,
Code = "procurement.rfqs",
Href = "/dashboard/procurement/rfqs",
Label = "RFQs",
@@ -4071,7 +4561,7 @@ namespace ERPCore.Migrations
},
new
{
- SubNavItemId = 11,
+ SubNavItemId = 19,
Code = "procurement.purchase-orders",
Href = "/dashboard/procurement/purchase-orders",
Label = "Purchase Orders",
@@ -4081,13 +4571,113 @@ namespace ERPCore.Migrations
},
new
{
- SubNavItemId = 12,
+ SubNavItemId = 20,
Code = "procurement.purchase-returns",
Href = "/dashboard/procurement/purchase-returns",
Label = "Purchase Returns",
NavItemId = 4,
SortOrder = 4,
Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 9,
+ Code = "ledgers.trial-balance",
+ Href = "/dashboard/ledgers/trial-balance",
+ Label = "Trial Balance",
+ NavItemId = 11,
+ SortOrder = 1,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 10,
+ Code = "ledgers.balance-sheet",
+ Href = "/dashboard/ledgers/balance-sheet",
+ Label = "Balance Sheet",
+ NavItemId = 11,
+ SortOrder = 2,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 11,
+ Code = "ledgers.general-ledger",
+ Href = "/dashboard/ledgers/general-ledger",
+ Label = "General Ledger",
+ NavItemId = 11,
+ SortOrder = 3,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 12,
+ Code = "ledgers.profit-and-loss",
+ Href = "/dashboard/ledgers/profit-and-loss",
+ Label = "Profit & Loss",
+ NavItemId = 11,
+ SortOrder = 4,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 13,
+ Code = "ledgers.cash-flow",
+ Href = "/dashboard/ledgers/cash-flow",
+ Label = "Cash Flow",
+ NavItemId = 11,
+ SortOrder = 5,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 14,
+ Code = "ledgers.budget-vs-actual",
+ Href = "/dashboard/ledgers/budget-vs-actual",
+ Label = "Budget vs Actual",
+ NavItemId = 11,
+ SortOrder = 6,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 16,
+ Code = "ledgers.tax-report",
+ Href = "/dashboard/ledgers/tax-report",
+ Label = "Tax Report",
+ NavItemId = 11,
+ SortOrder = 7,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 15,
+ Code = "accounts.bank-accounts",
+ Href = "/dashboard/accounts/bank-accounts",
+ Label = "Cash / Bank Accounts",
+ NavItemId = 12,
+ SortOrder = 1,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 21,
+ Code = "accounts.cheque-books",
+ Href = "/dashboard/accounts/cheque-books",
+ Label = "Cheque Books",
+ NavItemId = 12,
+ SortOrder = 2,
+ Status = "Active"
+ },
+ new
+ {
+ SubNavItemId = 22,
+ Code = "accounts.received-cheques",
+ Href = "/dashboard/accounts/received-cheques",
+ Label = "Received Cheques",
+ NavItemId = 12,
+ SortOrder = 3,
+ Status = "Active"
});
});
@@ -4133,6 +4723,48 @@ namespace ERPCore.Migrations
b.ToTable("hr_tax_slabs", (string)null);
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.TemplateStage", b =>
+ {
+ b.Property("StageId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("StageId"));
+
+ b.Property("EstimatedMinutes")
+ .HasColumnType("integer");
+
+ b.Property("FieldDefs")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(150)
+ .HasColumnType("character varying(150)");
+
+ b.Property("PosX")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("PosY")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("RoleLabel")
+ .HasMaxLength(60)
+ .HasColumnType("character varying(60)");
+
+ b.Property("TemplateId")
+ .HasColumnType("integer");
+
+ b.HasKey("StageId");
+
+ b.HasIndex("TemplateId");
+
+ b.ToTable("template_stages", (string)null);
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.Uom", b =>
{
b.Property("UomId")
@@ -4998,14 +5630,56 @@ namespace ERPCore.Migrations
b.Navigation("UpdatedByUser");
});
- modelBuilder.Entity("ERPCore.Domain.Entities.CompanyProfile", b =>
+ modelBuilder.Entity("ERPCore.Domain.Entities.ProductionRun", b =>
{
- b.HasOne("ERPCore.Domain.Entities.User", "UpdatedByUser")
+ b.HasOne("ERPCore.Domain.Entities.ReasonCode", "CancelReason")
.WithMany()
- .HasForeignKey("UpdatedBy")
+ .HasForeignKey("CancelReasonCodeId")
.OnDelete(DeleteBehavior.Restrict);
- b.Navigation("UpdatedByUser");
+ b.HasOne("ERPCore.Domain.Entities.User", "Creator")
+ .WithMany()
+ .HasForeignKey("CreatedBy")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.Bin", "OutputBin")
+ .WithMany()
+ .HasForeignKey("OutputBinId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("ERPCore.Domain.Entities.ProductionTemplate", "Template")
+ .WithMany("Runs")
+ .HasForeignKey("TemplateId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
+ .WithMany()
+ .HasForeignKey("WarehouseId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("CancelReason");
+
+ b.Navigation("Creator");
+
+ b.Navigation("OutputBin");
+
+ b.Navigation("Template");
+
+ b.Navigation("Warehouse");
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.ProductionTemplate", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.User", "Creator")
+ .WithMany()
+ .HasForeignKey("CreatedBy")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Creator");
});
modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b =>
@@ -5174,6 +5848,143 @@ namespace ERPCore.Migrations
b.Navigation("Role");
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunEdge", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.RunStage", "ChildRunStage")
+ .WithMany()
+ .HasForeignKey("ChildRunStageId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.RunStage", "ParentRunStage")
+ .WithMany()
+ .HasForeignKey("ParentRunStageId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.ProductionRun", "Run")
+ .WithMany("Edges")
+ .HasForeignKey("RunId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("ChildRunStage");
+
+ b.Navigation("ParentRunStage");
+
+ b.Navigation("Run");
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStage", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.ProductionRun", "Run")
+ .WithMany("Stages")
+ .HasForeignKey("RunId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.TemplateStage", "TemplateStage")
+ .WithMany()
+ .HasForeignKey("TemplateStageId")
+ .OnDelete(DeleteBehavior.SetNull);
+
+ b.Navigation("Run");
+
+ b.Navigation("TemplateStage");
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStageEvent", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.ProductionRun", "Run")
+ .WithMany("Events")
+ .HasForeignKey("RunId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.RunStage", "RunStage")
+ .WithMany("Events")
+ .HasForeignKey("RunStageId")
+ .OnDelete(DeleteBehavior.SetNull);
+
+ b.HasOne("ERPCore.Domain.Entities.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Run");
+
+ b.Navigation("RunStage");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStageInput", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.RunStageOutput", "FromRunOutput")
+ .WithMany()
+ .HasForeignKey("FromRunOutputId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("ERPCore.Domain.Entities.Item", "Item")
+ .WithMany()
+ .HasForeignKey("ItemId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("ERPCore.Domain.Entities.RunStage", "RunStage")
+ .WithMany("Inputs")
+ .HasForeignKey("RunStageId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.Uom", "Uom")
+ .WithMany()
+ .HasForeignKey("UomId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("FromRunOutput");
+
+ b.Navigation("Item");
+
+ b.Navigation("RunStage");
+
+ b.Navigation("Uom");
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStageOutput", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.Item", "Item")
+ .WithMany()
+ .HasForeignKey("ItemId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("ERPCore.Domain.Entities.RunStage", "RunStage")
+ .WithMany("Outputs")
+ .HasForeignKey("RunStageId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.ReasonCode", "ScrapReason")
+ .WithMany()
+ .HasForeignKey("ScrapReasonCodeId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("ERPCore.Domain.Entities.Uom", "Uom")
+ .WithMany()
+ .HasForeignKey("UomId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Item");
+
+ b.Navigation("RunStage");
+
+ b.Navigation("ScrapReason");
+
+ b.Navigation("Uom");
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoice", b =>
{
b.HasOne("ERPCore.Domain.Entities.User", "Creator")
@@ -5307,6 +6118,92 @@ namespace ERPCore.Migrations
b.Navigation("Item");
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.StageEdge", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.TemplateStage", "ChildStage")
+ .WithMany()
+ .HasForeignKey("ChildStageId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.TemplateStage", "ParentStage")
+ .WithMany()
+ .HasForeignKey("ParentStageId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.ProductionTemplate", "Template")
+ .WithMany("Edges")
+ .HasForeignKey("TemplateId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("ChildStage");
+
+ b.Navigation("ParentStage");
+
+ b.Navigation("Template");
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StageInput", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.StageOutput", "FromOutput")
+ .WithMany()
+ .HasForeignKey("FromOutputId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("ERPCore.Domain.Entities.Item", "Item")
+ .WithMany()
+ .HasForeignKey("ItemId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("ERPCore.Domain.Entities.TemplateStage", "Stage")
+ .WithMany("Inputs")
+ .HasForeignKey("StageId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.Uom", "Uom")
+ .WithMany()
+ .HasForeignKey("UomId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("FromOutput");
+
+ b.Navigation("Item");
+
+ b.Navigation("Stage");
+
+ b.Navigation("Uom");
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StageOutput", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.Item", "Item")
+ .WithMany()
+ .HasForeignKey("ItemId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.HasOne("ERPCore.Domain.Entities.TemplateStage", "Stage")
+ .WithMany("Outputs")
+ .HasForeignKey("StageId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ERPCore.Domain.Entities.Uom", "Uom")
+ .WithMany()
+ .HasForeignKey("UomId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Item");
+
+ b.Navigation("Stage");
+
+ b.Navigation("Uom");
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustment", b =>
{
b.HasOne("ERPCore.Domain.Entities.User", "Creator")
@@ -5575,6 +6472,17 @@ namespace ERPCore.Migrations
b.Navigation("NavItem");
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.TemplateStage", b =>
+ {
+ b.HasOne("ERPCore.Domain.Entities.ProductionTemplate", "Template")
+ .WithMany("Stages")
+ .HasForeignKey("TemplateId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Template");
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b =>
{
b.HasOne("ERPCore.Domain.Entities.Uom", "FromUom")
@@ -5692,6 +6600,24 @@ namespace ERPCore.Migrations
b.Navigation("Lines");
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.ProductionRun", b =>
+ {
+ b.Navigation("Edges");
+
+ b.Navigation("Events");
+
+ b.Navigation("Stages");
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.ProductionTemplate", b =>
+ {
+ b.Navigation("Edges");
+
+ b.Navigation("Runs");
+
+ b.Navigation("Stages");
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b =>
{
b.Navigation("Lines");
@@ -5714,6 +6640,15 @@ namespace ERPCore.Migrations
b.Navigation("Quotations");
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.RunStage", b =>
+ {
+ b.Navigation("Events");
+
+ b.Navigation("Inputs");
+
+ b.Navigation("Outputs");
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoice", b =>
{
b.Navigation("Lines");
@@ -5739,6 +6674,13 @@ namespace ERPCore.Migrations
b.Navigation("Lines");
});
+ modelBuilder.Entity("ERPCore.Domain.Entities.TemplateStage", b =>
+ {
+ b.Navigation("Inputs");
+
+ b.Navigation("Outputs");
+ });
+
modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b =>
{
b.Navigation("Lines");
diff --git a/Backend/ERPCore/Migrations/20260728053233_InitialCreate.cs b/Backend/ERPCore/Infra/Persistence/Migrations/20260803105635_SyncCurrentModel.cs
similarity index 77%
rename from Backend/ERPCore/Migrations/20260728053233_InitialCreate.cs
rename to Backend/ERPCore/Infra/Persistence/Migrations/20260803105635_SyncCurrentModel.cs
index 33fd144..c42f365 100644
--- a/Backend/ERPCore/Migrations/20260728053233_InitialCreate.cs
+++ b/Backend/ERPCore/Infra/Persistence/Migrations/20260803105635_SyncCurrentModel.cs
@@ -2,10 +2,10 @@
#nullable disable
-namespace ERPCore.Migrations
+namespace ERPCore.Infra.Persistence.Migrations
{
///
- public partial class InitialCreate : Migration
+ public partial class SyncCurrentModel : Migration
{
///
protected override void Up(MigrationBuilder migrationBuilder)
diff --git a/Backend/ERPCore/Infra/Persistence/Migrations/20260803143000_AddBundleSalesModule.cs b/Backend/ERPCore/Infra/Persistence/Migrations/20260803143000_AddBundleSalesModule.cs
new file mode 100644
index 0000000..24937a5
--- /dev/null
+++ b/Backend/ERPCore/Infra/Persistence/Migrations/20260803143000_AddBundleSalesModule.cs
@@ -0,0 +1,139 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace ERPCore.Infra.Persistence.Migrations;
+
+public partial class AddBundleSalesModule : Migration
+{
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "bundle_sale_templates",
+ columns: table => new
+ {
+ BundleSaleTemplateId = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ TemplateCode = table.Column(type: "character varying(50)", maxLength: 50, nullable: false),
+ TemplateName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false),
+ Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true),
+ Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Active"),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
+ xmin = table.Column(type: "xid", rowVersion: true, nullable: false)
+ },
+ constraints: table => table.PrimaryKey("PK_bundle_sale_templates", x => x.BundleSaleTemplateId));
+
+ migrationBuilder.CreateTable(
+ name: "bundle_sales",
+ columns: table => new
+ {
+ BundleSaleId = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ BundleNo = table.Column(type: "character varying(50)", maxLength: 50, nullable: false),
+ BundleDate = table.Column(type: "timestamp with time zone", nullable: false),
+ CustomerId = table.Column(type: "integer", nullable: false),
+ CustomerSnapshotName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false),
+ WarehouseId = table.Column(type: "integer", nullable: false),
+ CashierUserId = table.Column(type: "integer", nullable: false),
+ BundleSaleTemplateId = table.Column(type: "integer", nullable: false),
+ BundleName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false),
+ BundleCode = table.Column(type: "character varying(50)", maxLength: 50, nullable: false),
+ Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Draft"),
+ ComponentSubtotal = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ BundlePrice = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ MarginAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ DiscountTotal = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ TaxTotal = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ GrandTotal = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
+ xmin = table.Column(type: "xid", rowVersion: true, nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_bundle_sales", x => x.BundleSaleId);
+ table.ForeignKey("FK_bundle_sales_bundle_sale_templates_BundleSaleTemplateId", x => x.BundleSaleTemplateId, "bundle_sale_templates", "BundleSaleTemplateId", onDelete: ReferentialAction.Restrict);
+ table.ForeignKey("FK_bundle_sales_customers_CustomerId", x => x.CustomerId, "customers", "CustomerId", onDelete: ReferentialAction.Restrict);
+ table.ForeignKey("FK_bundle_sales_users_CashierUserId", x => x.CashierUserId, "users", "UserId", onDelete: ReferentialAction.Restrict);
+ table.ForeignKey("FK_bundle_sales_warehouses_WarehouseId", x => x.WarehouseId, "warehouses", "WarehouseId", onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "bundle_sale_template_lines",
+ columns: table => new
+ {
+ BundleSaleTemplateLineId = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ BundleSaleTemplateId = table.Column(type: "integer", nullable: false),
+ ItemId = table.Column(type: "integer", nullable: false),
+ UomId = table.Column(type: "integer", nullable: false),
+ WarehouseId = table.Column(type: "integer", nullable: false),
+ Qty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ UnitPrice = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ IncludeInBundle = table.Column(type: "boolean", nullable: false, defaultValue: true),
+ SortOrder = table.Column(type: "integer", nullable: false, defaultValue: 0)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_bundle_sale_template_lines", x => x.BundleSaleTemplateLineId);
+ table.ForeignKey("FK_bundle_sale_template_lines_bundle_sale_templates_BundleSaleTemplateId", x => x.BundleSaleTemplateId, "bundle_sale_templates", "BundleSaleTemplateId", onDelete: ReferentialAction.Cascade);
+ table.ForeignKey("FK_bundle_sale_template_lines_items_ItemId", x => x.ItemId, "items", "ItemId", onDelete: ReferentialAction.Restrict);
+ table.ForeignKey("FK_bundle_sale_template_lines_uoms_UomId", x => x.UomId, "uoms", "UomId", onDelete: ReferentialAction.Restrict);
+ table.ForeignKey("FK_bundle_sale_template_lines_warehouses_WarehouseId", x => x.WarehouseId, "warehouses", "WarehouseId", onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "bundle_sale_lines",
+ columns: table => new
+ {
+ BundleSaleLineId = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ BundleSaleId = table.Column(type: "integer", nullable: false),
+ ItemId = table.Column(type: "integer", nullable: false),
+ Description = table.Column(type: "character varying(200)", maxLength: 200, nullable: false),
+ Qty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ UomId = table.Column(type: "integer", nullable: false),
+ WarehouseId = table.Column(type: "integer", nullable: false),
+ UnitPrice = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ LineTotal = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
+ IncludeInBundle = table.Column(type: "boolean", nullable: false, defaultValue: true),
+ IsComponent = table.Column(type: "boolean", nullable: false, defaultValue: true),
+ ParentLineId = table.Column(type: "integer", nullable: true),
+ xmin = table.Column(type: "xid", rowVersion: true, nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_bundle_sale_lines", x => x.BundleSaleLineId);
+ table.ForeignKey("FK_bundle_sale_lines_bundle_sales_BundleSaleId", x => x.BundleSaleId, "bundle_sales", "BundleSaleId", onDelete: ReferentialAction.Cascade);
+ table.ForeignKey("FK_bundle_sale_lines_items_ItemId", x => x.ItemId, "items", "ItemId", onDelete: ReferentialAction.Restrict);
+ table.ForeignKey("FK_bundle_sale_lines_uoms_UomId", x => x.UomId, "uoms", "UomId", onDelete: ReferentialAction.Restrict);
+ table.ForeignKey("FK_bundle_sale_lines_warehouses_WarehouseId", x => x.WarehouseId, "warehouses", "WarehouseId", onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_templates_TemplateCode", table: "bundle_sale_templates", column: "TemplateCode", unique: true);
+ migrationBuilder.CreateIndex(name: "IX_bundle_sales_BundleNo", table: "bundle_sales", column: "BundleNo", unique: true);
+ migrationBuilder.CreateIndex(name: "IX_bundle_sales_BundleSaleTemplateId", table: "bundle_sales", column: "BundleSaleTemplateId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sales_CashierUserId", table: "bundle_sales", column: "CashierUserId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sales_CustomerId", table: "bundle_sales", column: "CustomerId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sales_Status", table: "bundle_sales", column: "Status");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sales_WarehouseId", table: "bundle_sales", column: "WarehouseId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_template_lines_BundleSaleTemplateId", table: "bundle_sale_template_lines", column: "BundleSaleTemplateId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_template_lines_ItemId", table: "bundle_sale_template_lines", column: "ItemId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_template_lines_UomId", table: "bundle_sale_template_lines", column: "UomId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_template_lines_WarehouseId", table: "bundle_sale_template_lines", column: "WarehouseId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_lines_BundleSaleId", table: "bundle_sale_lines", column: "BundleSaleId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_lines_ItemId", table: "bundle_sale_lines", column: "ItemId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_lines_UomId", table: "bundle_sale_lines", column: "UomId");
+ migrationBuilder.CreateIndex(name: "IX_bundle_sale_lines_WarehouseId", table: "bundle_sale_lines", column: "WarehouseId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable("bundle_sale_lines");
+ migrationBuilder.DropTable("bundle_sale_template_lines");
+ migrationBuilder.DropTable("bundle_sales");
+ migrationBuilder.DropTable("bundle_sale_templates");
+ }
+}
diff --git a/Backend/ERPCore/Infra/Persistence/Migrations/20260804103000_AddBundleSalesConcurrencyStamp.cs b/Backend/ERPCore/Infra/Persistence/Migrations/20260804103000_AddBundleSalesConcurrencyStamp.cs
new file mode 100644
index 0000000..88de032
--- /dev/null
+++ b/Backend/ERPCore/Infra/Persistence/Migrations/20260804103000_AddBundleSalesConcurrencyStamp.cs
@@ -0,0 +1,36 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace ERPCore.Infra.Persistence.Migrations;
+
+public partial class AddBundleSalesConcurrencyStamp : Migration
+{
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "ConcurrencyStamp",
+ table: "bundle_sale_templates",
+ type: "integer",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "ConcurrencyStamp",
+ table: "bundle_sales",
+ type: "integer",
+ nullable: false,
+ defaultValue: 0);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "ConcurrencyStamp",
+ table: "bundle_sales");
+
+ migrationBuilder.DropColumn(
+ name: "ConcurrencyStamp",
+ table: "bundle_sale_templates");
+ }
+}
diff --git a/Backend/ERPCore/Infra/Persistence/Migrations/ErpDbContextModelSnapshot.cs b/Backend/ERPCore/Infra/Persistence/Migrations/ErpDbContextModelSnapshot.cs
index 56bcc7b..5577794 100644
--- a/Backend/ERPCore/Infra/Persistence/Migrations/ErpDbContextModelSnapshot.cs
+++ b/Backend/ERPCore/Infra/Persistence/Migrations/ErpDbContextModelSnapshot.cs
@@ -17,7 +17,7 @@ namespace ERPCore.Infra.Persistence.Migrations
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "10.0.9")
+ .HasAnnotation("ProductVersion", "9.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
diff --git a/Backend/ERPCore/Migrations/20260728053233_InitialCreate.Designer.cs b/Backend/ERPCore/Migrations/20260728053233_InitialCreate.Designer.cs
deleted file mode 100644
index f11cbe0..0000000
--- a/Backend/ERPCore/Migrations/20260728053233_InitialCreate.Designer.cs
+++ /dev/null
@@ -1,5651 +0,0 @@
-//
-using System;
-using ERPCore.Infra.Persistence;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace ERPCore.Migrations
-{
- [DbContext(typeof(ErpDbContext))]
- [Migration("20260728053233_InitialCreate")]
- partial class InitialCreate
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.9")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("ERPCore.Domain.Entities.AttendanceRecord", b =>
- {
- b.Property("AttendanceRecordId")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("AttendanceRecordId"));
-
- b.Property("AttendanceDate")
- .HasColumnType("timestamp with time zone");
-
- b.Property("AttendanceStatus")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("AttendanceUploadBatchId")
- .HasColumnType("integer");
-
- b.Property("CheckIn")
- .HasColumnType("interval");
-
- b.Property("CheckOut")
- .HasColumnType("interval");
-
- b.Property("DuplicateOfAttendanceRecordId")
- .HasColumnType("integer");
-
- b.Property("EarlyLeaveMinutes")
- .HasColumnType("integer");
-
- b.Property("EditedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("EditedBy")
- .HasColumnType("integer");
-
- b.Property("EmployeeId")
- .HasColumnType("integer");
-
- b.Property("IsManualOverride")
- .HasColumnType("boolean");
-
- b.Property("LateMinutes")
- .HasColumnType("integer");
-
- b.Property("Notes")
- .HasMaxLength(1000)
- .HasColumnType("character varying(1000)");
-
- b.Property("OvertimeMinutes")
- .HasColumnType("integer");
-
- b.Property("RowValidationStatus")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("RowVersion")
- .IsConcurrencyToken()
- .ValueGeneratedOnAddOrUpdate()
- .HasColumnType("xid")
- .HasColumnName("xmin");
-
- b.Property("WorkShiftId")
- .HasColumnType("integer");
-
- b.Property("WorkingMinutes")
- .HasColumnType("integer");
-
- b.HasKey("AttendanceRecordId");
-
- b.HasIndex("AttendanceUploadBatchId");
-
- b.HasIndex("WorkShiftId");
-
- b.HasIndex("EmployeeId", "AttendanceDate");
-
- b.ToTable("hr_attendance_records", (string)null);
- });
-
- modelBuilder.Entity("ERPCore.Domain.Entities.AttendanceUploadBatch", b =>
- {
- b.Property("AttendanceUploadBatchId")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("AttendanceUploadBatchId"));
-
- b.Property("ConfirmedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("ConfirmedBy")
- .HasColumnType("integer");
-
- b.Property("DocNo")
- .IsRequired()
- .HasMaxLength(30)
- .HasColumnType("character varying(30)");
-
- b.Property("OriginalFileName")
- .HasMaxLength(260)
- .HasColumnType("character varying(260)");
-
- b.Property("PeriodEnd")
- .HasColumnType("timestamp with time zone");
-
- b.Property("PeriodStart")
- .HasColumnType("timestamp with time zone");
-
- b.Property("RowCountDuplicate")
- .HasColumnType("integer");
-
- b.Property("RowCountError")
- .HasColumnType("integer");
-
- b.Property("RowCountTotal")
- .HasColumnType("integer");
-
- b.Property("RowVersion")
- .IsConcurrencyToken()
- .ValueGeneratedOnAddOrUpdate()
- .HasColumnType("xid")
- .HasColumnName("xmin");
-
- b.Property("SourceType")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UploadedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("UploadedBy")
- .HasColumnType("integer");
-
- b.HasKey("AttendanceUploadBatchId");
-
- b.HasIndex("DocNo")
- .IsUnique();
-
- b.HasIndex("Status");
-
- b.HasIndex("PeriodStart", "PeriodEnd");
-
- b.ToTable("hr_attendance_upload_batches", (string)null);
- });
-
- modelBuilder.Entity("ERPCore.Domain.Entities.AuditLog", b =>
- {
- b.Property("AuditId")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("AuditId"));
-
- b.Property("Action")
- .IsRequired()
- .HasMaxLength(10)
- .HasColumnType("character varying(10)");
-
- b.Property("ChangeSet")
- .IsRequired()
- .HasColumnType("jsonb");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("EntityId")
- .HasColumnType("integer");
-
- b.Property("EntityType")
- .IsRequired()
- .HasMaxLength(80)
- .HasColumnType("character varying(80)");
-
- b.Property("UserId")
- .HasColumnType("integer");
-
- b.HasKey("AuditId");
-
- b.HasIndex("CreatedAt");
-
- b.HasIndex("UserId");
-
- b.HasIndex("EntityType", "EntityId");
-
- b.ToTable("audit_logs", (string)null);
- });
-
- modelBuilder.Entity("ERPCore.Domain.Entities.Batch", b =>
- {
- b.Property("BatchId")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("BatchId"));
-
- b.Property("BatchNo")
- .IsRequired()
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("ExpiryDate")
- .HasColumnType("date");
-
- b.Property("ItemId")
- .HasColumnType("integer");
-
- b.HasKey("BatchId");
-
- b.HasIndex("ItemId", "BatchNo")
- .IsUnique();
-
- b.ToTable("batches", (string)null);
- });
-
- modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b =>
- {
- b.Property("BinId")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("BinId"));
-
- b.Property("BinType")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("Code")
- .IsRequired()
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("WarehouseId")
- .HasColumnType("integer");
-
- b.HasKey("BinId");
-
- b.HasIndex("WarehouseId", "Code")
- .IsUnique();
-
- b.ToTable("bins", (string)null);
- });
-
- modelBuilder.Entity("ERPCore.Domain.Entities.Branch", b =>
- {
- b.Property("BranchId")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("BranchId"));
-
- b.Property("Address")
- .HasMaxLength(500)
- .HasColumnType("character varying(500)");
-
- b.Property("Code")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("RowVersion")
- .IsConcurrencyToken()
- .ValueGeneratedOnAddOrUpdate()
- .HasColumnType("xid")
- .HasColumnName("xmin");
-
- b.Property("Status")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)")
- .HasDefaultValue("Active");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("BranchId");
-
- b.HasIndex("Code")
- .IsUnique();
-
- b.HasIndex("Status");
-
- b.ToTable("hr_branches", (string)null);
- });
-
- modelBuilder.Entity("ERPCore.Domain.Entities.Brand", b =>
- {
- b.Property("BrandId")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("BrandId"));
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("RowVersion")
- .IsConcurrencyToken()
- .ValueGeneratedOnAddOrUpdate()
- .HasColumnType("xid")
- .HasColumnName("xmin");
-
- b.Property("Status")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)")
- .HasDefaultValue("Active");
-
- b.Property