diff --git a/.gitignore b/.gitignore
index 6b1868c..2b7364c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,8 +31,11 @@ Thumbs.db
.idea/
# ── Migrations ─────────────────────────────────────────────────────────
-# New EF Core migrations are not committed. Note the 4 migrations already in
-# Backend/ERPCore/Infra/Persistence/Migrations/ stay tracked — .gitignore does
-# not apply to tracked files — so edits to those still get committed as normal.
-# Untracking them too takes `git rm --cached`.
-**/Migrations/
+# Reverted 2026-07-31: excluding new EF Core migrations while
+# ErpDbContextModelSnapshot.cs stayed tracked meant every `dotnet ef
+# migrations add` after the initial 4 silently produced a migration git would
+# never see, while the (tracked) snapshot's changes committed normally —
+# so the snapshot kept claiming tables existed that no migration in git
+# history ever created them. Confirmed live: 25 HRM tables + 11 Manufacturing
+# tables were missing from the actual database for exactly this reason.
+# Migrations now stay tracked like any other source file — commit them.
diff --git a/Backend/ERPCore/Infra/Persistence/Migrations/20260720105238_AddLedgersNavSeed.Designer.cs b/Backend/ERPCore/Infra/Persistence/Migrations/20260720105238_AddLedgersNavSeed.Designer.cs
new file mode 100644
index 0000000..40b45f2
--- /dev/null
+++ b/Backend/ERPCore/Infra/Persistence/Migrations/20260720105238_AddLedgersNavSeed.Designer.cs
@@ -0,0 +1,3128 @@
+//
+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.Infra.Persistence.Migrations
+{
+ [DbContext(typeof(ErpDbContext))]
+ [Migration("20260720105238_AddLedgersNavSeed")]
+ partial class AddLedgersNavSeed
+ {
+ ///
+ 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.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.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("UpdatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("BrandId");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.HasIndex("Status");
+
+ b.ToTable("brands", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
+ {
+ b.Property("CategoryId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("CategoryId"));
+
+ 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("CategoryId");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.HasIndex("Status");
+
+ b.ToTable("categories", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.Grn", b =>
+ {
+ b.Property("GrnId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("GrnId"));
+
+ 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("PoId")
+ .HasColumnType("integer");
+
+ b.Property("PostedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("VendorId")
+ .HasColumnType("integer");
+
+ b.Property("WarehouseId")
+ .HasColumnType("integer");
+
+ b.HasKey("GrnId");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DocNo")
+ .IsUnique();
+
+ b.HasIndex("PoId");
+
+ b.HasIndex("Status");
+
+ b.HasIndex("VendorId");
+
+ b.HasIndex("WarehouseId");
+
+ b.ToTable("grns", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.GrnLine", b =>
+ {
+ b.Property("GrnLineId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("GrnLineId"));
+
+ b.Property("BatchId")
+ .HasColumnType("integer");
+
+ b.Property("BinId")
+ .HasColumnType("integer");
+
+ b.Property("GrnId")
+ .HasColumnType("integer");
+
+ b.Property("HoldStatus")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("PoLineId")
+ .HasColumnType("integer");
+
+ b.Property("Qty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ReceivedValue")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("UnitCost")
+ .HasPrecision(18, 6)
+ .HasColumnType("numeric(18,6)");
+
+ b.Property("UomId")
+ .HasColumnType("integer");
+
+ b.HasKey("GrnLineId");
+
+ b.HasIndex("BatchId");
+
+ b.HasIndex("BinId");
+
+ b.HasIndex("GrnId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("PoLineId");
+
+ b.HasIndex("UomId");
+
+ b.ToTable("grn_lines", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
+ {
+ b.Property("ItemId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ItemId"));
+
+ b.Property("BaseUomId")
+ .HasColumnType("integer");
+
+ b.Property("BrandId")
+ .HasColumnType("integer");
+
+ b.Property("CategoryId")
+ .HasColumnType("integer");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DefaultVendorId")
+ .HasColumnType("integer");
+
+ b.Property("Description")
+ .HasMaxLength(1000)
+ .HasColumnType("character varying(1000)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("Sku")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("Status")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)")
+ .HasDefaultValue("Active");
+
+ b.Property("StockNature")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("SubCategoryId")
+ .HasColumnType("integer");
+
+ b.Property("TaxClass")
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("TrackingMode")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("ItemId");
+
+ b.HasIndex("BaseUomId");
+
+ b.HasIndex("BrandId");
+
+ b.HasIndex("CategoryId");
+
+ b.HasIndex("DefaultVendorId");
+
+ b.HasIndex("Sku")
+ .IsUnique();
+
+ b.HasIndex("Status");
+
+ b.HasIndex("SubCategoryId");
+
+ b.ToTable("items", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b =>
+ {
+ b.Property("ReorderId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ReorderId"));
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("ReorderPoint")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ReorderQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("WarehouseId")
+ .HasColumnType("integer");
+
+ b.HasKey("ReorderId");
+
+ b.HasIndex("WarehouseId");
+
+ b.HasIndex("ItemId", "WarehouseId")
+ .IsUnique();
+
+ b.ToTable("item_reorders", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.ItemType", b =>
+ {
+ b.Property("ItemTypeId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ItemTypeId"));
+
+ 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("ItemTypeId");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.HasIndex("Status");
+
+ b.ToTable("item_types", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.JournalEntryStub", b =>
+ {
+ b.Property("JournalId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("JournalId"));
+
+ b.Property("Amount")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("CreditAccount")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("DebitAccount")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("SourceDocId")
+ .HasColumnType("integer");
+
+ b.Property("SourceDocType")
+ .IsRequired()
+ .HasMaxLength(10)
+ .HasColumnType("character varying(10)");
+
+ b.HasKey("JournalId");
+
+ b.HasIndex("SourceDocType", "SourceDocId");
+
+ b.ToTable("journal_entry_stubs", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.NavItem", b =>
+ {
+ b.Property("NavItemId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("NavItemId"));
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("Href")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("Icon")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("Label")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
+
+ b.Property("SortOrder")
+ .HasColumnType("integer");
+
+ b.Property("Status")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)")
+ .HasDefaultValue("Active");
+
+ b.HasKey("NavItemId");
+
+ b.HasIndex("Code")
+ .IsUnique();
+
+ b.ToTable("nav_items", (string)null);
+
+ b.HasData(
+ new
+ {
+ NavItemId = 1,
+ Code = "dashboard",
+ Href = "/dashboard",
+ Label = "Dashboard",
+ SortOrder = 1,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 2,
+ Code = "products",
+ Href = "/dashboard/products",
+ Label = "Products",
+ SortOrder = 2,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 3,
+ Code = "vendors",
+ Href = "/dashboard/vendors",
+ Label = "Vendors",
+ SortOrder = 3,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 4,
+ Code = "procurement",
+ Href = "/dashboard/procurement",
+ Label = "Procurement",
+ SortOrder = 4,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 5,
+ Code = "receiving",
+ Href = "/dashboard/receiving/grn",
+ Label = "Receiving",
+ SortOrder = 5,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 6,
+ Code = "stock",
+ Href = "/dashboard/stock",
+ Label = "Stock",
+ SortOrder = 6,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 7,
+ Code = "warehouses",
+ Href = "/dashboard/warehouse",
+ Label = "Warehouses",
+ SortOrder = 7,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 8,
+ Code = "orders",
+ Href = "/dashboard/orders",
+ Label = "Orders",
+ SortOrder = 8,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 9,
+ Code = "settings",
+ Href = "/dashboard/settings",
+ Label = "Settings",
+ SortOrder = 9,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 10,
+ Code = "help",
+ Href = "/dashboard/help",
+ Label = "Help",
+ SortOrder = 10,
+ Status = "Active"
+ },
+ new
+ {
+ NavItemId = 11,
+ Code = "ledgers",
+ Href = "/dashboard/ledgers",
+ Label = "Ledgers",
+ SortOrder = 11,
+ Status = "Active"
+ });
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.NumberSequence", b =>
+ {
+ b.Property("SequenceId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SequenceId"));
+
+ b.Property("DocType")
+ .IsRequired()
+ .HasMaxLength(10)
+ .HasColumnType("character varying(10)")
+ .HasColumnName("doc_type");
+
+ b.Property("LastNumber")
+ .HasColumnType("integer")
+ .HasColumnName("last_number");
+
+ b.Property("Year")
+ .HasColumnType("integer")
+ .HasColumnName("year");
+
+ b.HasKey("SequenceId");
+
+ b.HasIndex("DocType", "Year")
+ .IsUnique();
+
+ b.ToTable("number_sequences", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.Permission", b =>
+ {
+ b.Property("PermissionId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PermissionId"));
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(80)
+ .HasColumnType("character varying(80)");
+
+ b.Property("NavItemId")
+ .HasColumnType("integer");
+
+ b.Property("SubNavItemId")
+ .HasColumnType("integer");
+
+ b.HasKey("PermissionId");
+
+ b.HasIndex("Code")
+ .IsUnique();
+
+ b.HasIndex("NavItemId");
+
+ b.HasIndex("SubNavItemId");
+
+ b.ToTable("permissions", (string)null);
+
+ b.HasData(
+ new
+ {
+ PermissionId = 1,
+ Code = "NAV:dashboard",
+ NavItemId = 1
+ },
+ new
+ {
+ PermissionId = 2,
+ Code = "NAV:products",
+ NavItemId = 2
+ },
+ new
+ {
+ PermissionId = 3,
+ Code = "NAV:vendors",
+ NavItemId = 3
+ },
+ new
+ {
+ PermissionId = 4,
+ Code = "NAV:procurement",
+ NavItemId = 4
+ },
+ new
+ {
+ PermissionId = 5,
+ Code = "NAV:receiving",
+ NavItemId = 5
+ },
+ new
+ {
+ PermissionId = 6,
+ Code = "NAV:stock",
+ NavItemId = 6
+ },
+ new
+ {
+ PermissionId = 7,
+ Code = "NAV:warehouses",
+ NavItemId = 7
+ },
+ new
+ {
+ PermissionId = 8,
+ Code = "NAV:orders",
+ NavItemId = 8
+ },
+ new
+ {
+ PermissionId = 9,
+ Code = "NAV:settings",
+ NavItemId = 9
+ },
+ new
+ {
+ PermissionId = 10,
+ Code = "NAV:help",
+ NavItemId = 10
+ },
+ new
+ {
+ PermissionId = 11,
+ Code = "NAV:products.item",
+ SubNavItemId = 1
+ },
+ new
+ {
+ PermissionId = 12,
+ Code = "NAV:products.category",
+ SubNavItemId = 2
+ },
+ new
+ {
+ PermissionId = 13,
+ Code = "NAV:products.brand",
+ SubNavItemId = 3
+ },
+ new
+ {
+ PermissionId = 14,
+ Code = "NAV:products.item-type",
+ SubNavItemId = 4
+ },
+ new
+ {
+ PermissionId = 15,
+ Code = "NAV:products.uom",
+ SubNavItemId = 5
+ },
+ new
+ {
+ PermissionId = 16,
+ Code = "NAV:products.configuration",
+ SubNavItemId = 6
+ },
+ new
+ {
+ PermissionId = 17,
+ Code = "NAV:settings.roles",
+ SubNavItemId = 7
+ },
+ new
+ {
+ PermissionId = 18,
+ Code = "NAV:settings.users",
+ SubNavItemId = 8
+ },
+ new
+ {
+ PermissionId = 19,
+ Code = "NAV:ledgers",
+ NavItemId = 11
+ },
+ new
+ {
+ PermissionId = 20,
+ Code = "NAV:ledgers.trial-balance",
+ SubNavItemId = 9
+ },
+ new
+ {
+ PermissionId = 21,
+ Code = "NAV:ledgers.balance-sheet",
+ SubNavItemId = 10
+ },
+ new
+ {
+ PermissionId = 22,
+ 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 = 26,
+ Code = "NAV:ledgers.bank-accounts",
+ SubNavItemId = 15
+ });
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.PoLine", b =>
+ {
+ b.Property("PoLineId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PoLineId"));
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("PoId")
+ .HasColumnType("integer");
+
+ b.Property("Qty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("QtyReceived")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("Tax")
+ .HasPrecision(9, 4)
+ .HasColumnType("numeric(9,4)");
+
+ b.Property("UnitPrice")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("UomId")
+ .HasColumnType("integer");
+
+ b.Property("WarehouseId")
+ .HasColumnType("integer");
+
+ b.HasKey("PoLineId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("PoId");
+
+ b.HasIndex("UomId");
+
+ b.HasIndex("WarehouseId");
+
+ b.ToTable("po_lines", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.ProductConfig", b =>
+ {
+ b.Property("ConfigId")
+ .HasColumnType("integer");
+
+ b.Property("BrandsEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(true);
+
+ b.Property("ItemTypesEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(true);
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("SubcategoriesEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(true);
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("integer");
+
+ b.HasKey("ConfigId");
+
+ b.HasIndex("UpdatedBy");
+
+ b.ToTable("product_config", null, t =>
+ {
+ t.HasCheckConstraint("ck_product_config_singleton", "\"ConfigId\" = 1");
+ });
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b =>
+ {
+ b.Property("PoId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PoId"));
+
+ b.Property("ApprovalRequired")
+ .HasColumnType("boolean");
+
+ 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("RequisitionId")
+ .HasColumnType("integer");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("VendorId")
+ .HasColumnType("integer");
+
+ b.HasKey("PoId");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DocNo")
+ .IsUnique();
+
+ b.HasIndex("RequisitionId");
+
+ b.HasIndex("Status");
+
+ b.HasIndex("VendorId");
+
+ b.ToTable("purchase_orders", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseReturn", b =>
+ {
+ b.Property("ReturnId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ReturnId"));
+
+ 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("ReasonCodeId")
+ .HasColumnType("integer");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("VendorId")
+ .HasColumnType("integer");
+
+ b.Property("WarehouseId")
+ .HasColumnType("integer");
+
+ b.HasKey("ReturnId");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DocNo")
+ .IsUnique();
+
+ b.HasIndex("ReasonCodeId");
+
+ b.HasIndex("VendorId");
+
+ b.HasIndex("WarehouseId");
+
+ b.ToTable("purchase_returns", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseReturnLine", b =>
+ {
+ b.Property("ReturnLineId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ReturnLineId"));
+
+ b.Property("GrnLineId")
+ .HasColumnType("integer");
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("Qty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ReturnId")
+ .HasColumnType("integer");
+
+ b.HasKey("ReturnLineId");
+
+ b.HasIndex("GrnLineId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("ReturnId");
+
+ b.ToTable("purchase_return_lines", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.ReasonCode", b =>
+ {
+ b.Property("ReasonCodeId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ReasonCodeId"));
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("Context")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.HasKey("ReasonCodeId");
+
+ b.HasIndex("Context", "Code")
+ .IsUnique();
+
+ b.ToTable("reason_codes", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.Requisition", b =>
+ {
+ b.Property("RequisitionId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RequisitionId"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DocNo")
+ .IsRequired()
+ .HasMaxLength(30)
+ .HasColumnType("character varying(30)");
+
+ b.Property("RequestedBy")
+ .HasColumnType("integer");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.HasKey("RequisitionId");
+
+ b.HasIndex("DocNo")
+ .IsUnique();
+
+ b.HasIndex("RequestedBy");
+
+ b.HasIndex("Status");
+
+ b.ToTable("requisitions", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RequisitionLine", b =>
+ {
+ b.Property("ReqLineId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ReqLineId"));
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("Qty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("RequiredBy")
+ .HasColumnType("date");
+
+ b.Property("RequisitionId")
+ .HasColumnType("integer");
+
+ b.HasKey("ReqLineId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("RequisitionId");
+
+ b.ToTable("requisition_lines", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.Rfq", b =>
+ {
+ b.Property("RfqId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RfqId"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DocNo")
+ .IsRequired()
+ .HasMaxLength(30)
+ .HasColumnType("character varying(30)");
+
+ b.Property("RequisitionId")
+ .HasColumnType("integer");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.HasKey("RfqId");
+
+ b.HasIndex("DocNo")
+ .IsUnique();
+
+ b.HasIndex("RequisitionId");
+
+ b.ToTable("rfqs", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RfqLine", b =>
+ {
+ b.Property("RfqLineId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RfqLineId"));
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("Qty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("RfqId")
+ .HasColumnType("integer");
+
+ b.HasKey("RfqLineId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("RfqId");
+
+ b.ToTable("rfq_lines", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.Role", b =>
+ {
+ b.Property("RoleId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("RoleId"));
+
+ b.Property("AuthRoleId")
+ .HasColumnType("uuid")
+ .HasColumnName("auth_role_id");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsSystemRole")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false);
+
+ 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("RoleId");
+
+ b.HasIndex("AuthRoleId")
+ .IsUnique();
+
+ b.HasIndex("Code")
+ .IsUnique();
+
+ b.ToTable("roles", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.RolePermission", b =>
+ {
+ b.Property("RoleId")
+ .HasColumnType("integer");
+
+ b.Property("PermissionId")
+ .HasColumnType("integer");
+
+ b.HasKey("RoleId", "PermissionId");
+
+ b.HasIndex("PermissionId");
+
+ b.ToTable("role_permissions", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.Serial", b =>
+ {
+ b.Property("SerialId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SerialId"));
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("SerialNo")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.HasKey("SerialId");
+
+ b.HasIndex("ItemId", "SerialNo")
+ .IsUnique();
+
+ b.ToTable("serials", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustment", b =>
+ {
+ b.Property("AdjustmentId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("AdjustmentId"));
+
+ 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("ReasonCodeId")
+ .HasColumnType("integer");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("WarehouseId")
+ .HasColumnType("integer");
+
+ b.HasKey("AdjustmentId");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DocNo")
+ .IsUnique();
+
+ b.HasIndex("ReasonCodeId");
+
+ b.HasIndex("WarehouseId");
+
+ b.ToTable("stock_adjustments", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustmentLine", b =>
+ {
+ b.Property("AdjLineId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("AdjLineId"));
+
+ b.Property("AdjustmentId")
+ .HasColumnType("integer");
+
+ b.Property("BatchId")
+ .HasColumnType("integer");
+
+ b.Property("BinId")
+ .HasColumnType("integer");
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("QtyDelta")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("SerialId")
+ .HasColumnType("integer");
+
+ b.HasKey("AdjLineId");
+
+ b.HasIndex("AdjustmentId");
+
+ b.HasIndex("BatchId");
+
+ b.HasIndex("BinId");
+
+ b.HasIndex("ItemId");
+
+ b.HasIndex("SerialId");
+
+ b.ToTable("stock_adjustment_lines", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StockCount", b =>
+ {
+ b.Property("CountId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("CountId"));
+
+ b.Property("CountType")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ 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("RowVersion")
+ .IsConcurrencyToken()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("xid")
+ .HasColumnName("xmin");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("WarehouseId")
+ .HasColumnType("integer");
+
+ b.HasKey("CountId");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DocNo")
+ .IsUnique();
+
+ b.HasIndex("Status");
+
+ b.HasIndex("WarehouseId");
+
+ b.ToTable("stock_counts", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StockCountLine", b =>
+ {
+ b.Property("CountLineId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("CountLineId"));
+
+ b.Property("BinId")
+ .HasColumnType("integer");
+
+ b.Property("CountId")
+ .HasColumnType("integer");
+
+ b.Property("CountedQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("SystemQty")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("Variance")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.HasKey("CountLineId");
+
+ b.HasIndex("BinId");
+
+ b.HasIndex("CountId");
+
+ b.HasIndex("ItemId");
+
+ b.ToTable("stock_count_lines", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StockLayer", b =>
+ {
+ b.Property("LayerId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LayerId"));
+
+ b.Property("BatchId")
+ .HasColumnType("integer");
+
+ b.Property("GrnLineId")
+ .HasColumnType("integer");
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("QtyReceived")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("QtyRemaining")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("ReceiptDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("SerialId")
+ .HasColumnType("integer");
+
+ b.Property("UnitCost")
+ .HasPrecision(18, 6)
+ .HasColumnType("numeric(18,6)");
+
+ b.Property("WarehouseId")
+ .HasColumnType("integer");
+
+ b.HasKey("LayerId");
+
+ b.HasIndex("BatchId");
+
+ b.HasIndex("GrnLineId");
+
+ b.HasIndex("SerialId");
+
+ b.HasIndex("WarehouseId");
+
+ b.HasIndex("ItemId", "WarehouseId", "ReceiptDate", "LayerId");
+
+ b.ToTable("stock_layers", (string)null);
+ });
+
+ modelBuilder.Entity("ERPCore.Domain.Entities.StockLedger", b =>
+ {
+ b.Property("LedgerId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LedgerId"));
+
+ b.Property("BatchId")
+ .HasColumnType("integer");
+
+ b.Property("BinId")
+ .HasColumnType("integer");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Direction")
+ .IsRequired()
+ .HasMaxLength(5)
+ .HasColumnType("character varying(5)");
+
+ b.Property("ItemId")
+ .HasColumnType("integer");
+
+ b.Property("QtyBase")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("RunningBalance")
+ .HasPrecision(18, 4)
+ .HasColumnType("numeric(18,4)");
+
+ b.Property("SerialId")
+ .HasColumnType("integer");
+
+ b.Property("SourceDocId")
+ .HasColumnType("integer");
+
+ b.Property