Merge pull request 'Feat/sales management' (#23) from feat/sales-management into Dev

Reviewed-on: #23
This commit was merged in pull request #23.
This commit is contained in:
2026-08-01 01:47:27 +00:00
36 changed files with 3135 additions and 0 deletions
@@ -0,0 +1,50 @@
using ERPCore.Domain.Entities;
using ERPCore.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace ERPCore.Infra.Persistence.Configurations;
public sealed class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.ToTable("customers");
builder.HasKey(c => c.CustomerId);
builder.Property(c => c.CustomerCode).IsRequired().HasMaxLength(50);
builder.HasIndex(c => c.CustomerCode).IsUnique();
builder.Property(c => c.CustomerType)
.HasConversion<string>().HasMaxLength(20).IsRequired()
.HasDefaultValue(CustomerType.B2C);
builder.Property(c => c.Name).IsRequired().HasMaxLength(200);
builder.Property(c => c.DisplayName).HasMaxLength(200);
builder.Property(c => c.Phone).HasMaxLength(30);
builder.Property(c => c.Email).HasMaxLength(100);
builder.Property(c => c.AddressLine1).HasMaxLength(250);
builder.Property(c => c.AddressLine2).HasMaxLength(250);
builder.Property(c => c.City).HasMaxLength(100);
builder.Property(c => c.Country).HasMaxLength(100);
builder.Property(c => c.TaxRegistrationNo).HasMaxLength(50);
builder.Property(c => c.CreditLimit).HasPrecision(18, 4);
builder.Property(c => c.CreditDays).IsRequired();
builder.HasOne(c => c.DefaultWarehouse)
.WithMany()
.HasForeignKey(c => c.DefaultWarehouseId)
.OnDelete(DeleteBehavior.SetNull);
builder.Property(c => c.Status)
.HasConversion<string>().HasMaxLength(20).IsRequired()
.HasDefaultValue(EntityStatus.Active);
builder.Property(c => c.CreatedAt).IsRequired();
builder.Property(c => c.RowVersion).IsRowVersion();
builder.HasIndex(c => c.Status);
builder.HasIndex(c => c.CustomerType);
}
}
@@ -0,0 +1,95 @@
using ERPCore.Domain.Entities;
using ERPCore.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace ERPCore.Infra.Persistence.Configurations;
public sealed class SalesInvoiceConfiguration : IEntityTypeConfiguration<SalesInvoice>
{
public void Configure(EntityTypeBuilder<SalesInvoice> builder)
{
builder.ToTable("sales_invoices");
builder.HasKey(x => x.SalesInvoiceId);
builder.Property(x => x.InvoiceNo).IsRequired().HasMaxLength(50);
builder.HasIndex(x => x.InvoiceNo).IsUnique();
builder.Property(x => x.InvoiceDate).IsRequired();
builder.HasOne(x => x.Customer)
.WithMany()
.HasForeignKey(x => x.CustomerId)
.OnDelete(DeleteBehavior.Restrict);
builder.Property(x => x.CustomerSnapshotName).IsRequired().HasMaxLength(200);
builder.Property(x => x.CustomerSnapshotTaxNo).HasMaxLength(50);
builder.HasOne(x => x.Warehouse)
.WithMany()
.HasForeignKey(x => x.WarehouseId)
.OnDelete(DeleteBehavior.Restrict);
builder.Property(x => x.InvoiceType)
.HasConversion<string>().HasMaxLength(20).IsRequired()
.HasDefaultValue(SalesInvoiceType.B2C);
builder.Property(x => x.Status)
.HasConversion<string>().HasMaxLength(20).IsRequired()
.HasDefaultValue(SalesInvoiceStatus.Draft);
foreach (var p in new[] { nameof(SalesInvoice.Subtotal), nameof(SalesInvoice.DiscountTotal), nameof(SalesInvoice.TaxTotal), nameof(SalesInvoice.GrandTotal), nameof(SalesInvoice.RoundOff), nameof(SalesInvoice.NetPayable), nameof(SalesInvoice.PaidAmount), nameof(SalesInvoice.BalanceAmount) })
builder.Property<decimal>(p).HasPrecision(18, 4);
builder.Property(x => x.CreatedAt).IsRequired();
builder.Property(x => x.RowVersion).IsRowVersion();
builder.HasIndex(x => x.Status);
builder.HasIndex(x => x.InvoiceDate);
builder.HasMany(x => x.Lines)
.WithOne(x => x.SalesInvoice)
.HasForeignKey(x => x.SalesInvoiceId)
.OnDelete(DeleteBehavior.Cascade);
}
}
public sealed class SalesInvoiceLineConfiguration : IEntityTypeConfiguration<SalesInvoiceLine>
{
public void Configure(EntityTypeBuilder<SalesInvoiceLine> builder)
{
builder.ToTable("sales_invoice_lines");
builder.HasKey(x => x.SalesInvoiceLineId);
builder.HasOne(x => x.Item)
.WithMany()
.HasForeignKey(x => x.ItemId)
.OnDelete(DeleteBehavior.Restrict);
builder.Property(x => x.Description).IsRequired().HasMaxLength(200);
builder.Property(x => x.Qty).HasPrecision(18, 4);
builder.Property(x => x.FreeQty).HasPrecision(18, 4);
builder.Property(x => x.UnitPrice).HasPrecision(18, 4);
builder.Property(x => x.BaseCost).HasPrecision(18, 4);
builder.Property(x => x.DiscountPct).HasPrecision(9, 4);
builder.Property(x => x.DiscountAmount).HasPrecision(18, 4);
builder.Property(x => x.NetUnitPrice).HasPrecision(18, 4);
builder.Property(x => x.LineTotal).HasPrecision(18, 4);
builder.Property(x => x.TaxPct).HasPrecision(9, 4);
builder.Property(x => x.TaxAmount).HasPrecision(18, 4);
builder.HasOne(x => x.Uom)
.WithMany()
.HasForeignKey(x => x.UomId)
.OnDelete(DeleteBehavior.Restrict);
builder.HasOne(x => x.Warehouse)
.WithMany()
.HasForeignKey(x => x.WarehouseId)
.OnDelete(DeleteBehavior.Restrict);
builder.Property(x => x.PriceSource).HasMaxLength(50);
builder.Property(x => x.RowVersion).IsRowVersion();
}
}
@@ -0,0 +1,95 @@
using ERPCore.Domain.Entities;
using ERPCore.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace ERPCore.Infra.Persistence.Configurations;
public sealed class SalesSlipConfiguration : IEntityTypeConfiguration<SalesSlip>
{
public void Configure(EntityTypeBuilder<SalesSlip> builder)
{
builder.ToTable("sales_slips");
builder.HasKey(x => x.SalesSlipId);
builder.Property(x => x.SlipNo).IsRequired().HasMaxLength(50);
builder.HasIndex(x => x.SlipNo).IsUnique();
builder.Property(x => x.SlipDate).IsRequired();
builder.HasOne(x => x.Customer)
.WithMany()
.HasForeignKey(x => x.CustomerId)
.OnDelete(DeleteBehavior.Restrict);
builder.Property(x => x.CustomerSnapshotName).IsRequired().HasMaxLength(200);
builder.HasOne(x => x.Warehouse)
.WithMany()
.HasForeignKey(x => x.WarehouseId)
.OnDelete(DeleteBehavior.Restrict);
builder.HasOne(x => x.CashierUser)
.WithMany()
.HasForeignKey(x => x.CashierUserId)
.OnDelete(DeleteBehavior.Restrict);
builder.Property(x => x.Status)
.HasConversion<string>().HasMaxLength(20).IsRequired()
.HasDefaultValue(SalesSlipStatus.Draft);
foreach (var p in new[] { nameof(SalesSlip.Subtotal), nameof(SalesSlip.DiscountTotal), nameof(SalesSlip.TaxTotal), nameof(SalesSlip.GrandTotal), nameof(SalesSlip.PaidAmount), nameof(SalesSlip.BalanceAmount) })
builder.Property<decimal>(p).HasPrecision(18, 4);
builder.Property(x => x.CreatedAt).IsRequired();
builder.Property(x => x.RowVersion).IsRowVersion();
builder.HasIndex(x => x.Status);
builder.HasIndex(x => x.SlipDate);
builder.HasMany(x => x.Lines)
.WithOne(x => x.SalesSlip)
.HasForeignKey(x => x.SalesSlipId)
.OnDelete(DeleteBehavior.Cascade);
}
}
public sealed class SalesSlipLineConfiguration : IEntityTypeConfiguration<SalesSlipLine>
{
public void Configure(EntityTypeBuilder<SalesSlipLine> builder)
{
builder.ToTable("sales_slip_lines");
builder.HasKey(x => x.SalesSlipLineId);
builder.HasOne(x => x.Item)
.WithMany()
.HasForeignKey(x => x.ItemId)
.OnDelete(DeleteBehavior.Restrict);
builder.Property(x => x.Description).IsRequired().HasMaxLength(200);
builder.Property(x => x.Qty).HasPrecision(18, 4);
builder.Property(x => x.FreeQty).HasPrecision(18, 4);
builder.Property(x => x.UnitPrice).HasPrecision(18, 4);
builder.Property(x => x.BaseCost).HasPrecision(18, 4);
builder.Property(x => x.DiscountPct).HasPrecision(9, 4);
builder.Property(x => x.DiscountAmount).HasPrecision(18, 4);
builder.Property(x => x.NetUnitPrice).HasPrecision(18, 4);
builder.Property(x => x.LineTotal).HasPrecision(18, 4);
builder.Property(x => x.TaxPct).HasPrecision(9, 4);
builder.Property(x => x.TaxAmount).HasPrecision(18, 4);
builder.HasOne(x => x.Uom)
.WithMany()
.HasForeignKey(x => x.UomId)
.OnDelete(DeleteBehavior.Restrict);
builder.HasOne(x => x.Warehouse)
.WithMany()
.HasForeignKey(x => x.WarehouseId)
.OnDelete(DeleteBehavior.Restrict);
builder.Property(x => x.PriceSource).HasMaxLength(50);
builder.Property(x => x.RowVersion).IsRowVersion();
}
}
@@ -22,6 +22,7 @@ public class ErpDbContext : DbContext
}
// --- Master Data (docs/10 Part C.1) ---
public DbSet<Customer> Customers => Set<Customer>();
public DbSet<Category> Categories => Set<Category>();
public DbSet<SubCategory> SubCategories => Set<SubCategory>();
public DbSet<Brand> Brands => Set<Brand>();
@@ -82,6 +83,12 @@ public class ErpDbContext : DbContext
public DbSet<PurchaseReturn> PurchaseReturns => Set<PurchaseReturn>();
public DbSet<PurchaseReturnLine> PurchaseReturnLines => Set<PurchaseReturnLine>();
// --- Sales (Phase 1) ---
public DbSet<SalesInvoice> SalesInvoices => Set<SalesInvoice>();
public DbSet<SalesInvoiceLine> SalesInvoiceLines => Set<SalesInvoiceLine>();
public DbSet<SalesSlip> SalesSlips => Set<SalesSlip>();
public DbSet<SalesSlipLine> SalesSlipLines => Set<SalesSlipLine>();
// --- Reference data (docs/10 Part C.7) ---
public DbSet<ReasonCode> ReasonCodes => Set<ReasonCode>();
@@ -407,6 +407,106 @@ namespace ERPCore.Infra.Persistence.Migrations
b.ToTable("categories", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Customer", b =>
{
b.Property<int>("CustomerId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("CustomerId"));
b.Property<string>("AddressLine1")
.HasMaxLength(250)
.HasColumnType("character varying(250)");
b.Property<string>("AddressLine2")
.HasMaxLength(250)
.HasColumnType("character varying(250)");
b.Property<string>("City")
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<string>("Country")
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("CreditDays")
.HasColumnType("integer");
b.Property<decimal>("CreditLimit")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<string>("CustomerCode")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("CustomerType")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("B2C");
b.Property<int?>("DefaultWarehouseId")
.HasColumnType("integer");
b.Property<string>("DisplayName")
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<string>("Email")
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<string>("Phone")
.HasMaxLength(30)
.HasColumnType("character varying(30)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Active");
b.Property<string>("TaxRegistrationNo")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("CustomerId");
b.HasIndex("CustomerCode")
.IsUnique();
b.HasIndex("CustomerType");
b.HasIndex("DefaultWarehouseId");
b.HasIndex("Status");
b.ToTable("customers", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Department", b =>
{
b.Property<int>("DepartmentId")
@@ -3302,6 +3402,406 @@ namespace ERPCore.Infra.Persistence.Migrations
b.ToTable("hr_salary_components", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoice", b =>
{
b.Property<int>("SalesInvoiceId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("SalesInvoiceId"));
b.Property<decimal>("BalanceAmount")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("CreatedBy")
.HasColumnType("integer");
b.Property<int?>("CreatorUserId")
.HasColumnType("integer");
b.Property<int>("CustomerId")
.HasColumnType("integer");
b.Property<string>("CustomerSnapshotName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<string>("CustomerSnapshotTaxNo")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<decimal>("DiscountTotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("GrandTotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<DateTime>("InvoiceDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("InvoiceNo")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("InvoiceType")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("B2C");
b.Property<decimal>("NetPayable")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("PaidAmount")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("RoundOff")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Draft");
b.Property<decimal>("Subtotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("TaxTotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("WarehouseId")
.HasColumnType("integer");
b.HasKey("SalesInvoiceId");
b.HasIndex("CreatorUserId");
b.HasIndex("CustomerId");
b.HasIndex("InvoiceDate");
b.HasIndex("InvoiceNo")
.IsUnique();
b.HasIndex("Status");
b.HasIndex("WarehouseId");
b.ToTable("sales_invoices", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoiceLine", b =>
{
b.Property<int>("SalesInvoiceLineId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("SalesInvoiceLineId"));
b.Property<decimal>("BaseCost")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<string>("Description")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<decimal>("DiscountAmount")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<int>("DiscountMode")
.HasColumnType("integer");
b.Property<decimal>("DiscountPct")
.HasPrecision(9, 4)
.HasColumnType("numeric(9,4)");
b.Property<decimal>("FreeQty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<bool>("IsFreeIssue")
.HasColumnType("boolean");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<decimal>("LineTotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("NetUnitPrice")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<int?>("ParentLineId")
.HasColumnType("integer");
b.Property<string>("PriceSource")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<decimal>("Qty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<int>("SalesInvoiceId")
.HasColumnType("integer");
b.Property<decimal>("TaxAmount")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("TaxPct")
.HasPrecision(9, 4)
.HasColumnType("numeric(9,4)");
b.Property<decimal>("UnitPrice")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<int>("UomId")
.HasColumnType("integer");
b.Property<int>("WarehouseId")
.HasColumnType("integer");
b.HasKey("SalesInvoiceLineId");
b.HasIndex("ItemId");
b.HasIndex("SalesInvoiceId");
b.HasIndex("UomId");
b.HasIndex("WarehouseId");
b.ToTable("sales_invoice_lines", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesSlip", b =>
{
b.Property<int>("SalesSlipId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("SalesSlipId"));
b.Property<decimal>("BalanceAmount")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<int>("CashierUserId")
.HasColumnType("integer");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("CustomerId")
.HasColumnType("integer");
b.Property<string>("CustomerSnapshotName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<decimal>("DiscountTotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("GrandTotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("PaidAmount")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<DateTime>("SlipDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("SlipNo")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Draft");
b.Property<decimal>("Subtotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("TaxTotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("WarehouseId")
.HasColumnType("integer");
b.HasKey("SalesSlipId");
b.HasIndex("CashierUserId");
b.HasIndex("CustomerId");
b.HasIndex("SlipDate");
b.HasIndex("SlipNo")
.IsUnique();
b.HasIndex("Status");
b.HasIndex("WarehouseId");
b.ToTable("sales_slips", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesSlipLine", b =>
{
b.Property<int>("SalesSlipLineId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("SalesSlipLineId"));
b.Property<decimal>("BaseCost")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<string>("Description")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<decimal>("DiscountAmount")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<int>("DiscountMode")
.HasColumnType("integer");
b.Property<decimal>("DiscountPct")
.HasPrecision(9, 4)
.HasColumnType("numeric(9,4)");
b.Property<decimal>("FreeQty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<bool>("IsFreeIssue")
.HasColumnType("boolean");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<decimal>("LineTotal")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("NetUnitPrice")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<int?>("ParentLineId")
.HasColumnType("integer");
b.Property<string>("PriceSource")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<decimal>("Qty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<int>("SalesSlipId")
.HasColumnType("integer");
b.Property<decimal>("TaxAmount")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("TaxPct")
.HasPrecision(9, 4)
.HasColumnType("numeric(9,4)");
b.Property<decimal>("UnitPrice")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<int>("UomId")
.HasColumnType("integer");
b.Property<int>("WarehouseId")
.HasColumnType("integer");
b.HasKey("SalesSlipLineId");
b.HasIndex("ItemId");
b.HasIndex("SalesSlipId");
b.HasIndex("UomId");
b.HasIndex("WarehouseId");
b.ToTable("sales_slip_lines", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Serial", b =>
{
b.Property<int>("SerialId")
@@ -4649,6 +5149,16 @@ namespace ERPCore.Infra.Persistence.Migrations
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Customer", b =>
{
b.HasOne("ERPCore.Domain.Entities.Warehouse", "DefaultWarehouse")
.WithMany()
.HasForeignKey("DefaultWarehouseId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("DefaultWarehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Department", b =>
{
b.HasOne("ERPCore.Domain.Entities.Branch", "Branch")
@@ -5472,6 +5982,128 @@ namespace ERPCore.Infra.Persistence.Migrations
b.Navigation("Uom");
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoice", b =>
{
b.HasOne("ERPCore.Domain.Entities.User", "Creator")
.WithMany()
.HasForeignKey("CreatorUserId");
b.HasOne("ERPCore.Domain.Entities.Customer", "Customer")
.WithMany()
.HasForeignKey("CustomerId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany()
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Creator");
b.Navigation("Customer");
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoiceLine", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany()
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.SalesInvoice", "SalesInvoice")
.WithMany("Lines")
.HasForeignKey("SalesInvoiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Uom", "Uom")
.WithMany()
.HasForeignKey("UomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany()
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Item");
b.Navigation("SalesInvoice");
b.Navigation("Uom");
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesSlip", b =>
{
b.HasOne("ERPCore.Domain.Entities.User", "CashierUser")
.WithMany()
.HasForeignKey("CashierUserId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Customer", "Customer")
.WithMany()
.HasForeignKey("CustomerId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany()
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("CashierUser");
b.Navigation("Customer");
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesSlipLine", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany()
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.SalesSlip", "SalesSlip")
.WithMany("Lines")
.HasForeignKey("SalesSlipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Uom", "Uom")
.WithMany()
.HasForeignKey("UomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany()
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Item");
b.Navigation("SalesSlip");
b.Navigation("Uom");
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Serial", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
@@ -6014,6 +6646,16 @@ namespace ERPCore.Infra.Persistence.Migrations
b.Navigation("Outputs");
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoice", b =>
{
b.Navigation("Lines");
});
modelBuilder.Entity("ERPCore.Domain.Entities.SalesSlip", b =>
{
b.Navigation("Lines");
});
modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustment", b =>
{
b.Navigation("Lines");