diff --git a/Backend/ERPCore/Controllers/BundleSalesController.cs b/Backend/ERPCore/Controllers/BundleSalesController.cs new file mode 100644 index 0000000..6b45382 --- /dev/null +++ b/Backend/ERPCore/Controllers/BundleSalesController.cs @@ -0,0 +1,79 @@ +using ERPCore.Domain.Enums; +using ERPCore.Dtos.Common; +using ERPCore.Dtos.Sales; +using ERPCore.Services.Interfaces; +using Microsoft.AspNetCore.Mvc; + +namespace ERPCore.Controllers; + +[Route("api/v1/bundle-sales")] +public sealed class BundleSalesController : ApiControllerBase +{ + private readonly IBundleSaleService _bundles; + + public BundleSalesController(IBundleSaleService bundles) => _bundles = bundles; + + [HttpGet("templates")] + [ProducesResponseType(typeof(PagedResponse), StatusCodes.Status200OK)] + public async Task>> ListTemplates( + [FromQuery] PageQuery query, + CancellationToken ct) + => Ok(await _bundles.ListTemplatesAsync(query, ct)); + + [HttpGet("templates/{bundleSaleTemplateId:int}")] + [ProducesResponseType(typeof(BundleSaleTemplateDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> GetTemplate(int bundleSaleTemplateId, CancellationToken ct) + { + var result = await _bundles.GetTemplateAsync(bundleSaleTemplateId, ct); + return result is null ? NotFound() : Ok(result); + } + + [HttpGet] + [ProducesResponseType(typeof(PagedResponse), StatusCodes.Status200OK)] + public async Task>> List( + [FromQuery] PageQuery query, + [FromQuery] int? customerId, + [FromQuery] int? warehouseId, + CancellationToken ct) + => Ok(await _bundles.ListAsync(query, customerId, warehouseId, ct)); + + [HttpGet("{bundleSaleId:int}")] + [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> GetById(int bundleSaleId, CancellationToken ct) + { + var result = await _bundles.GetAsync(bundleSaleId, ct); + return result is null ? NotFound() : Ok(result); + } + + [HttpGet("{bundleSaleId:int}/posting-check")] + [ProducesResponseType(typeof(BundleSalePostingCheckDto), StatusCodes.Status200OK)] + public async Task> PostingCheck(int bundleSaleId, CancellationToken ct) + => Ok(await _bundles.CheckPostingAsync(bundleSaleId, ct)); + + [HttpPost] + [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status201Created)] + public async Task> Create([FromBody] CreateBundleSaleRequest request, CancellationToken ct) + { + var result = await _bundles.CreateAsync(request, ct); + return Created($"/api/v1/bundle-sales/{result.BundleSaleId}", result); + } + + [HttpPut("{bundleSaleId:int}")] + [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status200OK)] + public async Task> Update(int bundleSaleId, [FromBody] UpdateBundleSaleRequest request, CancellationToken ct) + { + return Ok(await _bundles.UpdateAsync(bundleSaleId, request, ct)); + } + + [HttpPost("{bundleSaleId:int}/post")] + [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status200OK)] + public async Task> Post(int bundleSaleId, CancellationToken ct) + => Ok(await _bundles.PostAsync(bundleSaleId, ct)); + + [HttpPost("{bundleSaleId:int}/cancel")] + [ProducesResponseType(typeof(BundleSaleDto), StatusCodes.Status200OK)] + public async Task> Cancel(int bundleSaleId, CancellationToken ct) + => Ok(await _bundles.CancelAsync(bundleSaleId, ct)); +} diff --git a/Backend/ERPCore/Domain/DocumentTypes.cs b/Backend/ERPCore/Domain/DocumentTypes.cs index 4e1f4ee..cbd91da 100644 --- a/Backend/ERPCore/Domain/DocumentTypes.cs +++ b/Backend/ERPCore/Domain/DocumentTypes.cs @@ -19,4 +19,5 @@ public static class DocumentTypes public const string Production = "PRD"; public const string SalesInvoice = "SI"; public const string SalesSlip = "SSL"; + public const string BundleSale = "BND"; } diff --git a/Backend/ERPCore/Domain/Entities/BundleSale.cs b/Backend/ERPCore/Domain/Entities/BundleSale.cs new file mode 100644 index 0000000..3129935 --- /dev/null +++ b/Backend/ERPCore/Domain/Entities/BundleSale.cs @@ -0,0 +1,33 @@ +using ERPCore.Domain.Enums; + +namespace ERPCore.Domain.Entities; + +public class BundleSale +{ + public int BundleSaleId { get; set; } + public string BundleNo { get; set; } = string.Empty; + public DateTime BundleDate { get; set; } + public int CustomerId { get; set; } + public Customer? Customer { get; set; } + public string CustomerSnapshotName { get; set; } = string.Empty; + public int WarehouseId { get; set; } + public Warehouse? Warehouse { get; set; } + public int CashierUserId { get; set; } + public User? CashierUser { get; set; } + public int BundleSaleTemplateId { get; set; } + public BundleSaleTemplate? BundleSaleTemplate { get; set; } + public string BundleName { get; set; } = string.Empty; + public string BundleCode { get; set; } = string.Empty; + public BundleSaleStatus Status { get; set; } = BundleSaleStatus.Draft; + public decimal ComponentSubtotal { get; set; } + public decimal BundlePrice { get; set; } + public decimal MarginAmount { get; set; } + public decimal DiscountTotal { get; set; } + public decimal TaxTotal { get; set; } + public decimal GrandTotal { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } + public int ConcurrencyStamp { get; set; } + + public ICollection Lines { get; set; } = new List(); +} diff --git a/Backend/ERPCore/Domain/Entities/BundleSaleLine.cs b/Backend/ERPCore/Domain/Entities/BundleSaleLine.cs new file mode 100644 index 0000000..fecf7ef --- /dev/null +++ b/Backend/ERPCore/Domain/Entities/BundleSaleLine.cs @@ -0,0 +1,24 @@ +using ERPCore.Domain.Enums; + +namespace ERPCore.Domain.Entities; + +public class BundleSaleLine +{ + public int BundleSaleLineId { get; set; } + public int BundleSaleId { get; set; } + public BundleSale? BundleSale { get; set; } + + public int ItemId { get; set; } + public Item? Item { get; set; } + public string Description { get; set; } = string.Empty; + public decimal Qty { get; set; } + public int UomId { get; set; } + public Uom? Uom { get; set; } + public int WarehouseId { get; set; } + public Warehouse? Warehouse { get; set; } + public decimal UnitPrice { get; set; } + public decimal LineTotal { get; set; } + public bool IncludeInBundle { get; set; } = true; + public bool IsComponent { get; set; } = true; + public int? ParentLineId { get; set; } +} diff --git a/Backend/ERPCore/Domain/Entities/BundleSaleTemplate.cs b/Backend/ERPCore/Domain/Entities/BundleSaleTemplate.cs new file mode 100644 index 0000000..0343a23 --- /dev/null +++ b/Backend/ERPCore/Domain/Entities/BundleSaleTemplate.cs @@ -0,0 +1,17 @@ +using ERPCore.Domain.Enums; + +namespace ERPCore.Domain.Entities; + +public class BundleSaleTemplate +{ + public int BundleSaleTemplateId { get; set; } + public string TemplateCode { get; set; } = string.Empty; + public string TemplateName { get; set; } = string.Empty; + public string? Description { get; set; } + public EntityStatus Status { get; set; } = EntityStatus.Active; + public DateTime CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } + public int ConcurrencyStamp { get; set; } + + public ICollection Lines { get; set; } = new List(); +} diff --git a/Backend/ERPCore/Domain/Entities/BundleSaleTemplateLine.cs b/Backend/ERPCore/Domain/Entities/BundleSaleTemplateLine.cs new file mode 100644 index 0000000..e41414b --- /dev/null +++ b/Backend/ERPCore/Domain/Entities/BundleSaleTemplateLine.cs @@ -0,0 +1,20 @@ +namespace ERPCore.Domain.Entities; + +public class BundleSaleTemplateLine +{ + public int BundleSaleTemplateLineId { get; set; } + public int BundleSaleTemplateId { get; set; } + public BundleSaleTemplate? BundleSaleTemplate { get; set; } + + public int ItemId { get; set; } + public Item? Item { get; set; } + public int UomId { get; set; } + public Uom? Uom { get; set; } + public int WarehouseId { get; set; } + public Warehouse? Warehouse { get; set; } + + public decimal Qty { get; set; } + public decimal UnitPrice { get; set; } + public bool IncludeInBundle { get; set; } = true; + public int SortOrder { get; set; } +} diff --git a/Backend/ERPCore/Domain/Enums/BundleSaleStatus.cs b/Backend/ERPCore/Domain/Enums/BundleSaleStatus.cs new file mode 100644 index 0000000..a17d0eb --- /dev/null +++ b/Backend/ERPCore/Domain/Enums/BundleSaleStatus.cs @@ -0,0 +1,8 @@ +namespace ERPCore.Domain.Enums; + +public enum BundleSaleStatus +{ + Draft = 0, + Posted = 1, + Cancelled = 2 +} diff --git a/Backend/ERPCore/Dtos/Sales/BundleSaleDtos.cs b/Backend/ERPCore/Dtos/Sales/BundleSaleDtos.cs new file mode 100644 index 0000000..7d14af7 --- /dev/null +++ b/Backend/ERPCore/Dtos/Sales/BundleSaleDtos.cs @@ -0,0 +1,83 @@ +using System.ComponentModel.DataAnnotations; +using ERPCore.Domain.Enums; + +namespace ERPCore.Dtos.Sales; + +public sealed record BundleSaleLineDto( + int BundleSaleLineId, int ItemId, string Description, decimal Qty, int UomId, int WarehouseId, + decimal UnitPrice, decimal LineTotal, bool IncludeInBundle, bool IsComponent, int? ParentLineId); + +public sealed record BundleSaleDto( + int BundleSaleId, string BundleNo, DateTime BundleDate, int CustomerId, string CustomerSnapshotName, + int WarehouseId, int CashierUserId, int BundleSaleTemplateId, string BundleName, string BundleCode, + BundleSaleStatus Status, decimal ComponentSubtotal, decimal BundlePrice, decimal MarginAmount, + decimal DiscountTotal, decimal TaxTotal, decimal GrandTotal, DateTime CreatedAt, DateTime? UpdatedAt, + IReadOnlyList Lines); + +public sealed record BundleSaleSummaryDto( + int BundleSaleId, string BundleNo, DateTime BundleDate, int CustomerId, string CustomerSnapshotName, + int WarehouseId, string BundleName, string BundleCode, BundleSaleStatus Status, + decimal ComponentSubtotal, decimal BundlePrice, decimal GrandTotal, DateTime CreatedAt); + +public sealed record BundleSaleTemplateLineDto( + int BundleSaleTemplateLineId, int ItemId, int UomId, int WarehouseId, decimal Qty, + decimal UnitPrice, bool IncludeInBundle, int SortOrder); + +public sealed record BundleSaleTemplateDto( + int BundleSaleTemplateId, string TemplateCode, string TemplateName, string? Description, + EntityStatus Status, DateTime CreatedAt, DateTime? UpdatedAt, IReadOnlyList Lines); + +public sealed record BundleSaleTemplateSummaryDto( + int BundleSaleTemplateId, string TemplateCode, string TemplateName, string? Description, + EntityStatus Status, int LineCount, DateTime CreatedAt, DateTime? UpdatedAt); + +public sealed record BundleSalePostingIssueDto( + int BundleSaleLineId, int ItemId, string ItemSku, string ItemName, int WarehouseId, + decimal RequestedQty, decimal AvailableQty, decimal ShortQty); + +public sealed record BundleSalePostingCheckDto( + int BundleSaleId, string BundleNo, BundleSaleStatus Status, bool CanPost, + IReadOnlyList Issues); + +public sealed class CreateBundleSaleTemplateLineRequest +{ + [Required] public int ItemId { get; set; } + [Required] public int UomId { get; set; } + [Required] public int WarehouseId { get; set; } + [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; } + [Range(0, double.MaxValue)] public decimal UnitPrice { get; set; } + public bool IncludeInBundle { get; set; } = true; + public int SortOrder { get; set; } +} + +public sealed class CreateBundleSaleTemplateRequest +{ + [Required] public string TemplateCode { get; set; } = string.Empty; + [Required] public string TemplateName { get; set; } = string.Empty; + public string? Description { get; set; } + [Required, MinLength(1)] public List Lines { get; set; } = new(); +} + +public sealed class CreateBundleSaleRequest +{ + [Required] public int CustomerId { get; set; } + [Required] public int WarehouseId { get; set; } + [Required] public int CashierUserId { get; set; } + [Required] public int BundleSaleTemplateId { get; set; } + [Required] public string BundleName { get; set; } = string.Empty; + [Range(0, double.MaxValue)] public decimal BundlePrice { get; set; } + public bool AllowPriceOverride { get; set; } + [Required, MinLength(1)] public List Lines { get; set; } = new(); +} + +public sealed class UpdateBundleSaleRequest +{ + [Required] public int CustomerId { get; set; } + [Required] public int WarehouseId { get; set; } + [Required] public int CashierUserId { get; set; } + [Required] public int BundleSaleTemplateId { get; set; } + [Required] public string BundleName { get; set; } = string.Empty; + [Range(0, double.MaxValue)] public decimal BundlePrice { get; set; } + public bool AllowPriceOverride { get; set; } + [Required, MinLength(1)] public List Lines { get; set; } = new(); +} diff --git a/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleConfiguration.cs b/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleConfiguration.cs new file mode 100644 index 0000000..d53b314 --- /dev/null +++ b/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleConfiguration.cs @@ -0,0 +1,46 @@ +using ERPCore.Domain.Entities; +using ERPCore.Domain.Enums; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace ERPCore.Infra.Persistence.Configurations; + +public sealed class BundleSaleConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("bundle_sales"); + builder.HasKey(x => x.BundleSaleId); + builder.Property(x => x.BundleNo).IsRequired().HasMaxLength(50); + builder.HasIndex(x => x.BundleNo).IsUnique(); + builder.Property(x => x.BundleDate).IsRequired(); + builder.Property(x => x.CustomerSnapshotName).IsRequired().HasMaxLength(200); + builder.Property(x => x.BundleName).IsRequired().HasMaxLength(200); + builder.Property(x => x.BundleCode).IsRequired().HasMaxLength(50); + builder.Property(x => x.Status) + .HasConversion().HasMaxLength(20).IsRequired() + .HasDefaultValue(BundleSaleStatus.Draft); + builder.Property(x => x.ComponentSubtotal).HasPrecision(18, 4); + builder.Property(x => x.BundlePrice).HasPrecision(18, 4); + builder.Property(x => x.MarginAmount).HasPrecision(18, 4); + builder.Property(x => x.DiscountTotal).HasPrecision(18, 4); + builder.Property(x => x.TaxTotal).HasPrecision(18, 4); + builder.Property(x => x.GrandTotal).HasPrecision(18, 4); + builder.Property(x => x.CreatedAt).IsRequired(); + builder.Property(x => x.ConcurrencyStamp) + .IsRequired() + .HasColumnType("integer") + .HasDefaultValue(0) + .IsConcurrencyToken(); + + builder.HasOne(x => x.Customer).WithMany().HasForeignKey(x => x.CustomerId).OnDelete(DeleteBehavior.Restrict); + 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.HasOne(x => x.BundleSaleTemplate).WithMany().HasForeignKey(x => x.BundleSaleTemplateId).OnDelete(DeleteBehavior.Restrict); + + builder.HasMany(x => x.Lines) + .WithOne(x => x.BundleSale) + .HasForeignKey(x => x.BundleSaleId) + .OnDelete(DeleteBehavior.Cascade); + } +} diff --git a/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleLineConfiguration.cs b/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleLineConfiguration.cs new file mode 100644 index 0000000..fac3e88 --- /dev/null +++ b/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleLineConfiguration.cs @@ -0,0 +1,24 @@ +using ERPCore.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace ERPCore.Infra.Persistence.Configurations; + +public sealed class BundleSaleLineConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("bundle_sale_lines"); + builder.HasKey(x => x.BundleSaleLineId); + builder.Property(x => x.Description).IsRequired().HasMaxLength(200); + builder.Property(x => x.Qty).HasPrecision(18, 4); + builder.Property(x => x.UnitPrice).HasPrecision(18, 4); + builder.Property(x => x.LineTotal).HasPrecision(18, 4); + builder.Property(x => x.IncludeInBundle).HasDefaultValue(true); + builder.Property(x => x.IsComponent).HasDefaultValue(true); + + builder.HasOne(x => x.Item).WithMany().HasForeignKey(x => x.ItemId).OnDelete(DeleteBehavior.Restrict); + 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); + } +} diff --git a/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleTemplateConfiguration.cs b/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleTemplateConfiguration.cs new file mode 100644 index 0000000..e580e08 --- /dev/null +++ b/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleTemplateConfiguration.cs @@ -0,0 +1,34 @@ +using ERPCore.Domain.Entities; +using ERPCore.Domain.Enums; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace ERPCore.Infra.Persistence.Configurations; + +public sealed class BundleSaleTemplateConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("bundle_sale_templates"); + builder.HasKey(x => x.BundleSaleTemplateId); + + builder.Property(x => x.TemplateCode).IsRequired().HasMaxLength(50); + builder.HasIndex(x => x.TemplateCode).IsUnique(); + builder.Property(x => x.TemplateName).IsRequired().HasMaxLength(200); + builder.Property(x => x.Description).HasMaxLength(1000); + builder.Property(x => x.Status) + .HasConversion().HasMaxLength(20).IsRequired() + .HasDefaultValue(EntityStatus.Active); + builder.Property(x => x.CreatedAt).IsRequired(); + builder.Property(x => x.ConcurrencyStamp) + .IsRequired() + .HasColumnType("integer") + .HasDefaultValue(0) + .IsConcurrencyToken(); + + builder.HasMany(x => x.Lines) + .WithOne(x => x.BundleSaleTemplate) + .HasForeignKey(x => x.BundleSaleTemplateId) + .OnDelete(DeleteBehavior.Cascade); + } +} diff --git a/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleTemplateLineConfiguration.cs b/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleTemplateLineConfiguration.cs new file mode 100644 index 0000000..113647e --- /dev/null +++ b/Backend/ERPCore/Infra/Persistence/Configurations/BundleSaleTemplateLineConfiguration.cs @@ -0,0 +1,21 @@ +using ERPCore.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace ERPCore.Infra.Persistence.Configurations; + +public sealed class BundleSaleTemplateLineConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("bundle_sale_template_lines"); + builder.HasKey(x => x.BundleSaleTemplateLineId); + builder.Property(x => x.Qty).HasPrecision(18, 4); + builder.Property(x => x.UnitPrice).HasPrecision(18, 4); + builder.Property(x => x.SortOrder).HasDefaultValue(0); + + builder.HasOne(x => x.Item).WithMany().HasForeignKey(x => x.ItemId).OnDelete(DeleteBehavior.Restrict); + 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); + } +} diff --git a/Backend/ERPCore/Infra/Persistence/Configurations/NavItemConfiguration.cs b/Backend/ERPCore/Infra/Persistence/Configurations/NavItemConfiguration.cs index 4db1434..afc2771 100644 --- a/Backend/ERPCore/Infra/Persistence/Configurations/NavItemConfiguration.cs +++ b/Backend/ERPCore/Infra/Persistence/Configurations/NavItemConfiguration.cs @@ -38,7 +38,8 @@ public sealed class NavItemConfiguration : IEntityTypeConfiguration new NavItem { NavItemId = 9, Code = "settings", Label = "Settings", Href = "/dashboard/settings", SortOrder = 9 }, new NavItem { NavItemId = 10, Code = "help", Label = "Help", Href = "/dashboard/help", SortOrder = 10 }, new NavItem { NavItemId = 11, Code = "ledgers", Label = "Ledgers", Href = "/dashboard/ledgers", SortOrder = 11 }, - new NavItem { NavItemId = 12, Code = "accounts", Label = "Accounts", Href = "/dashboard/accounts", SortOrder = 12 } + new NavItem { NavItemId = 12, Code = "accounts", Label = "Accounts", Href = "/dashboard/accounts", SortOrder = 12 }, + new NavItem { NavItemId = 13, Code = "sales", Label = "Sales", Href = "/dashboard/sales", SortOrder = 13 } ); } } diff --git a/Backend/ERPCore/Infra/Persistence/Configurations/SubNavItemConfiguration.cs b/Backend/ERPCore/Infra/Persistence/Configurations/SubNavItemConfiguration.cs index 42e5b04..4282211 100644 --- a/Backend/ERPCore/Infra/Persistence/Configurations/SubNavItemConfiguration.cs +++ b/Backend/ERPCore/Infra/Persistence/Configurations/SubNavItemConfiguration.cs @@ -33,6 +33,7 @@ public sealed class SubNavItemConfiguration : IEntityTypeConfiguration - private static async Task SeedCompanyProfileAsync(ErpDbContext db, CancellationToken ct) - { - if (await db.CompanyProfiles.AnyAsync(c => c.CompanyProfileId == CompanyProfile.SingletonId, ct)) return false; + //private static async Task SeedCompanyProfileAsync(ErpDbContext db, CancellationToken ct) + //{ + // if (await db.CompanyProfiles.AnyAsync(c => c.CompanyProfileId == CompanyProfile.SingletonId, ct)) return false; - db.CompanyProfiles.Add(new CompanyProfile - { - CompanyProfileId = CompanyProfile.SingletonId, - LegalName = "ERP Core Trading (Pvt) Ltd", - TradeName = "ERP Core Trading", - TaxRegistrationNo = "TAX-DEFAULT-001", - VatRegistrationNo = "VAT-DEFAULT-001", - AddressLine1 = "1 Demo Street", - City = "Colombo", - Country = "Sri Lanka", - Phone = "+94 11 000 0000", - Email = "accounts@example.com", - BankName = "Demo Bank", - BankBranch = "Colombo Main", - AccountName = "ERP Core Trading (Pvt) Ltd", - AccountNumber = "000123456789", - SwiftCode = "DEMO1234", - FooterNote = "Thank you for your business." - }); - return true; - } + // db.CompanyProfiles.Add(new CompanyProfile + // { + // CompanyProfileId = CompanyProfile.SingletonId, + // LegalName = "ERP Core Trading (Pvt) Ltd", + // TradeName = "ERP Core Trading", + // TaxRegistrationNo = "TAX-DEFAULT-001", + // VatRegistrationNo = "VAT-DEFAULT-001", + // AddressLine1 = "1 Demo Street", + // City = "Colombo", + // Country = "Sri Lanka", + // Phone = "+94 11 000 0000", + // Email = "accounts@example.com", + // BankName = "Demo Bank", + // BankBranch = "Colombo Main", + // AccountName = "ERP Core Trading (Pvt) Ltd", + // AccountNumber = "000123456789", + // SwiftCode = "DEMO1234", + // FooterNote = "Thank you for your business." + // }); + // return true; + //} /// /// Seeds the minimum catalog data required for the sales demo rows to exist. @@ -318,6 +318,15 @@ public static class DataSeeder dirty |= await SeedSalesSequencesAsync(db, ct); dirty |= await SeedSampleSalesDocsAsync(db, ct); + try + { + dirty |= await SeedBundleSalesAsync(db, ct); + } + catch + { + // Bundle demo data is best-effort only; never block startup because of seed drift. + } + return dirty; } @@ -369,7 +378,7 @@ public static class DataSeeder { var year = DateTime.UtcNow.Year; var existing = await db.NumberSequences - .Where(s => s.Year == year && (s.DocType == DocumentTypes.SalesInvoice || s.DocType == DocumentTypes.SalesSlip)) + .Where(s => s.Year == year && (s.DocType == DocumentTypes.SalesInvoice || s.DocType == DocumentTypes.SalesSlip || s.DocType == DocumentTypes.BundleSale)) .Select(s => s.DocType) .ToListAsync(ct); var have = existing.ToHashSet(StringComparer.OrdinalIgnoreCase); @@ -377,7 +386,8 @@ public static class DataSeeder var seeds = new[] { new NumberSequence { DocType = DocumentTypes.SalesInvoice, Year = year, LastNumber = 0 }, - new NumberSequence { DocType = DocumentTypes.SalesSlip, Year = year, LastNumber = 0 } + new NumberSequence { DocType = DocumentTypes.SalesSlip, Year = year, LastNumber = 0 }, + new NumberSequence { DocType = DocumentTypes.BundleSale, Year = year, LastNumber = 0 } }; var toAdd = seeds.Where(s => !have.Contains(s.DocType)).ToList(); @@ -387,6 +397,209 @@ public static class DataSeeder return true; } + private static async Task SeedBundleSalesAsync(ErpDbContext db, CancellationToken ct) + { + if (await db.BundleSaleTemplates.AnyAsync(ct) || await db.BundleSales.AnyAsync(ct)) + return false; + + var customer = await db.Customers.AsNoTracking() + .OrderBy(c => c.CustomerId) + .FirstOrDefaultAsync(ct); + var warehouse = await db.Warehouses.AsNoTracking() + .OrderBy(w => w.WarehouseId) + .FirstOrDefaultAsync(ct); + var secondaryWarehouse = await db.Warehouses.AsNoTracking() + .OrderByDescending(w => w.WarehouseId) + .FirstOrDefaultAsync(ct); + var items = await db.Items.AsNoTracking() + .OrderBy(i => i.ItemId) + .Take(2) + .ToListAsync(ct); + var uom = await db.Uoms.AsNoTracking() + .OrderBy(u => u.UomId) + .FirstOrDefaultAsync(ct); + var user = await db.Users.AsNoTracking() + .OrderBy(u => u.UserId) + .FirstOrDefaultAsync(ct); + + if (customer is null || warehouse is null || secondaryWarehouse is null || items.Count < 2 || uom is null || user is null) + return false; + + var now = DateTime.UtcNow; + var template = new BundleSaleTemplate + { + TemplateCode = "BND-DEMO-001", + TemplateName = "Demo Bundle Pack", + Description = "Seeded fixed bundle template for integration testing", + Status = EntityStatus.Active, + CreatedAt = now, + Lines = + [ + new BundleSaleTemplateLine + { + ItemId = items[0].ItemId, + UomId = uom.UomId, + WarehouseId = warehouse.WarehouseId, + Qty = 1m, + UnitPrice = items[0].SalePrice.GetValueOrDefault(), + IncludeInBundle = true, + SortOrder = 1 + }, + new BundleSaleTemplateLine + { + ItemId = items[1].ItemId, + UomId = uom.UomId, + WarehouseId = warehouse.WarehouseId, + Qty = 1m, + UnitPrice = items[1].SalePrice.GetValueOrDefault(), + IncludeInBundle = true, + SortOrder = 2 + } + ] + }; + + db.BundleSaleTemplates.Add(template); + await db.SaveChangesAsync(ct); + + var bundleSales = new[] + { + new BundleSale + { + BundleNo = $"BND-{now:yyyy}-00001", + BundleDate = now.Date.AddDays(-2), + CustomerId = customer.CustomerId, + CustomerSnapshotName = customer.DisplayName ?? customer.Name, + WarehouseId = warehouse.WarehouseId, + CashierUserId = user.UserId, + BundleSaleTemplateId = template.BundleSaleTemplateId, + BundleName = "Demo Bundle Draft", + BundleCode = "BND-DEMO-001", + Status = BundleSaleStatus.Draft, + ComponentSubtotal = items[0].SalePrice.GetValueOrDefault() + items[1].SalePrice.GetValueOrDefault(), + BundlePrice = 0m, + MarginAmount = -(items[0].SalePrice.GetValueOrDefault() + items[1].SalePrice.GetValueOrDefault()), + DiscountTotal = items[0].SalePrice.GetValueOrDefault() + items[1].SalePrice.GetValueOrDefault(), + TaxTotal = 0m, + GrandTotal = 0m, + CreatedAt = now.AddDays(-2), + Lines = + [ + new BundleSaleLine + { + ItemId = items[0].ItemId, + Description = items[0].Name, + Qty = 1m, + UomId = uom.UomId, + WarehouseId = warehouse.WarehouseId, + UnitPrice = items[0].SalePrice.GetValueOrDefault(), + LineTotal = items[0].SalePrice.GetValueOrDefault(), + IncludeInBundle = true, + IsComponent = true + }, + new BundleSaleLine + { + ItemId = items[1].ItemId, + Description = items[1].Name, + Qty = 1m, + UomId = uom.UomId, + WarehouseId = warehouse.WarehouseId, + UnitPrice = items[1].SalePrice.GetValueOrDefault(), + LineTotal = items[1].SalePrice.GetValueOrDefault(), + IncludeInBundle = true, + IsComponent = true + } + ] + }, + new BundleSale + { + BundleNo = $"BND-{now:yyyy}-00002", + BundleDate = now.Date.AddDays(-1), + CustomerId = customer.CustomerId, + CustomerSnapshotName = customer.DisplayName ?? customer.Name, + WarehouseId = warehouse.WarehouseId, + CashierUserId = user.UserId, + BundleSaleTemplateId = template.BundleSaleTemplateId, + BundleName = "Demo Bundle Posted", + BundleCode = "BND-DEMO-001", + Status = BundleSaleStatus.Posted, + ComponentSubtotal = items[0].SalePrice.GetValueOrDefault() + items[1].SalePrice.GetValueOrDefault(), + BundlePrice = (items[0].SalePrice.GetValueOrDefault() + items[1].SalePrice.GetValueOrDefault()) - 10m, + MarginAmount = -10m, + DiscountTotal = 10m, + TaxTotal = 0m, + GrandTotal = (items[0].SalePrice.GetValueOrDefault() + items[1].SalePrice.GetValueOrDefault()) - 10m, + CreatedAt = now.AddDays(-1), + UpdatedAt = now.AddHours(-2), + Lines = + [ + new BundleSaleLine + { + ItemId = items[0].ItemId, + Description = items[0].Name, + Qty = 1m, + UomId = uom.UomId, + WarehouseId = warehouse.WarehouseId, + UnitPrice = items[0].SalePrice.GetValueOrDefault(), + LineTotal = items[0].SalePrice.GetValueOrDefault(), + IncludeInBundle = true, + IsComponent = true + }, + new BundleSaleLine + { + ItemId = items[1].ItemId, + Description = items[1].Name, + Qty = 1m, + UomId = uom.UomId, + WarehouseId = warehouse.WarehouseId, + UnitPrice = items[1].SalePrice.GetValueOrDefault(), + LineTotal = items[1].SalePrice.GetValueOrDefault(), + IncludeInBundle = true, + IsComponent = true + } + ] + }, + new BundleSale + { + BundleNo = $"BND-{now:yyyy}-00003", + BundleDate = now.Date, + CustomerId = customer.CustomerId, + CustomerSnapshotName = customer.DisplayName ?? customer.Name, + WarehouseId = secondaryWarehouse.WarehouseId, + CashierUserId = user.UserId, + BundleSaleTemplateId = template.BundleSaleTemplateId, + BundleName = "Demo Bundle Cancelled", + BundleCode = "BND-DEMO-001", + Status = BundleSaleStatus.Cancelled, + ComponentSubtotal = items[0].SalePrice.GetValueOrDefault(), + BundlePrice = items[0].SalePrice.GetValueOrDefault(), + MarginAmount = 0m, + DiscountTotal = 0m, + TaxTotal = 0m, + GrandTotal = items[0].SalePrice.GetValueOrDefault(), + CreatedAt = now, + UpdatedAt = now, + Lines = + [ + new BundleSaleLine + { + ItemId = items[0].ItemId, + Description = items[0].Name, + Qty = 1m, + UomId = uom.UomId, + WarehouseId = secondaryWarehouse.WarehouseId, + UnitPrice = items[0].SalePrice.GetValueOrDefault(), + LineTotal = items[0].SalePrice.GetValueOrDefault(), + IncludeInBundle = true, + IsComponent = true + } + ] + } + }; + + db.BundleSales.AddRange(bundleSales); + return true; + } + private static async Task SeedSampleSalesDocsAsync(ErpDbContext db, CancellationToken ct) { if (await db.SalesInvoices.AnyAsync(ct) || await db.SalesSlips.AnyAsync(ct)) diff --git a/Backend/ERPCore/Infra/Persistence/ErpDbContext.cs b/Backend/ERPCore/Infra/Persistence/ErpDbContext.cs index c795331..556890c 100644 --- a/Backend/ERPCore/Infra/Persistence/ErpDbContext.cs +++ b/Backend/ERPCore/Infra/Persistence/ErpDbContext.cs @@ -90,6 +90,10 @@ public class ErpDbContext : DbContext public DbSet SalesInvoiceLines => Set(); public DbSet SalesSlips => Set(); public DbSet SalesSlipLines => Set(); + public DbSet BundleSaleTemplates => Set(); + public DbSet BundleSaleTemplateLines => Set(); + public DbSet BundleSales => Set(); + public DbSet BundleSaleLines => Set(); // --- Reference data (docs/10 Part C.7) --- public DbSet ReasonCodes => Set(); 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("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.Customer", b => - { - b.Property("CustomerId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("CustomerId")); - - b.Property("AddressLine1") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.Property("AddressLine2") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.Property("City") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Country") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreditDays") - .HasColumnType("integer"); - - b.Property("CreditLimit") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("CustomerCode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CustomerType") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("B2C"); - - b.Property("DefaultWarehouseId") - .HasColumnType("integer"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Email") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Phone") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("TaxRegistrationNo") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("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("DepartmentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("DepartmentId")); - - b.Property("BranchId") - .HasColumnType("integer"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("HeadEmployeeId") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("ParentDepartmentId") - .HasColumnType("integer"); - - 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("DepartmentId"); - - b.HasIndex("BranchId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("HeadEmployeeId"); - - b.HasIndex("ParentDepartmentId"); - - b.HasIndex("Status"); - - b.ToTable("hr_departments", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Designation", b => - { - b.Property("DesignationId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("DesignationId")); - - 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("DesignationId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_designations", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Employee", b => - { - b.Property("EmployeeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeId")); - - b.Property("AddressLine1") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("AddressLine2") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("BranchId") - .HasColumnType("integer"); - - b.Property("City") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("ConfirmationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Country") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("DateOfBirth") - .HasColumnType("timestamp with time zone"); - - b.Property("DepartmentId") - .HasColumnType("integer"); - - b.Property("DesignationId") - .HasColumnType("integer"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("character varying(320)"); - - b.Property("EmergencyContactName") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("EmergencyContactPhone") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("EmergencyContactRelationship") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("EmployeeCode") - .IsRequired() - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("EmploymentTypeId") - .HasColumnType("integer"); - - b.Property("EpfNumber") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("EtfNumber") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("FullName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Gender") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("HireDate") - .HasColumnType("timestamp with time zone"); - - b.Property("LastWorkingDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Nationality") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Nic") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("PersonalMobile") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("PostalCode") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ProfilePhotoPath") - .HasMaxLength(500) - .HasColumnType("character varying(500)"); - - b.Property("ReportingManagerId") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("TaxIdentificationNumber") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("UpdatedBy") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("integer"); - - b.Property("WorkShiftId") - .HasColumnType("integer"); - - b.HasKey("EmployeeId"); - - b.HasIndex("BranchId"); - - b.HasIndex("DepartmentId"); - - b.HasIndex("DesignationId"); - - b.HasIndex("Email"); - - b.HasIndex("EmployeeCode") - .IsUnique(); - - b.HasIndex("EmploymentTypeId"); - - b.HasIndex("ReportingManagerId"); - - b.HasIndex("Status"); - - b.HasIndex("UserId") - .IsUnique(); - - b.HasIndex("WorkShiftId"); - - b.ToTable("hr_employees", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeBankDetail", b => - { - b.Property("EmployeeBankDetailId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeBankDetailId")); - - b.Property("AccountHolderName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("AccountNumber") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("BankName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("BranchName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("SwiftCode") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.HasKey("EmployeeBankDetailId"); - - b.HasIndex("EmployeeId"); - - b.ToTable("hr_employee_bank_details", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeDocument", b => - { - b.Property("EmployeeDocumentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeDocumentId")); - - b.Property("ContentType") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("ExpiryDate") - .HasColumnType("timestamp with time zone"); - - b.Property("HrDocumentTypeId") - .HasColumnType("integer"); - - b.Property("IssueDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Notes") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("OriginalFileName") - .IsRequired() - .HasMaxLength(260) - .HasColumnType("character varying(260)"); - - b.Property("RelativePath") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SizeBytes") - .HasColumnType("bigint"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("StoredFileName") - .IsRequired() - .HasMaxLength(260) - .HasColumnType("character varying(260)"); - - b.Property("UploadedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("UploadedBy") - .HasColumnType("integer"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("VerifiedBy") - .HasColumnType("integer"); - - b.HasKey("EmployeeDocumentId"); - - b.HasIndex("EmployeeId"); - - b.HasIndex("ExpiryDate"); - - b.HasIndex("HrDocumentTypeId"); - - b.ToTable("hr_employee_documents", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeLoan", b => - { - b.Property("EmployeeLoanId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeLoanId")); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedBy") - .HasColumnType("integer"); - - 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("EmployeeId") - .HasColumnType("integer"); - - b.Property("InstallmentAmount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("InterestRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("LoanKind") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("NumberOfInstallments") - .HasColumnType("integer"); - - b.Property("OutstandingBalance") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("PrincipalAmount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("StartMonth") - .HasColumnType("integer"); - - b.Property("StartYear") - .HasColumnType("integer"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("EmployeeLoanId"); - - b.HasIndex("DocNo") - .IsUnique(); - - b.HasIndex("EmployeeId"); - - b.HasIndex("Status"); - - b.ToTable("hr_employee_loans", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructure", b => - { - b.Property("EmployeeSalaryStructureId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeSalaryStructureId")); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedBy") - .HasColumnType("integer"); - - b.Property("BasicSalary") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("Currency") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("character varying(3)"); - - b.Property("EffectiveFrom") - .HasColumnType("timestamp with time zone"); - - b.Property("EffectiveTo") - .HasColumnType("timestamp with time zone"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("EmployeeSalaryStructureId"); - - b.HasIndex("EmployeeId", "EffectiveTo"); - - b.ToTable("hr_employee_salary_structures", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructureLine", b => - { - b.Property("EmployeeSalaryStructureLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeSalaryStructureLineId")); - - b.Property("Amount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("EmployeeSalaryStructureId") - .HasColumnType("integer"); - - b.Property("SalaryComponentId") - .HasColumnType("integer"); - - b.HasKey("EmployeeSalaryStructureLineId"); - - b.HasIndex("EmployeeSalaryStructureId"); - - b.HasIndex("SalaryComponentId"); - - b.ToTable("hr_employee_salary_structure_lines", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmploymentType", b => - { - b.Property("EmploymentTypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmploymentTypeId")); - - 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("EmploymentTypeId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_employment_types", (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("DiscountPct") - .HasPrecision(9, 4) - .HasColumnType("numeric(9,4)"); - - b.Property("GrnId") - .HasColumnType("integer"); - - b.Property("HoldStatus") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("LineTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("NetUnitCost") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("PoLineId") - .HasColumnType("integer"); - - b.Property("PoUnitPrice") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - 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.Property("VatAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("VatPct") - .HasPrecision(9, 4) - .HasColumnType("numeric(9,4)"); - - 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.HrDocumentType", b => - { - b.Property("HrDocumentTypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("HrDocumentTypeId")); - - b.Property("Category") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpiryTracked") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("RequiredAtOnboarding") - .HasColumnType("boolean"); - - 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("HrDocumentTypeId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_document_types", (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("SalePrice") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - 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.LeaveBalance", b => - { - b.Property("LeaveBalanceId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaveBalanceId")); - - b.Property("AdjustmentDays") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("CarriedForwardDays") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("EntitledDays") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("LeaveTypeId") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("TakenDays") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Year") - .HasColumnType("integer"); - - b.HasKey("LeaveBalanceId"); - - b.HasIndex("LeaveTypeId"); - - b.HasIndex("EmployeeId", "LeaveTypeId", "Year") - .IsUnique(); - - b.ToTable("hr_leave_balances", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LeaveRequest", b => - { - b.Property("LeaveRequestId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaveRequestId")); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedBy") - .HasColumnType("integer"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("DaysCount") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("DocNo") - .IsRequired() - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("EndDate") - .HasColumnType("timestamp with time zone"); - - b.Property("LeaveTypeId") - .HasColumnType("integer"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("RejectionReason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("StartDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("LeaveRequestId"); - - b.HasIndex("DocNo") - .IsUnique(); - - b.HasIndex("EmployeeId"); - - b.HasIndex("LeaveTypeId"); - - b.HasIndex("Status"); - - b.HasIndex("StartDate", "EndDate"); - - b.ToTable("hr_leave_requests", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LeaveType", b => - { - b.Property("LeaveTypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaveTypeId")); - - b.Property("AccrualPerYear") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("CarryForwardAllowed") - .HasColumnType("boolean"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CountsAsNoPay") - .HasColumnType("boolean"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("IsPaid") - .HasColumnType("boolean"); - - b.Property("MaxCarryForwardDays") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("RequiresApproval") - .HasColumnType("boolean"); - - 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("LeaveTypeId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_leave_types", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LoanInstallment", b => - { - b.Property("LoanInstallmentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LoanInstallmentId")); - - b.Property("DueMonth") - .HasColumnType("integer"); - - b.Property("DueYear") - .HasColumnType("integer"); - - b.Property("EmployeeLoanId") - .HasColumnType("integer"); - - b.Property("InstallmentNumber") - .HasColumnType("integer"); - - b.Property("PaidAmount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("PayrollRunId") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("ScheduledAmount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("LoanInstallmentId"); - - b.HasIndex("EmployeeLoanId"); - - b.HasIndex("PayrollRunId"); - - b.HasIndex("DueYear", "DueMonth"); - - b.ToTable("hr_loan_installments", (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" - }); - }); - - 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.PayrollLine", b => - { - b.Property("PayrollLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayrollLineId")); - - b.Property("AbsentDays") - .HasColumnType("integer"); - - b.Property("BasicSalary") - .HasColumnType("numeric(18,2)"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("EpfEmployeeAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("EpfEmployerAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("EtfEmployerAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("GrossSalary") - .HasColumnType("numeric(18,2)"); - - b.Property("LateDeductionAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("LateMinutesTotal") - .HasColumnType("integer"); - - b.Property("LeaveDays") - .HasColumnType("integer"); - - b.Property("LoanDeductionAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("NetSalary") - .HasColumnType("numeric(18,2)"); - - b.Property("NoPayAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("OtMinutesTotal") - .HasColumnType("integer"); - - b.Property("OtherDeductionsAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("OvertimeAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("PayrollRunId") - .HasColumnType("integer"); - - b.Property("PresentDays") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("TaxAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("TotalAllowances") - .HasColumnType("numeric(18,2)"); - - b.Property("WorkingDays") - .HasColumnType("integer"); - - b.HasKey("PayrollLineId"); - - b.HasIndex("EmployeeId"); - - b.HasIndex("PayrollRunId", "EmployeeId") - .IsUnique(); - - b.ToTable("hr_payroll_lines", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollLineComponent", b => - { - b.Property("PayrollLineComponentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayrollLineComponentId")); - - b.Property("Amount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("ComponentCategory") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Label") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("PayrollLineId") - .HasColumnType("integer"); - - b.Property("SalaryComponentId") - .HasColumnType("integer"); - - b.Property("SortOrder") - .HasColumnType("integer"); - - b.HasKey("PayrollLineComponentId"); - - b.HasIndex("PayrollLineId"); - - b.HasIndex("SalaryComponentId"); - - b.ToTable("hr_payroll_line_components", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollRun", b => - { - b.Property("PayrollRunId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayrollRunId")); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedBy") - .HasColumnType("integer"); - - b.Property("BranchId") - .HasColumnType("integer"); - - b.Property("DocNo") - .IsRequired() - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("GeneratedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("GeneratedBy") - .HasColumnType("integer"); - - b.Property("LockedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("LockedBy") - .HasColumnType("integer"); - - b.Property("PeriodMonth") - .HasColumnType("integer"); - - b.Property("PeriodYear") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("UnlockReason") - .HasMaxLength(500) - .HasColumnType("character varying(500)"); - - b.Property("UnlockedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("UnlockedBy") - .HasColumnType("integer"); - - b.HasKey("PayrollRunId"); - - b.HasIndex("BranchId"); - - b.HasIndex("DocNo") - .IsUnique(); - - b.HasIndex("Status"); - - b.HasIndex("PeriodYear", "PeriodMonth", "BranchId"); - - b.ToTable("hr_payroll_runs", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollStatutorySetting", b => - { - b.Property("PayrollStatutorySettingId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayrollStatutorySettingId")); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("EffectiveFrom") - .HasColumnType("timestamp with time zone"); - - b.Property("EffectiveTo") - .HasColumnType("timestamp with time zone"); - - b.Property("EpfEmployeeRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("EpfEmployerRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("EtfEmployerRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("OtMultiplierDefault") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.HasKey("PayrollStatutorySettingId"); - - b.HasIndex("EffectiveFrom"); - - b.ToTable("hr_payroll_statutory_settings", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Payslip", b => - { - b.Property("PayslipId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayslipId")); - - b.Property("GeneratedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("PayrollLineId") - .HasColumnType("integer"); - - b.Property("ReleasedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ReleasedBy") - .HasColumnType("integer"); - - b.HasKey("PayslipId"); - - b.HasIndex("PayrollLineId") - .IsUnique(); - - b.ToTable("hr_payslips", (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:procurement.requisitions", - SubNavItemId = 9 - }, - new - { - PermissionId = 20, - Code = "NAV:procurement.rfqs", - SubNavItemId = 10 - }, - new - { - PermissionId = 21, - Code = "NAV:procurement.purchase-orders", - SubNavItemId = 11 - }, - new - { - PermissionId = 22, - Code = "NAV:procurement.purchase-returns", - SubNavItemId = 12 - }); - }); - - 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.SalaryComponent", b => - { - b.Property("SalaryComponentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalaryComponentId")); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ComponentType") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("IsEpfEtfApplicable") - .HasColumnType("boolean"); - - b.Property("IsTaxable") - .HasColumnType("boolean"); - - 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("SalaryComponentId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_salary_components", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoice", b => - { - b.Property("SalesInvoiceId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalesInvoiceId")); - - b.Property("BalanceAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("CreatorUserId") - .HasColumnType("integer"); - - b.Property("CustomerId") - .HasColumnType("integer"); - - b.Property("CustomerSnapshotName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("CustomerSnapshotTaxNo") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("DiscountTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("GrandTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("InvoiceDate") - .HasColumnType("timestamp with time zone"); - - b.Property("InvoiceNo") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("InvoiceType") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("B2C"); - - b.Property("NetPayable") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("PaidAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RoundOff") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Draft"); - - b.Property("Subtotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("TaxTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("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("SalesInvoiceLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalesInvoiceLineId")); - - b.Property("BaseCost") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("DiscountAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("DiscountMode") - .HasColumnType("integer"); - - b.Property("DiscountPct") - .HasPrecision(9, 4) - .HasColumnType("numeric(9,4)"); - - b.Property("FreeQty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("IsFreeIssue") - .HasColumnType("boolean"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("LineTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("NetUnitPrice") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("ParentLineId") - .HasColumnType("integer"); - - b.Property("PriceSource") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Qty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SalesInvoiceId") - .HasColumnType("integer"); - - b.Property("TaxAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("TaxPct") - .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("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("SalesSlipId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalesSlipId")); - - b.Property("BalanceAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("CashierUserId") - .HasColumnType("integer"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CustomerId") - .HasColumnType("integer"); - - b.Property("CustomerSnapshotName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("DiscountTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("GrandTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("PaidAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SlipDate") - .HasColumnType("timestamp with time zone"); - - b.Property("SlipNo") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Draft"); - - b.Property("Subtotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("TaxTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("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("SalesSlipLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalesSlipLineId")); - - b.Property("BaseCost") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("DiscountAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("DiscountMode") - .HasColumnType("integer"); - - b.Property("DiscountPct") - .HasPrecision(9, 4) - .HasColumnType("numeric(9,4)"); - - b.Property("FreeQty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("IsFreeIssue") - .HasColumnType("boolean"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("LineTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("NetUnitPrice") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("ParentLineId") - .HasColumnType("integer"); - - b.Property("PriceSource") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Qty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SalesSlipId") - .HasColumnType("integer"); - - b.Property("TaxAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("TaxPct") - .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("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("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("SourceDocType") - .IsRequired() - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("UnitCost") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("UserId") - .HasColumnType("integer"); - - b.Property("Value") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("WarehouseId") - .HasColumnType("integer"); - - b.HasKey("LedgerId"); - - b.HasIndex("BatchId"); - - b.HasIndex("BinId"); - - b.HasIndex("SerialId"); - - b.HasIndex("UserId"); - - b.HasIndex("WarehouseId"); - - b.HasIndex("SourceDocType", "SourceDocId"); - - b.HasIndex("ItemId", "WarehouseId", "CreatedAt"); - - b.HasIndex("ItemId", "WarehouseId", "LedgerId"); - - b.ToTable("stock_ledger", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransfer", b => - { - b.Property("TransferId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("TransferId")); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("DestWarehouseId") - .HasColumnType("integer"); - - b.Property("DocNo") - .IsRequired() - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SrcWarehouseId") - .HasColumnType("integer"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("TransferId"); - - b.HasIndex("CreatedBy"); - - b.HasIndex("DestWarehouseId"); - - b.HasIndex("DocNo") - .IsUnique(); - - b.HasIndex("SrcWarehouseId"); - - b.HasIndex("Status"); - - b.ToTable("stock_transfers", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransferLine", b => - { - b.Property("TransferLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("TransferLineId")); - - b.Property("BatchId") - .HasColumnType("integer"); - - b.Property("DestBinId") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Qty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("QtyReceived") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("SerialId") - .HasColumnType("integer"); - - b.Property("SrcBinId") - .HasColumnType("integer"); - - b.Property("TransferId") - .HasColumnType("integer"); - - b.Property("UnitCost") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.HasKey("TransferLineId"); - - b.HasIndex("BatchId"); - - b.HasIndex("DestBinId"); - - b.HasIndex("ItemId"); - - b.HasIndex("SerialId"); - - b.HasIndex("SrcBinId"); - - b.HasIndex("TransferId"); - - b.ToTable("stock_transfer_lines", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SubCategory", b => - { - b.Property("SubCategoryId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SubCategoryId")); - - b.Property("CategoryId") - .HasColumnType("integer"); - - 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("SubCategoryId"); - - b.HasIndex("Status"); - - b.HasIndex("CategoryId", "Name") - .IsUnique(); - - b.ToTable("subcategories", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SubNavItem", b => - { - b.Property("SubNavItemId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SubNavItemId")); - - 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("NavItemId") - .HasColumnType("integer"); - - b.Property("SortOrder") - .HasColumnType("integer"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.HasKey("SubNavItemId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("NavItemId"); - - b.ToTable("sub_nav_items", (string)null); - - b.HasData( - new - { - SubNavItemId = 1, - Code = "products.item", - Href = "/dashboard/products", - Label = "Item", - NavItemId = 2, - SortOrder = 1, - Status = "Active" - }, - new - { - SubNavItemId = 2, - Code = "products.category", - Href = "/dashboard/products/categories", - Label = "Category", - NavItemId = 2, - SortOrder = 2, - Status = "Active" - }, - new - { - SubNavItemId = 3, - Code = "products.brand", - Href = "/dashboard/products/brands", - Label = "Brand", - NavItemId = 2, - SortOrder = 3, - Status = "Active" - }, - new - { - SubNavItemId = 4, - Code = "products.item-type", - Href = "/dashboard/products/item-types", - Label = "Item Type", - NavItemId = 2, - SortOrder = 4, - Status = "Active" - }, - new - { - SubNavItemId = 5, - Code = "products.uom", - Href = "/dashboard/products/uoms", - Label = "UOM", - NavItemId = 2, - SortOrder = 5, - Status = "Active" - }, - new - { - SubNavItemId = 6, - Code = "products.configuration", - Href = "/dashboard/products/settings", - Label = "Configuration", - NavItemId = 2, - SortOrder = 6, - Status = "Active" - }, - new - { - SubNavItemId = 7, - Code = "settings.roles", - Href = "/dashboard/settings/roles", - Label = "Roles", - NavItemId = 9, - SortOrder = 1, - Status = "Active" - }, - new - { - SubNavItemId = 8, - Code = "settings.users", - Href = "/dashboard/settings/users", - Label = "Users", - NavItemId = 9, - SortOrder = 2, - Status = "Active" - }, - new - { - SubNavItemId = 9, - Code = "procurement.requisitions", - Href = "/dashboard/procurement/requisitions", - Label = "Requisitions", - NavItemId = 4, - SortOrder = 1, - Status = "Active" - }, - new - { - SubNavItemId = 10, - Code = "procurement.rfqs", - Href = "/dashboard/procurement/rfqs", - Label = "RFQs", - NavItemId = 4, - SortOrder = 2, - Status = "Active" - }, - new - { - SubNavItemId = 11, - Code = "procurement.purchase-orders", - Href = "/dashboard/procurement/purchase-orders", - Label = "Purchase Orders", - NavItemId = 4, - SortOrder = 3, - Status = "Active" - }, - new - { - SubNavItemId = 12, - Code = "procurement.purchase-returns", - Href = "/dashboard/procurement/purchase-returns", - Label = "Purchase Returns", - NavItemId = 4, - SortOrder = 4, - Status = "Active" - }); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.TaxSlab", b => - { - b.Property("TaxSlabId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("TaxSlabId")); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("EffectiveFrom") - .HasColumnType("timestamp with time zone"); - - b.Property("EffectiveTo") - .HasColumnType("timestamp with time zone"); - - b.Property("LowerBound") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("Rate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("UpperBound") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.HasKey("TaxSlabId"); - - b.HasIndex("EffectiveFrom"); - - b.ToTable("hr_tax_slabs", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Uom", b => - { - b.Property("UomId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("UomId")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("UomId"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("uoms", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b => - { - b.Property("ConversionId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ConversionId")); - - b.Property("Factor") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("FromUomId") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("ToUomId") - .HasColumnType("integer"); - - b.HasKey("ConversionId"); - - b.HasIndex("FromUomId"); - - b.HasIndex("ToUomId"); - - b.HasIndex("ItemId", "FromUomId", "ToUomId") - .IsUnique(); - - b.ToTable("uom_conversions", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.User", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("UserId")); - - b.Property("AuthUserId") - .HasColumnType("uuid") - .HasColumnName("auth_user_id"); - - b.Property("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("character varying(320)"); - - b.Property("RoleId") - .HasColumnType("integer"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Username") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("UserId"); - - b.HasIndex("AuthUserId") - .IsUnique(); - - b.HasIndex("Email") - .IsUnique(); - - b.HasIndex("RoleId"); - - b.HasIndex("Username") - .IsUnique(); - - b.ToTable("users", (string)null); - - b.HasData( - new - { - UserId = 1, - DisplayName = "System", - Status = "Active", - Username = "system" - }); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Vendor", b => - { - b.Property("VendorId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("VendorId")); - - b.Property("Code") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Currency") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(3) - .HasColumnType("character varying(3)") - .HasDefaultValue("LKR"); - - 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("TaxReg") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Terms") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.HasKey("VendorId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("vendors", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b => - { - b.Property("QuotationId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("QuotationId")); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("RfqId") - .HasColumnType("integer"); - - b.Property("VendorId") - .HasColumnType("integer"); - - b.HasKey("QuotationId"); - - b.HasIndex("VendorId"); - - b.HasIndex("RfqId", "VendorId") - .IsUnique(); - - b.ToTable("vendor_quotations", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotationLine", b => - { - b.Property("QuotationLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("QuotationLineId")); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("LeadDays") - .HasColumnType("integer"); - - b.Property("QuotationId") - .HasColumnType("integer"); - - b.Property("UnitPrice") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.HasKey("QuotationLineId"); - - b.HasIndex("ItemId"); - - b.HasIndex("QuotationId"); - - b.ToTable("vendor_quotation_lines", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b => - { - b.Property("WarehouseId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("WarehouseId")); - - b.Property("Code") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.HasKey("WarehouseId"); - - b.HasIndex("Code") - .IsUnique(); - - b.ToTable("warehouses", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.WorkShift", b => - { - b.Property("WorkShiftId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("WorkShiftId")); - - b.Property("BreakMinutes") - .HasColumnType("integer"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("EndTime") - .HasColumnType("interval"); - - b.Property("GraceMinutes") - .HasColumnType("integer"); - - b.Property("IsOvernight") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("OtMultiplier") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("StandardWorkingMinutes") - .HasColumnType("integer"); - - b.Property("StartTime") - .HasColumnType("interval"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("WorkingDaysMask") - .HasColumnType("integer"); - - b.HasKey("WorkShiftId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_work_shifts", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.AttendanceRecord", b => - { - b.HasOne("ERPCore.Domain.Entities.AttendanceUploadBatch", "AttendanceUploadBatch") - .WithMany() - .HasForeignKey("AttendanceUploadBatchId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.WorkShift", "WorkShift") - .WithMany() - .HasForeignKey("WorkShiftId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("AttendanceUploadBatch"); - - b.Navigation("Employee"); - - b.Navigation("WorkShift"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.AuditLog", b => - { - b.HasOne("ERPCore.Domain.Entities.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Batch", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b => - { - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany("Bins") - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - 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") - .WithMany() - .HasForeignKey("BranchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Employee", "HeadEmployee") - .WithMany() - .HasForeignKey("HeadEmployeeId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Department", "ParentDepartment") - .WithMany() - .HasForeignKey("ParentDepartmentId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Branch"); - - b.Navigation("HeadEmployee"); - - b.Navigation("ParentDepartment"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Employee", b => - { - b.HasOne("ERPCore.Domain.Entities.Branch", "Branch") - .WithMany() - .HasForeignKey("BranchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Department", "Department") - .WithMany() - .HasForeignKey("DepartmentId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Designation", "Designation") - .WithMany() - .HasForeignKey("DesignationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.EmploymentType", "EmploymentType") - .WithMany() - .HasForeignKey("EmploymentTypeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Employee", "ReportingManager") - .WithMany() - .HasForeignKey("ReportingManagerId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.User", "User") - .WithOne() - .HasForeignKey("ERPCore.Domain.Entities.Employee", "UserId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.WorkShift", "WorkShift") - .WithMany() - .HasForeignKey("WorkShiftId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Branch"); - - b.Navigation("Department"); - - b.Navigation("Designation"); - - b.Navigation("EmploymentType"); - - b.Navigation("ReportingManager"); - - b.Navigation("User"); - - b.Navigation("WorkShift"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeBankDetail", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Employee"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeDocument", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.HrDocumentType", "HrDocumentType") - .WithMany() - .HasForeignKey("HrDocumentTypeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - - b.Navigation("HrDocumentType"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeLoan", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructure", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructureLine", b => - { - b.HasOne("ERPCore.Domain.Entities.EmployeeSalaryStructure", "EmployeeSalaryStructure") - .WithMany("Lines") - .HasForeignKey("EmployeeSalaryStructureId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.SalaryComponent", "SalaryComponent") - .WithMany() - .HasForeignKey("SalaryComponentId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("EmployeeSalaryStructure"); - - b.Navigation("SalaryComponent"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Grn", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PurchaseOrder", "PurchaseOrder") - .WithMany() - .HasForeignKey("PoId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor") - .WithMany() - .HasForeignKey("VendorId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("PurchaseOrder"); - - b.Navigation("Vendor"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.GrnLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Batch", "Batch") - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", "Bin") - .WithMany() - .HasForeignKey("BinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Grn", "Grn") - .WithMany("Lines") - .HasForeignKey("GrnId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PoLine", "PoLine") - .WithMany() - .HasForeignKey("PoLineId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Uom", "Uom") - .WithMany() - .HasForeignKey("UomId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Batch"); - - b.Navigation("Bin"); - - b.Navigation("Grn"); - - b.Navigation("Item"); - - b.Navigation("PoLine"); - - b.Navigation("Uom"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Item", b => - { - b.HasOne("ERPCore.Domain.Entities.Uom", "BaseUom") - .WithMany() - .HasForeignKey("BaseUomId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Brand", "Brand") - .WithMany() - .HasForeignKey("BrandId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "DefaultVendor") - .WithMany() - .HasForeignKey("DefaultVendorId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.SubCategory", "SubCategory") - .WithMany() - .HasForeignKey("SubCategoryId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("BaseUom"); - - b.Navigation("Brand"); - - b.Navigation("Category"); - - b.Navigation("DefaultVendor"); - - b.Navigation("SubCategory"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany("ReorderSettings") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LeaveBalance", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.LeaveType", "LeaveType") - .WithMany() - .HasForeignKey("LeaveTypeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - - b.Navigation("LeaveType"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LeaveRequest", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.LeaveType", "LeaveType") - .WithMany() - .HasForeignKey("LeaveTypeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - - b.Navigation("LeaveType"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LoanInstallment", b => - { - b.HasOne("ERPCore.Domain.Entities.EmployeeLoan", "EmployeeLoan") - .WithMany("Installments") - .HasForeignKey("EmployeeLoanId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PayrollRun", "PayrollRun") - .WithMany() - .HasForeignKey("PayrollRunId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("EmployeeLoan"); - - b.Navigation("PayrollRun"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PayrollRun", "PayrollRun") - .WithMany("Lines") - .HasForeignKey("PayrollRunId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Employee"); - - b.Navigation("PayrollRun"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollLineComponent", b => - { - b.HasOne("ERPCore.Domain.Entities.PayrollLine", "PayrollLine") - .WithMany("Components") - .HasForeignKey("PayrollLineId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.SalaryComponent", "SalaryComponent") - .WithMany() - .HasForeignKey("SalaryComponentId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("PayrollLine"); - - b.Navigation("SalaryComponent"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollRun", b => - { - b.HasOne("ERPCore.Domain.Entities.Branch", "Branch") - .WithMany() - .HasForeignKey("BranchId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Branch"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Payslip", b => - { - b.HasOne("ERPCore.Domain.Entities.PayrollLine", "PayrollLine") - .WithOne() - .HasForeignKey("ERPCore.Domain.Entities.Payslip", "PayrollLineId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("PayrollLine"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Permission", b => - { - b.HasOne("ERPCore.Domain.Entities.NavItem", "NavItem") - .WithMany() - .HasForeignKey("NavItemId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("ERPCore.Domain.Entities.SubNavItem", "SubNavItem") - .WithMany() - .HasForeignKey("SubNavItemId") - .OnDelete(DeleteBehavior.Cascade); - - b.Navigation("NavItem"); - - b.Navigation("SubNavItem"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PoLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PurchaseOrder", "PurchaseOrder") - .WithMany("Lines") - .HasForeignKey("PoId") - .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("PurchaseOrder"); - - b.Navigation("Uom"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.ProductConfig", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "UpdatedByUser") - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("UpdatedByUser"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition") - .WithMany() - .HasForeignKey("RequisitionId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor") - .WithMany() - .HasForeignKey("VendorId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("Requisition"); - - b.Navigation("Vendor"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseReturn", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.ReasonCode", "ReasonCode") - .WithMany() - .HasForeignKey("ReasonCodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor") - .WithMany() - .HasForeignKey("VendorId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("ReasonCode"); - - b.Navigation("Vendor"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseReturnLine", b => - { - b.HasOne("ERPCore.Domain.Entities.GrnLine", "GrnLine") - .WithMany() - .HasForeignKey("GrnLineId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PurchaseReturn", "Return") - .WithMany("Lines") - .HasForeignKey("ReturnId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("GrnLine"); - - b.Navigation("Item"); - - b.Navigation("Return"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Requisition", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Requester") - .WithMany() - .HasForeignKey("RequestedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Requester"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.RequisitionLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition") - .WithMany("Lines") - .HasForeignKey("RequisitionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Requisition"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Rfq", b => - { - b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition") - .WithMany() - .HasForeignKey("RequisitionId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Requisition"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.RfqLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Rfq", "Rfq") - .WithMany("Lines") - .HasForeignKey("RfqId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Rfq"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.RolePermission", b => - { - b.HasOne("ERPCore.Domain.Entities.Permission", "Permission") - .WithMany() - .HasForeignKey("PermissionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Role", "Role") - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Permission"); - - b.Navigation("Role"); - }); - - 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") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustment", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.ReasonCode", "ReasonCode") - .WithMany() - .HasForeignKey("ReasonCodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("ReasonCode"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustmentLine", b => - { - b.HasOne("ERPCore.Domain.Entities.StockAdjustment", "Adjustment") - .WithMany("Lines") - .HasForeignKey("AdjustmentId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Batch", null) - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("BinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Serial", null) - .WithMany() - .HasForeignKey("SerialId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Adjustment"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockCount", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockCountLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("BinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.StockCount", "Count") - .WithMany("Lines") - .HasForeignKey("CountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Count"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockLayer", b => - { - b.HasOne("ERPCore.Domain.Entities.Batch", "Batch") - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.GrnLine", "GrnLine") - .WithMany() - .HasForeignKey("GrnLineId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Serial", "Serial") - .WithMany() - .HasForeignKey("SerialId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Batch"); - - b.Navigation("GrnLine"); - - b.Navigation("Item"); - - b.Navigation("Serial"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockLedger", b => - { - b.HasOne("ERPCore.Domain.Entities.Batch", null) - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("BinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", null) - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Serial", null) - .WithMany() - .HasForeignKey("SerialId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", null) - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransfer", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "DestWarehouse") - .WithMany() - .HasForeignKey("DestWarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "SrcWarehouse") - .WithMany() - .HasForeignKey("SrcWarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("DestWarehouse"); - - b.Navigation("SrcWarehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransferLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Batch", null) - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("DestBinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Serial", null) - .WithMany() - .HasForeignKey("SerialId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("SrcBinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.StockTransfer", "Transfer") - .WithMany("Lines") - .HasForeignKey("TransferId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Transfer"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SubCategory", b => - { - b.HasOne("ERPCore.Domain.Entities.Category", "Category") - .WithMany("SubCategories") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SubNavItem", b => - { - b.HasOne("ERPCore.Domain.Entities.NavItem", "NavItem") - .WithMany("Children") - .HasForeignKey("NavItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("NavItem"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b => - { - b.HasOne("ERPCore.Domain.Entities.Uom", "FromUom") - .WithMany() - .HasForeignKey("FromUomId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany("UomConversions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Uom", "ToUom") - .WithMany() - .HasForeignKey("ToUomId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("FromUom"); - - b.Navigation("Item"); - - b.Navigation("ToUom"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.User", b => - { - b.HasOne("ERPCore.Domain.Entities.Role", "Role") - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Role"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b => - { - b.HasOne("ERPCore.Domain.Entities.Rfq", "Rfq") - .WithMany("Quotations") - .HasForeignKey("RfqId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor") - .WithMany() - .HasForeignKey("VendorId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Rfq"); - - b.Navigation("Vendor"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotationLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.VendorQuotation", "Quotation") - .WithMany("Lines") - .HasForeignKey("QuotationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Quotation"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Category", b => - { - b.Navigation("SubCategories"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeLoan", b => - { - b.Navigation("Installments"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructure", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Grn", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Item", b => - { - b.Navigation("ReorderSettings"); - - b.Navigation("UomConversions"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.NavItem", b => - { - b.Navigation("Children"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollLine", b => - { - b.Navigation("Components"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollRun", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseReturn", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Requisition", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Rfq", b => - { - b.Navigation("Lines"); - - b.Navigation("Quotations"); - }); - - 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"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockCount", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransfer", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b => - { - b.Navigation("Bins"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Backend/ERPCore/Migrations/20260728054611_InitialCreate1.Designer.cs b/Backend/ERPCore/Migrations/20260728054611_InitialCreate1.Designer.cs deleted file mode 100644 index f8c9318..0000000 --- a/Backend/ERPCore/Migrations/20260728054611_InitialCreate1.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("20260728054611_InitialCreate1")] - partial class InitialCreate1 - { - /// - 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("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.Customer", b => - { - b.Property("CustomerId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("CustomerId")); - - b.Property("AddressLine1") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.Property("AddressLine2") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); - - b.Property("City") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Country") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreditDays") - .HasColumnType("integer"); - - b.Property("CreditLimit") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("CustomerCode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CustomerType") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("B2C"); - - b.Property("DefaultWarehouseId") - .HasColumnType("integer"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Email") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Phone") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("TaxRegistrationNo") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("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("DepartmentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("DepartmentId")); - - b.Property("BranchId") - .HasColumnType("integer"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("HeadEmployeeId") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("ParentDepartmentId") - .HasColumnType("integer"); - - 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("DepartmentId"); - - b.HasIndex("BranchId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("HeadEmployeeId"); - - b.HasIndex("ParentDepartmentId"); - - b.HasIndex("Status"); - - b.ToTable("hr_departments", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Designation", b => - { - b.Property("DesignationId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("DesignationId")); - - 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("DesignationId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_designations", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Employee", b => - { - b.Property("EmployeeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeId")); - - b.Property("AddressLine1") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("AddressLine2") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("BranchId") - .HasColumnType("integer"); - - b.Property("City") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("ConfirmationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Country") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("DateOfBirth") - .HasColumnType("timestamp with time zone"); - - b.Property("DepartmentId") - .HasColumnType("integer"); - - b.Property("DesignationId") - .HasColumnType("integer"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("character varying(320)"); - - b.Property("EmergencyContactName") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("EmergencyContactPhone") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("EmergencyContactRelationship") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("EmployeeCode") - .IsRequired() - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("EmploymentTypeId") - .HasColumnType("integer"); - - b.Property("EpfNumber") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("EtfNumber") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("FullName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Gender") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("HireDate") - .HasColumnType("timestamp with time zone"); - - b.Property("LastWorkingDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Nationality") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Nic") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("PersonalMobile") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("PostalCode") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ProfilePhotoPath") - .HasMaxLength(500) - .HasColumnType("character varying(500)"); - - b.Property("ReportingManagerId") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("TaxIdentificationNumber") - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("UpdatedBy") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("integer"); - - b.Property("WorkShiftId") - .HasColumnType("integer"); - - b.HasKey("EmployeeId"); - - b.HasIndex("BranchId"); - - b.HasIndex("DepartmentId"); - - b.HasIndex("DesignationId"); - - b.HasIndex("Email"); - - b.HasIndex("EmployeeCode") - .IsUnique(); - - b.HasIndex("EmploymentTypeId"); - - b.HasIndex("ReportingManagerId"); - - b.HasIndex("Status"); - - b.HasIndex("UserId") - .IsUnique(); - - b.HasIndex("WorkShiftId"); - - b.ToTable("hr_employees", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeBankDetail", b => - { - b.Property("EmployeeBankDetailId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeBankDetailId")); - - b.Property("AccountHolderName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("AccountNumber") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("BankName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("BranchName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("IsPrimary") - .HasColumnType("boolean"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("SwiftCode") - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.HasKey("EmployeeBankDetailId"); - - b.HasIndex("EmployeeId"); - - b.ToTable("hr_employee_bank_details", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeDocument", b => - { - b.Property("EmployeeDocumentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeDocumentId")); - - b.Property("ContentType") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("ExpiryDate") - .HasColumnType("timestamp with time zone"); - - b.Property("HrDocumentTypeId") - .HasColumnType("integer"); - - b.Property("IssueDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Notes") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("OriginalFileName") - .IsRequired() - .HasMaxLength(260) - .HasColumnType("character varying(260)"); - - b.Property("RelativePath") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SizeBytes") - .HasColumnType("bigint"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("StoredFileName") - .IsRequired() - .HasMaxLength(260) - .HasColumnType("character varying(260)"); - - b.Property("UploadedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("UploadedBy") - .HasColumnType("integer"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("VerifiedBy") - .HasColumnType("integer"); - - b.HasKey("EmployeeDocumentId"); - - b.HasIndex("EmployeeId"); - - b.HasIndex("ExpiryDate"); - - b.HasIndex("HrDocumentTypeId"); - - b.ToTable("hr_employee_documents", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeLoan", b => - { - b.Property("EmployeeLoanId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeLoanId")); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedBy") - .HasColumnType("integer"); - - 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("EmployeeId") - .HasColumnType("integer"); - - b.Property("InstallmentAmount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("InterestRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("LoanKind") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("NumberOfInstallments") - .HasColumnType("integer"); - - b.Property("OutstandingBalance") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("PrincipalAmount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("StartMonth") - .HasColumnType("integer"); - - b.Property("StartYear") - .HasColumnType("integer"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("EmployeeLoanId"); - - b.HasIndex("DocNo") - .IsUnique(); - - b.HasIndex("EmployeeId"); - - b.HasIndex("Status"); - - b.ToTable("hr_employee_loans", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructure", b => - { - b.Property("EmployeeSalaryStructureId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeSalaryStructureId")); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedBy") - .HasColumnType("integer"); - - b.Property("BasicSalary") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("Currency") - .IsRequired() - .HasMaxLength(3) - .HasColumnType("character varying(3)"); - - b.Property("EffectiveFrom") - .HasColumnType("timestamp with time zone"); - - b.Property("EffectiveTo") - .HasColumnType("timestamp with time zone"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("EmployeeSalaryStructureId"); - - b.HasIndex("EmployeeId", "EffectiveTo"); - - b.ToTable("hr_employee_salary_structures", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructureLine", b => - { - b.Property("EmployeeSalaryStructureLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmployeeSalaryStructureLineId")); - - b.Property("Amount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("EmployeeSalaryStructureId") - .HasColumnType("integer"); - - b.Property("SalaryComponentId") - .HasColumnType("integer"); - - b.HasKey("EmployeeSalaryStructureLineId"); - - b.HasIndex("EmployeeSalaryStructureId"); - - b.HasIndex("SalaryComponentId"); - - b.ToTable("hr_employee_salary_structure_lines", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmploymentType", b => - { - b.Property("EmploymentTypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("EmploymentTypeId")); - - 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("EmploymentTypeId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_employment_types", (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("DiscountPct") - .HasPrecision(9, 4) - .HasColumnType("numeric(9,4)"); - - b.Property("GrnId") - .HasColumnType("integer"); - - b.Property("HoldStatus") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("LineTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("NetUnitCost") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("PoLineId") - .HasColumnType("integer"); - - b.Property("PoUnitPrice") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - 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.Property("VatAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("VatPct") - .HasPrecision(9, 4) - .HasColumnType("numeric(9,4)"); - - 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.HrDocumentType", b => - { - b.Property("HrDocumentTypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("HrDocumentTypeId")); - - b.Property("Category") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpiryTracked") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("RequiredAtOnboarding") - .HasColumnType("boolean"); - - 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("HrDocumentTypeId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_document_types", (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("SalePrice") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - 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.LeaveBalance", b => - { - b.Property("LeaveBalanceId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaveBalanceId")); - - b.Property("AdjustmentDays") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("CarriedForwardDays") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("EntitledDays") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("LeaveTypeId") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("TakenDays") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Year") - .HasColumnType("integer"); - - b.HasKey("LeaveBalanceId"); - - b.HasIndex("LeaveTypeId"); - - b.HasIndex("EmployeeId", "LeaveTypeId", "Year") - .IsUnique(); - - b.ToTable("hr_leave_balances", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LeaveRequest", b => - { - b.Property("LeaveRequestId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaveRequestId")); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedBy") - .HasColumnType("integer"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("DaysCount") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("DocNo") - .IsRequired() - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("EndDate") - .HasColumnType("timestamp with time zone"); - - b.Property("LeaveTypeId") - .HasColumnType("integer"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("RejectionReason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("StartDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("LeaveRequestId"); - - b.HasIndex("DocNo") - .IsUnique(); - - b.HasIndex("EmployeeId"); - - b.HasIndex("LeaveTypeId"); - - b.HasIndex("Status"); - - b.HasIndex("StartDate", "EndDate"); - - b.ToTable("hr_leave_requests", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LeaveType", b => - { - b.Property("LeaveTypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaveTypeId")); - - b.Property("AccrualPerYear") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("CarryForwardAllowed") - .HasColumnType("boolean"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CountsAsNoPay") - .HasColumnType("boolean"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("IsPaid") - .HasColumnType("boolean"); - - b.Property("MaxCarryForwardDays") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("RequiresApproval") - .HasColumnType("boolean"); - - 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("LeaveTypeId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_leave_types", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LoanInstallment", b => - { - b.Property("LoanInstallmentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LoanInstallmentId")); - - b.Property("DueMonth") - .HasColumnType("integer"); - - b.Property("DueYear") - .HasColumnType("integer"); - - b.Property("EmployeeLoanId") - .HasColumnType("integer"); - - b.Property("InstallmentNumber") - .HasColumnType("integer"); - - b.Property("PaidAmount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("PayrollRunId") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("ScheduledAmount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("LoanInstallmentId"); - - b.HasIndex("EmployeeLoanId"); - - b.HasIndex("PayrollRunId"); - - b.HasIndex("DueYear", "DueMonth"); - - b.ToTable("hr_loan_installments", (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" - }); - }); - - 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.PayrollLine", b => - { - b.Property("PayrollLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayrollLineId")); - - b.Property("AbsentDays") - .HasColumnType("integer"); - - b.Property("BasicSalary") - .HasColumnType("numeric(18,2)"); - - b.Property("EmployeeId") - .HasColumnType("integer"); - - b.Property("EpfEmployeeAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("EpfEmployerAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("EtfEmployerAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("GrossSalary") - .HasColumnType("numeric(18,2)"); - - b.Property("LateDeductionAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("LateMinutesTotal") - .HasColumnType("integer"); - - b.Property("LeaveDays") - .HasColumnType("integer"); - - b.Property("LoanDeductionAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("NetSalary") - .HasColumnType("numeric(18,2)"); - - b.Property("NoPayAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("OtMinutesTotal") - .HasColumnType("integer"); - - b.Property("OtherDeductionsAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("OvertimeAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("PayrollRunId") - .HasColumnType("integer"); - - b.Property("PresentDays") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("TaxAmount") - .HasColumnType("numeric(18,2)"); - - b.Property("TotalAllowances") - .HasColumnType("numeric(18,2)"); - - b.Property("WorkingDays") - .HasColumnType("integer"); - - b.HasKey("PayrollLineId"); - - b.HasIndex("EmployeeId"); - - b.HasIndex("PayrollRunId", "EmployeeId") - .IsUnique(); - - b.ToTable("hr_payroll_lines", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollLineComponent", b => - { - b.Property("PayrollLineComponentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayrollLineComponentId")); - - b.Property("Amount") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("ComponentCategory") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Label") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("PayrollLineId") - .HasColumnType("integer"); - - b.Property("SalaryComponentId") - .HasColumnType("integer"); - - b.Property("SortOrder") - .HasColumnType("integer"); - - b.HasKey("PayrollLineComponentId"); - - b.HasIndex("PayrollLineId"); - - b.HasIndex("SalaryComponentId"); - - b.ToTable("hr_payroll_line_components", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollRun", b => - { - b.Property("PayrollRunId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayrollRunId")); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedBy") - .HasColumnType("integer"); - - b.Property("BranchId") - .HasColumnType("integer"); - - b.Property("DocNo") - .IsRequired() - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("GeneratedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("GeneratedBy") - .HasColumnType("integer"); - - b.Property("LockedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("LockedBy") - .HasColumnType("integer"); - - b.Property("PeriodMonth") - .HasColumnType("integer"); - - b.Property("PeriodYear") - .HasColumnType("integer"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("UnlockReason") - .HasMaxLength(500) - .HasColumnType("character varying(500)"); - - b.Property("UnlockedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("UnlockedBy") - .HasColumnType("integer"); - - b.HasKey("PayrollRunId"); - - b.HasIndex("BranchId"); - - b.HasIndex("DocNo") - .IsUnique(); - - b.HasIndex("Status"); - - b.HasIndex("PeriodYear", "PeriodMonth", "BranchId"); - - b.ToTable("hr_payroll_runs", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollStatutorySetting", b => - { - b.Property("PayrollStatutorySettingId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayrollStatutorySettingId")); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("EffectiveFrom") - .HasColumnType("timestamp with time zone"); - - b.Property("EffectiveTo") - .HasColumnType("timestamp with time zone"); - - b.Property("EpfEmployeeRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("EpfEmployerRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("EtfEmployerRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("OtMultiplierDefault") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.HasKey("PayrollStatutorySettingId"); - - b.HasIndex("EffectiveFrom"); - - b.ToTable("hr_payroll_statutory_settings", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Payslip", b => - { - b.Property("PayslipId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PayslipId")); - - b.Property("GeneratedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("PayrollLineId") - .HasColumnType("integer"); - - b.Property("ReleasedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ReleasedBy") - .HasColumnType("integer"); - - b.HasKey("PayslipId"); - - b.HasIndex("PayrollLineId") - .IsUnique(); - - b.ToTable("hr_payslips", (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:procurement.requisitions", - SubNavItemId = 9 - }, - new - { - PermissionId = 20, - Code = "NAV:procurement.rfqs", - SubNavItemId = 10 - }, - new - { - PermissionId = 21, - Code = "NAV:procurement.purchase-orders", - SubNavItemId = 11 - }, - new - { - PermissionId = 22, - Code = "NAV:procurement.purchase-returns", - SubNavItemId = 12 - }); - }); - - 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.SalaryComponent", b => - { - b.Property("SalaryComponentId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalaryComponentId")); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("ComponentType") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("IsEpfEtfApplicable") - .HasColumnType("boolean"); - - b.Property("IsTaxable") - .HasColumnType("boolean"); - - 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("SalaryComponentId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_salary_components", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SalesInvoice", b => - { - b.Property("SalesInvoiceId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalesInvoiceId")); - - b.Property("BalanceAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("CreatorUserId") - .HasColumnType("integer"); - - b.Property("CustomerId") - .HasColumnType("integer"); - - b.Property("CustomerSnapshotName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("CustomerSnapshotTaxNo") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("DiscountTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("GrandTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("InvoiceDate") - .HasColumnType("timestamp with time zone"); - - b.Property("InvoiceNo") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("InvoiceType") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("B2C"); - - b.Property("NetPayable") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("PaidAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RoundOff") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Draft"); - - b.Property("Subtotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("TaxTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("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("SalesInvoiceLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalesInvoiceLineId")); - - b.Property("BaseCost") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("DiscountAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("DiscountMode") - .HasColumnType("integer"); - - b.Property("DiscountPct") - .HasPrecision(9, 4) - .HasColumnType("numeric(9,4)"); - - b.Property("FreeQty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("IsFreeIssue") - .HasColumnType("boolean"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("LineTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("NetUnitPrice") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("ParentLineId") - .HasColumnType("integer"); - - b.Property("PriceSource") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Qty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SalesInvoiceId") - .HasColumnType("integer"); - - b.Property("TaxAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("TaxPct") - .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("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("SalesSlipId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalesSlipId")); - - b.Property("BalanceAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("CashierUserId") - .HasColumnType("integer"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CustomerId") - .HasColumnType("integer"); - - b.Property("CustomerSnapshotName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("DiscountTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("GrandTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("PaidAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SlipDate") - .HasColumnType("timestamp with time zone"); - - b.Property("SlipNo") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Draft"); - - b.Property("Subtotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("TaxTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("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("SalesSlipLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SalesSlipLineId")); - - b.Property("BaseCost") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("DiscountAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("DiscountMode") - .HasColumnType("integer"); - - b.Property("DiscountPct") - .HasPrecision(9, 4) - .HasColumnType("numeric(9,4)"); - - b.Property("FreeQty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("IsFreeIssue") - .HasColumnType("boolean"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("LineTotal") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("NetUnitPrice") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("ParentLineId") - .HasColumnType("integer"); - - b.Property("PriceSource") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Qty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SalesSlipId") - .HasColumnType("integer"); - - b.Property("TaxAmount") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("TaxPct") - .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("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("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("SourceDocType") - .IsRequired() - .HasMaxLength(10) - .HasColumnType("character varying(10)"); - - b.Property("UnitCost") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("UserId") - .HasColumnType("integer"); - - b.Property("Value") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("WarehouseId") - .HasColumnType("integer"); - - b.HasKey("LedgerId"); - - b.HasIndex("BatchId"); - - b.HasIndex("BinId"); - - b.HasIndex("SerialId"); - - b.HasIndex("UserId"); - - b.HasIndex("WarehouseId"); - - b.HasIndex("SourceDocType", "SourceDocId"); - - b.HasIndex("ItemId", "WarehouseId", "CreatedAt"); - - b.HasIndex("ItemId", "WarehouseId", "LedgerId"); - - b.ToTable("stock_ledger", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransfer", b => - { - b.Property("TransferId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("TransferId")); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedBy") - .HasColumnType("integer"); - - b.Property("DestWarehouseId") - .HasColumnType("integer"); - - b.Property("DocNo") - .IsRequired() - .HasMaxLength(30) - .HasColumnType("character varying(30)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("SrcWarehouseId") - .HasColumnType("integer"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.HasKey("TransferId"); - - b.HasIndex("CreatedBy"); - - b.HasIndex("DestWarehouseId"); - - b.HasIndex("DocNo") - .IsUnique(); - - b.HasIndex("SrcWarehouseId"); - - b.HasIndex("Status"); - - b.ToTable("stock_transfers", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransferLine", b => - { - b.Property("TransferLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("TransferLineId")); - - b.Property("BatchId") - .HasColumnType("integer"); - - b.Property("DestBinId") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Qty") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("QtyReceived") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.Property("SerialId") - .HasColumnType("integer"); - - b.Property("SrcBinId") - .HasColumnType("integer"); - - b.Property("TransferId") - .HasColumnType("integer"); - - b.Property("UnitCost") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.HasKey("TransferLineId"); - - b.HasIndex("BatchId"); - - b.HasIndex("DestBinId"); - - b.HasIndex("ItemId"); - - b.HasIndex("SerialId"); - - b.HasIndex("SrcBinId"); - - b.HasIndex("TransferId"); - - b.ToTable("stock_transfer_lines", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SubCategory", b => - { - b.Property("SubCategoryId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SubCategoryId")); - - b.Property("CategoryId") - .HasColumnType("integer"); - - 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("SubCategoryId"); - - b.HasIndex("Status"); - - b.HasIndex("CategoryId", "Name") - .IsUnique(); - - b.ToTable("subcategories", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SubNavItem", b => - { - b.Property("SubNavItemId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("SubNavItemId")); - - 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("NavItemId") - .HasColumnType("integer"); - - b.Property("SortOrder") - .HasColumnType("integer"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.HasKey("SubNavItemId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("NavItemId"); - - b.ToTable("sub_nav_items", (string)null); - - b.HasData( - new - { - SubNavItemId = 1, - Code = "products.item", - Href = "/dashboard/products", - Label = "Item", - NavItemId = 2, - SortOrder = 1, - Status = "Active" - }, - new - { - SubNavItemId = 2, - Code = "products.category", - Href = "/dashboard/products/categories", - Label = "Category", - NavItemId = 2, - SortOrder = 2, - Status = "Active" - }, - new - { - SubNavItemId = 3, - Code = "products.brand", - Href = "/dashboard/products/brands", - Label = "Brand", - NavItemId = 2, - SortOrder = 3, - Status = "Active" - }, - new - { - SubNavItemId = 4, - Code = "products.item-type", - Href = "/dashboard/products/item-types", - Label = "Item Type", - NavItemId = 2, - SortOrder = 4, - Status = "Active" - }, - new - { - SubNavItemId = 5, - Code = "products.uom", - Href = "/dashboard/products/uoms", - Label = "UOM", - NavItemId = 2, - SortOrder = 5, - Status = "Active" - }, - new - { - SubNavItemId = 6, - Code = "products.configuration", - Href = "/dashboard/products/settings", - Label = "Configuration", - NavItemId = 2, - SortOrder = 6, - Status = "Active" - }, - new - { - SubNavItemId = 7, - Code = "settings.roles", - Href = "/dashboard/settings/roles", - Label = "Roles", - NavItemId = 9, - SortOrder = 1, - Status = "Active" - }, - new - { - SubNavItemId = 8, - Code = "settings.users", - Href = "/dashboard/settings/users", - Label = "Users", - NavItemId = 9, - SortOrder = 2, - Status = "Active" - }, - new - { - SubNavItemId = 9, - Code = "procurement.requisitions", - Href = "/dashboard/procurement/requisitions", - Label = "Requisitions", - NavItemId = 4, - SortOrder = 1, - Status = "Active" - }, - new - { - SubNavItemId = 10, - Code = "procurement.rfqs", - Href = "/dashboard/procurement/rfqs", - Label = "RFQs", - NavItemId = 4, - SortOrder = 2, - Status = "Active" - }, - new - { - SubNavItemId = 11, - Code = "procurement.purchase-orders", - Href = "/dashboard/procurement/purchase-orders", - Label = "Purchase Orders", - NavItemId = 4, - SortOrder = 3, - Status = "Active" - }, - new - { - SubNavItemId = 12, - Code = "procurement.purchase-returns", - Href = "/dashboard/procurement/purchase-returns", - Label = "Purchase Returns", - NavItemId = 4, - SortOrder = 4, - Status = "Active" - }); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.TaxSlab", b => - { - b.Property("TaxSlabId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("TaxSlabId")); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("EffectiveFrom") - .HasColumnType("timestamp with time zone"); - - b.Property("EffectiveTo") - .HasColumnType("timestamp with time zone"); - - b.Property("LowerBound") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.Property("Rate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("UpperBound") - .HasPrecision(18, 2) - .HasColumnType("numeric(18,2)"); - - b.HasKey("TaxSlabId"); - - b.HasIndex("EffectiveFrom"); - - b.ToTable("hr_tax_slabs", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Uom", b => - { - b.Property("UomId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("UomId")); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("UomId"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("uoms", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b => - { - b.Property("ConversionId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ConversionId")); - - b.Property("Factor") - .HasPrecision(18, 6) - .HasColumnType("numeric(18,6)"); - - b.Property("FromUomId") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("ToUomId") - .HasColumnType("integer"); - - b.HasKey("ConversionId"); - - b.HasIndex("FromUomId"); - - b.HasIndex("ToUomId"); - - b.HasIndex("ItemId", "FromUomId", "ToUomId") - .IsUnique(); - - b.ToTable("uom_conversions", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.User", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("UserId")); - - b.Property("AuthUserId") - .HasColumnType("uuid") - .HasColumnName("auth_user_id"); - - b.Property("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("character varying(320)"); - - b.Property("RoleId") - .HasColumnType("integer"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("Username") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.HasKey("UserId"); - - b.HasIndex("AuthUserId") - .IsUnique(); - - b.HasIndex("Email") - .IsUnique(); - - b.HasIndex("RoleId"); - - b.HasIndex("Username") - .IsUnique(); - - b.ToTable("users", (string)null); - - b.HasData( - new - { - UserId = 1, - DisplayName = "System", - Status = "Active", - Username = "system" - }); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Vendor", b => - { - b.Property("VendorId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("VendorId")); - - b.Property("Code") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("Currency") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(3) - .HasColumnType("character varying(3)") - .HasDefaultValue("LKR"); - - 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("TaxReg") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Terms") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.HasKey("VendorId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("vendors", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b => - { - b.Property("QuotationId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("QuotationId")); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("RfqId") - .HasColumnType("integer"); - - b.Property("VendorId") - .HasColumnType("integer"); - - b.HasKey("QuotationId"); - - b.HasIndex("VendorId"); - - b.HasIndex("RfqId", "VendorId") - .IsUnique(); - - b.ToTable("vendor_quotations", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotationLine", b => - { - b.Property("QuotationLineId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("QuotationLineId")); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("LeadDays") - .HasColumnType("integer"); - - b.Property("QuotationId") - .HasColumnType("integer"); - - b.Property("UnitPrice") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)"); - - b.HasKey("QuotationLineId"); - - b.HasIndex("ItemId"); - - b.HasIndex("QuotationId"); - - b.ToTable("vendor_quotation_lines", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b => - { - b.Property("WarehouseId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("WarehouseId")); - - b.Property("Code") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.HasKey("WarehouseId"); - - b.HasIndex("Code") - .IsUnique(); - - b.ToTable("warehouses", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.WorkShift", b => - { - b.Property("WorkShiftId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("WorkShiftId")); - - b.Property("BreakMinutes") - .HasColumnType("integer"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("EndTime") - .HasColumnType("interval"); - - b.Property("GraceMinutes") - .HasColumnType("integer"); - - b.Property("IsOvernight") - .HasColumnType("boolean"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("OtMultiplier") - .HasPrecision(6, 2) - .HasColumnType("numeric(6,2)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("xid") - .HasColumnName("xmin"); - - b.Property("StandardWorkingMinutes") - .HasColumnType("integer"); - - b.Property("StartTime") - .HasColumnType("interval"); - - b.Property("Status") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(20) - .HasColumnType("character varying(20)") - .HasDefaultValue("Active"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("WorkingDaysMask") - .HasColumnType("integer"); - - b.HasKey("WorkShiftId"); - - b.HasIndex("Code") - .IsUnique(); - - b.HasIndex("Status"); - - b.ToTable("hr_work_shifts", (string)null); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.AttendanceRecord", b => - { - b.HasOne("ERPCore.Domain.Entities.AttendanceUploadBatch", "AttendanceUploadBatch") - .WithMany() - .HasForeignKey("AttendanceUploadBatchId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.WorkShift", "WorkShift") - .WithMany() - .HasForeignKey("WorkShiftId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("AttendanceUploadBatch"); - - b.Navigation("Employee"); - - b.Navigation("WorkShift"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.AuditLog", b => - { - b.HasOne("ERPCore.Domain.Entities.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Batch", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b => - { - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany("Bins") - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - 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") - .WithMany() - .HasForeignKey("BranchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Employee", "HeadEmployee") - .WithMany() - .HasForeignKey("HeadEmployeeId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Department", "ParentDepartment") - .WithMany() - .HasForeignKey("ParentDepartmentId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Branch"); - - b.Navigation("HeadEmployee"); - - b.Navigation("ParentDepartment"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Employee", b => - { - b.HasOne("ERPCore.Domain.Entities.Branch", "Branch") - .WithMany() - .HasForeignKey("BranchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Department", "Department") - .WithMany() - .HasForeignKey("DepartmentId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Designation", "Designation") - .WithMany() - .HasForeignKey("DesignationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.EmploymentType", "EmploymentType") - .WithMany() - .HasForeignKey("EmploymentTypeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Employee", "ReportingManager") - .WithMany() - .HasForeignKey("ReportingManagerId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.User", "User") - .WithOne() - .HasForeignKey("ERPCore.Domain.Entities.Employee", "UserId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.WorkShift", "WorkShift") - .WithMany() - .HasForeignKey("WorkShiftId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Branch"); - - b.Navigation("Department"); - - b.Navigation("Designation"); - - b.Navigation("EmploymentType"); - - b.Navigation("ReportingManager"); - - b.Navigation("User"); - - b.Navigation("WorkShift"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeBankDetail", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Employee"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeDocument", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.HrDocumentType", "HrDocumentType") - .WithMany() - .HasForeignKey("HrDocumentTypeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - - b.Navigation("HrDocumentType"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeLoan", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructure", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructureLine", b => - { - b.HasOne("ERPCore.Domain.Entities.EmployeeSalaryStructure", "EmployeeSalaryStructure") - .WithMany("Lines") - .HasForeignKey("EmployeeSalaryStructureId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.SalaryComponent", "SalaryComponent") - .WithMany() - .HasForeignKey("SalaryComponentId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("EmployeeSalaryStructure"); - - b.Navigation("SalaryComponent"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Grn", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PurchaseOrder", "PurchaseOrder") - .WithMany() - .HasForeignKey("PoId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor") - .WithMany() - .HasForeignKey("VendorId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("PurchaseOrder"); - - b.Navigation("Vendor"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.GrnLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Batch", "Batch") - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", "Bin") - .WithMany() - .HasForeignKey("BinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Grn", "Grn") - .WithMany("Lines") - .HasForeignKey("GrnId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PoLine", "PoLine") - .WithMany() - .HasForeignKey("PoLineId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Uom", "Uom") - .WithMany() - .HasForeignKey("UomId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Batch"); - - b.Navigation("Bin"); - - b.Navigation("Grn"); - - b.Navigation("Item"); - - b.Navigation("PoLine"); - - b.Navigation("Uom"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Item", b => - { - b.HasOne("ERPCore.Domain.Entities.Uom", "BaseUom") - .WithMany() - .HasForeignKey("BaseUomId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Brand", "Brand") - .WithMany() - .HasForeignKey("BrandId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "DefaultVendor") - .WithMany() - .HasForeignKey("DefaultVendorId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.SubCategory", "SubCategory") - .WithMany() - .HasForeignKey("SubCategoryId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("BaseUom"); - - b.Navigation("Brand"); - - b.Navigation("Category"); - - b.Navigation("DefaultVendor"); - - b.Navigation("SubCategory"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany("ReorderSettings") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LeaveBalance", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.LeaveType", "LeaveType") - .WithMany() - .HasForeignKey("LeaveTypeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - - b.Navigation("LeaveType"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LeaveRequest", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.LeaveType", "LeaveType") - .WithMany() - .HasForeignKey("LeaveTypeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Employee"); - - b.Navigation("LeaveType"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.LoanInstallment", b => - { - b.HasOne("ERPCore.Domain.Entities.EmployeeLoan", "EmployeeLoan") - .WithMany("Installments") - .HasForeignKey("EmployeeLoanId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PayrollRun", "PayrollRun") - .WithMany() - .HasForeignKey("PayrollRunId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("EmployeeLoan"); - - b.Navigation("PayrollRun"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Employee", "Employee") - .WithMany() - .HasForeignKey("EmployeeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PayrollRun", "PayrollRun") - .WithMany("Lines") - .HasForeignKey("PayrollRunId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Employee"); - - b.Navigation("PayrollRun"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollLineComponent", b => - { - b.HasOne("ERPCore.Domain.Entities.PayrollLine", "PayrollLine") - .WithMany("Components") - .HasForeignKey("PayrollLineId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.SalaryComponent", "SalaryComponent") - .WithMany() - .HasForeignKey("SalaryComponentId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("PayrollLine"); - - b.Navigation("SalaryComponent"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollRun", b => - { - b.HasOne("ERPCore.Domain.Entities.Branch", "Branch") - .WithMany() - .HasForeignKey("BranchId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Branch"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Payslip", b => - { - b.HasOne("ERPCore.Domain.Entities.PayrollLine", "PayrollLine") - .WithOne() - .HasForeignKey("ERPCore.Domain.Entities.Payslip", "PayrollLineId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("PayrollLine"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Permission", b => - { - b.HasOne("ERPCore.Domain.Entities.NavItem", "NavItem") - .WithMany() - .HasForeignKey("NavItemId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("ERPCore.Domain.Entities.SubNavItem", "SubNavItem") - .WithMany() - .HasForeignKey("SubNavItemId") - .OnDelete(DeleteBehavior.Cascade); - - b.Navigation("NavItem"); - - b.Navigation("SubNavItem"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PoLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PurchaseOrder", "PurchaseOrder") - .WithMany("Lines") - .HasForeignKey("PoId") - .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("PurchaseOrder"); - - b.Navigation("Uom"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.ProductConfig", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "UpdatedByUser") - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("UpdatedByUser"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition") - .WithMany() - .HasForeignKey("RequisitionId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor") - .WithMany() - .HasForeignKey("VendorId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("Requisition"); - - b.Navigation("Vendor"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseReturn", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.ReasonCode", "ReasonCode") - .WithMany() - .HasForeignKey("ReasonCodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor") - .WithMany() - .HasForeignKey("VendorId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("ReasonCode"); - - b.Navigation("Vendor"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseReturnLine", b => - { - b.HasOne("ERPCore.Domain.Entities.GrnLine", "GrnLine") - .WithMany() - .HasForeignKey("GrnLineId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.PurchaseReturn", "Return") - .WithMany("Lines") - .HasForeignKey("ReturnId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("GrnLine"); - - b.Navigation("Item"); - - b.Navigation("Return"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Requisition", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Requester") - .WithMany() - .HasForeignKey("RequestedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Requester"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.RequisitionLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition") - .WithMany("Lines") - .HasForeignKey("RequisitionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Requisition"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Rfq", b => - { - b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition") - .WithMany() - .HasForeignKey("RequisitionId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Requisition"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.RfqLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Rfq", "Rfq") - .WithMany("Lines") - .HasForeignKey("RfqId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Rfq"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.RolePermission", b => - { - b.HasOne("ERPCore.Domain.Entities.Permission", "Permission") - .WithMany() - .HasForeignKey("PermissionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Role", "Role") - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Permission"); - - b.Navigation("Role"); - }); - - 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") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustment", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.ReasonCode", "ReasonCode") - .WithMany() - .HasForeignKey("ReasonCodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("ReasonCode"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockAdjustmentLine", b => - { - b.HasOne("ERPCore.Domain.Entities.StockAdjustment", "Adjustment") - .WithMany("Lines") - .HasForeignKey("AdjustmentId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Batch", null) - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("BinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Serial", null) - .WithMany() - .HasForeignKey("SerialId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Adjustment"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockCount", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockCountLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("BinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.StockCount", "Count") - .WithMany("Lines") - .HasForeignKey("CountId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Count"); - - b.Navigation("Item"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockLayer", b => - { - b.HasOne("ERPCore.Domain.Entities.Batch", "Batch") - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.GrnLine", "GrnLine") - .WithMany() - .HasForeignKey("GrnLineId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Serial", "Serial") - .WithMany() - .HasForeignKey("SerialId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse") - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Batch"); - - b.Navigation("GrnLine"); - - b.Navigation("Item"); - - b.Navigation("Serial"); - - b.Navigation("Warehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockLedger", b => - { - b.HasOne("ERPCore.Domain.Entities.Batch", null) - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("BinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", null) - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Serial", null) - .WithMany() - .HasForeignKey("SerialId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", null) - .WithMany() - .HasForeignKey("WarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransfer", b => - { - b.HasOne("ERPCore.Domain.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "DestWarehouse") - .WithMany() - .HasForeignKey("DestWarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Warehouse", "SrcWarehouse") - .WithMany() - .HasForeignKey("SrcWarehouseId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Creator"); - - b.Navigation("DestWarehouse"); - - b.Navigation("SrcWarehouse"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransferLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Batch", null) - .WithMany() - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("DestBinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Serial", null) - .WithMany() - .HasForeignKey("SerialId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.Bin", null) - .WithMany() - .HasForeignKey("SrcBinId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ERPCore.Domain.Entities.StockTransfer", "Transfer") - .WithMany("Lines") - .HasForeignKey("TransferId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Transfer"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SubCategory", b => - { - b.HasOne("ERPCore.Domain.Entities.Category", "Category") - .WithMany("SubCategories") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.SubNavItem", b => - { - b.HasOne("ERPCore.Domain.Entities.NavItem", "NavItem") - .WithMany("Children") - .HasForeignKey("NavItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("NavItem"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b => - { - b.HasOne("ERPCore.Domain.Entities.Uom", "FromUom") - .WithMany() - .HasForeignKey("FromUomId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany("UomConversions") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Uom", "ToUom") - .WithMany() - .HasForeignKey("ToUomId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("FromUom"); - - b.Navigation("Item"); - - b.Navigation("ToUom"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.User", b => - { - b.HasOne("ERPCore.Domain.Entities.Role", "Role") - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Role"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b => - { - b.HasOne("ERPCore.Domain.Entities.Rfq", "Rfq") - .WithMany("Quotations") - .HasForeignKey("RfqId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor") - .WithMany() - .HasForeignKey("VendorId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Rfq"); - - b.Navigation("Vendor"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotationLine", b => - { - b.HasOne("ERPCore.Domain.Entities.Item", "Item") - .WithMany() - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ERPCore.Domain.Entities.VendorQuotation", "Quotation") - .WithMany("Lines") - .HasForeignKey("QuotationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Item"); - - b.Navigation("Quotation"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Category", b => - { - b.Navigation("SubCategories"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeLoan", b => - { - b.Navigation("Installments"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.EmployeeSalaryStructure", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Grn", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Item", b => - { - b.Navigation("ReorderSettings"); - - b.Navigation("UomConversions"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.NavItem", b => - { - b.Navigation("Children"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollLine", b => - { - b.Navigation("Components"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PayrollRun", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseReturn", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Requisition", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Rfq", b => - { - b.Navigation("Lines"); - - b.Navigation("Quotations"); - }); - - 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"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockCount", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.StockTransfer", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b => - { - b.Navigation("Lines"); - }); - - modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b => - { - b.Navigation("Bins"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Backend/ERPCore/Migrations/20260728054611_InitialCreate1.cs b/Backend/ERPCore/Migrations/20260728054611_InitialCreate1.cs deleted file mode 100644 index 9f7d032..0000000 --- a/Backend/ERPCore/Migrations/20260728054611_InitialCreate1.cs +++ /dev/null @@ -1,3829 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional - -namespace ERPCore.Migrations -{ - /// - public partial class InitialCreate1 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "brands", - columns: table => new - { - BrandId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - 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_brands", x => x.BrandId); - }); - - migrationBuilder.CreateTable( - name: "categories", - columns: table => new - { - CategoryId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - 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_categories", x => x.CategoryId); - }); - - migrationBuilder.CreateTable( - name: "hr_attendance_upload_batches", - columns: table => new - { - AttendanceUploadBatchId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - PeriodStart = table.Column(type: "timestamp with time zone", nullable: false), - PeriodEnd = table.Column(type: "timestamp with time zone", nullable: false), - SourceType = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - OriginalFileName = table.Column(type: "character varying(260)", maxLength: 260, nullable: true), - UploadedBy = table.Column(type: "integer", nullable: false), - UploadedAt = table.Column(type: "timestamp with time zone", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - ConfirmedBy = table.Column(type: "integer", nullable: true), - ConfirmedAt = table.Column(type: "timestamp with time zone", nullable: true), - RowCountTotal = table.Column(type: "integer", nullable: false), - RowCountDuplicate = table.Column(type: "integer", nullable: false), - RowCountError = table.Column(type: "integer", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_attendance_upload_batches", x => x.AttendanceUploadBatchId); - }); - - migrationBuilder.CreateTable( - name: "hr_branches", - columns: table => new - { - BranchId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - Address = table.Column(type: "character varying(500)", maxLength: 500, 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_hr_branches", x => x.BranchId); - }); - - migrationBuilder.CreateTable( - name: "hr_designations", - columns: table => new - { - DesignationId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - 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_hr_designations", x => x.DesignationId); - }); - - migrationBuilder.CreateTable( - name: "hr_document_types", - columns: table => new - { - HrDocumentTypeId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - Category = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - RequiredAtOnboarding = table.Column(type: "boolean", nullable: false), - ExpiryTracked = table.Column(type: "boolean", nullable: false), - 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_hr_document_types", x => x.HrDocumentTypeId); - }); - - migrationBuilder.CreateTable( - name: "hr_employment_types", - columns: table => new - { - EmploymentTypeId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - 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_hr_employment_types", x => x.EmploymentTypeId); - }); - - migrationBuilder.CreateTable( - name: "hr_leave_types", - columns: table => new - { - LeaveTypeId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - IsPaid = table.Column(type: "boolean", nullable: false), - CountsAsNoPay = table.Column(type: "boolean", nullable: false), - AccrualPerYear = table.Column(type: "numeric(6,2)", precision: 6, scale: 2, nullable: false), - CarryForwardAllowed = table.Column(type: "boolean", nullable: false), - MaxCarryForwardDays = table.Column(type: "integer", nullable: true), - RequiresApproval = table.Column(type: "boolean", nullable: false), - 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_hr_leave_types", x => x.LeaveTypeId); - }); - - migrationBuilder.CreateTable( - name: "hr_payroll_statutory_settings", - columns: table => new - { - PayrollStatutorySettingId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EpfEmployeeRate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - EpfEmployerRate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - EtfEmployerRate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - OtMultiplierDefault = table.Column(type: "numeric(6,2)", precision: 6, scale: 2, nullable: false), - EffectiveFrom = table.Column(type: "timestamp with time zone", nullable: false), - EffectiveTo = table.Column(type: "timestamp with time zone", nullable: true), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_payroll_statutory_settings", x => x.PayrollStatutorySettingId); - }); - - migrationBuilder.CreateTable( - name: "hr_salary_components", - columns: table => new - { - SalaryComponentId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - ComponentType = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - IsTaxable = table.Column(type: "boolean", nullable: false), - IsEpfEtfApplicable = table.Column(type: "boolean", nullable: false), - 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_hr_salary_components", x => x.SalaryComponentId); - }); - - migrationBuilder.CreateTable( - name: "hr_tax_slabs", - columns: table => new - { - TaxSlabId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EffectiveFrom = table.Column(type: "timestamp with time zone", nullable: false), - EffectiveTo = table.Column(type: "timestamp with time zone", nullable: true), - LowerBound = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), - UpperBound = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: true), - Rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_tax_slabs", x => x.TaxSlabId); - }); - - migrationBuilder.CreateTable( - name: "hr_work_shifts", - columns: table => new - { - WorkShiftId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - StartTime = table.Column(type: "interval", nullable: false), - EndTime = table.Column(type: "interval", nullable: false), - IsOvernight = table.Column(type: "boolean", nullable: false), - GraceMinutes = table.Column(type: "integer", nullable: false), - BreakMinutes = table.Column(type: "integer", nullable: false), - StandardWorkingMinutes = table.Column(type: "integer", nullable: false), - OtMultiplier = table.Column(type: "numeric(6,2)", precision: 6, scale: 2, nullable: false), - WorkingDaysMask = table.Column(type: "integer", nullable: false), - 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_hr_work_shifts", x => x.WorkShiftId); - }); - - migrationBuilder.CreateTable( - name: "item_types", - columns: table => new - { - ItemTypeId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - 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_item_types", x => x.ItemTypeId); - }); - - migrationBuilder.CreateTable( - name: "journal_entry_stubs", - columns: table => new - { - JournalId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - SourceDocType = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), - SourceDocId = table.Column(type: "integer", nullable: false), - DebitAccount = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - CreditAccount = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Amount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_journal_entry_stubs", x => x.JournalId); - }); - - migrationBuilder.CreateTable( - name: "nav_items", - columns: table => new - { - NavItemId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - Label = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - Icon = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - Href = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - SortOrder = table.Column(type: "integer", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Active") - }, - constraints: table => - { - table.PrimaryKey("PK_nav_items", x => x.NavItemId); - }); - - migrationBuilder.CreateTable( - name: "number_sequences", - columns: table => new - { - SequenceId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - doc_type = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), - year = table.Column(type: "integer", nullable: false), - last_number = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_number_sequences", x => x.SequenceId); - }); - - migrationBuilder.CreateTable( - name: "reason_codes", - columns: table => new - { - ReasonCodeId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Description = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - Context = table.Column(type: "character varying(20)", maxLength: 20, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_reason_codes", x => x.ReasonCodeId); - }); - - migrationBuilder.CreateTable( - name: "roles", - columns: table => new - { - RoleId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - auth_role_id = table.Column(type: "uuid", nullable: false), - Code = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - IsSystemRole = table.Column(type: "boolean", nullable: false, defaultValue: false), - 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_roles", x => x.RoleId); - }); - - migrationBuilder.CreateTable( - name: "uoms", - columns: table => new - { - UomId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(50)", maxLength: 50, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_uoms", x => x.UomId); - }); - - migrationBuilder.CreateTable( - name: "vendors", - columns: table => new - { - VendorId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - Terms = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - TaxReg = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - Currency = table.Column(type: "character varying(3)", maxLength: 3, nullable: false, defaultValue: "LKR"), - 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_vendors", x => x.VendorId); - }); - - migrationBuilder.CreateTable( - name: "warehouses", - columns: table => new - { - WarehouseId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_warehouses", x => x.WarehouseId); - }); - - migrationBuilder.CreateTable( - name: "subcategories", - columns: table => new - { - SubCategoryId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - CategoryId = table.Column(type: "integer", nullable: false), - 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_subcategories", x => x.SubCategoryId); - table.ForeignKey( - name: "FK_subcategories_categories_CategoryId", - column: x => x.CategoryId, - principalTable: "categories", - principalColumn: "CategoryId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_payroll_runs", - columns: table => new - { - PayrollRunId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - PeriodYear = table.Column(type: "integer", nullable: false), - PeriodMonth = table.Column(type: "integer", nullable: false), - BranchId = table.Column(type: "integer", nullable: true), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - GeneratedBy = table.Column(type: "integer", nullable: false), - GeneratedAt = table.Column(type: "timestamp with time zone", nullable: false), - ApprovedBy = table.Column(type: "integer", nullable: true), - ApprovedAt = table.Column(type: "timestamp with time zone", nullable: true), - LockedBy = table.Column(type: "integer", nullable: true), - LockedAt = table.Column(type: "timestamp with time zone", nullable: true), - UnlockedBy = table.Column(type: "integer", nullable: true), - UnlockedAt = table.Column(type: "timestamp with time zone", nullable: true), - UnlockReason = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_payroll_runs", x => x.PayrollRunId); - table.ForeignKey( - name: "FK_hr_payroll_runs_hr_branches_BranchId", - column: x => x.BranchId, - principalTable: "hr_branches", - principalColumn: "BranchId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "sub_nav_items", - columns: table => new - { - SubNavItemId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - NavItemId = table.Column(type: "integer", nullable: false), - Code = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - Label = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - Icon = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - Href = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - SortOrder = table.Column(type: "integer", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Active") - }, - constraints: table => - { - table.PrimaryKey("PK_sub_nav_items", x => x.SubNavItemId); - table.ForeignKey( - name: "FK_sub_nav_items_nav_items_NavItemId", - column: x => x.NavItemId, - principalTable: "nav_items", - principalColumn: "NavItemId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "users", - columns: table => new - { - UserId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Username = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - DisplayName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - auth_user_id = table.Column(type: "uuid", nullable: true), - Email = table.Column(type: "character varying(320)", maxLength: 320, nullable: true), - RoleId = table.Column(type: "integer", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_users", x => x.UserId); - table.ForeignKey( - name: "FK_users_roles_RoleId", - column: x => x.RoleId, - principalTable: "roles", - principalColumn: "RoleId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "bins", - columns: table => new - { - BinId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - WarehouseId = table.Column(type: "integer", nullable: false), - Code = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - BinType = table.Column(type: "character varying(50)", maxLength: 50, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_bins", x => x.BinId); - table.ForeignKey( - name: "FK_bins_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "customers", - columns: table => new - { - CustomerId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - CustomerCode = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - CustomerType = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "B2C"), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - DisplayName = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - Phone = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), - Email = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - AddressLine1 = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), - AddressLine2 = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), - City = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - Country = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - TaxRegistrationNo = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - CreditLimit = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - CreditDays = table.Column(type: "integer", nullable: false), - DefaultWarehouseId = table.Column(type: "integer", 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_customers", x => x.CustomerId); - table.ForeignKey( - name: "FK_customers_warehouses_DefaultWarehouseId", - column: x => x.DefaultWarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "items", - columns: table => new - { - ItemId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Sku = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - CategoryId = table.Column(type: "integer", nullable: false), - SubCategoryId = table.Column(type: "integer", nullable: true), - BrandId = table.Column(type: "integer", nullable: true), - BaseUomId = table.Column(type: "integer", nullable: false), - DefaultVendorId = table.Column(type: "integer", nullable: true), - StockNature = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - TrackingMode = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - TaxClass = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), - SalePrice = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, 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_items", x => x.ItemId); - table.ForeignKey( - name: "FK_items_brands_BrandId", - column: x => x.BrandId, - principalTable: "brands", - principalColumn: "BrandId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_items_categories_CategoryId", - column: x => x.CategoryId, - principalTable: "categories", - principalColumn: "CategoryId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_items_subcategories_SubCategoryId", - column: x => x.SubCategoryId, - principalTable: "subcategories", - principalColumn: "SubCategoryId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_items_uoms_BaseUomId", - column: x => x.BaseUomId, - principalTable: "uoms", - principalColumn: "UomId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_items_vendors_DefaultVendorId", - column: x => x.DefaultVendorId, - principalTable: "vendors", - principalColumn: "VendorId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "permissions", - columns: table => new - { - PermissionId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(80)", maxLength: 80, nullable: false), - NavItemId = table.Column(type: "integer", nullable: true), - SubNavItemId = table.Column(type: "integer", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_permissions", x => x.PermissionId); - table.ForeignKey( - name: "FK_permissions_nav_items_NavItemId", - column: x => x.NavItemId, - principalTable: "nav_items", - principalColumn: "NavItemId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_permissions_sub_nav_items_SubNavItemId", - column: x => x.SubNavItemId, - principalTable: "sub_nav_items", - principalColumn: "SubNavItemId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "audit_logs", - columns: table => new - { - AuditId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - UserId = table.Column(type: "integer", nullable: false), - EntityType = table.Column(type: "character varying(80)", maxLength: 80, nullable: false), - EntityId = table.Column(type: "integer", nullable: false), - Action = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), - ChangeSet = table.Column(type: "jsonb", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_audit_logs", x => x.AuditId); - table.ForeignKey( - name: "FK_audit_logs_users_UserId", - column: x => x.UserId, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "product_config", - columns: table => new - { - ConfigId = table.Column(type: "integer", nullable: false), - SubcategoriesEnabled = table.Column(type: "boolean", nullable: false, defaultValue: true), - BrandsEnabled = table.Column(type: "boolean", nullable: false, defaultValue: true), - ItemTypesEnabled = table.Column(type: "boolean", nullable: false, defaultValue: true), - UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true), - UpdatedBy = table.Column(type: "integer", nullable: true), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_product_config", x => x.ConfigId); - table.CheckConstraint("ck_product_config_singleton", "\"ConfigId\" = 1"); - table.ForeignKey( - name: "FK_product_config_users_UpdatedBy", - column: x => x.UpdatedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "purchase_returns", - columns: table => new - { - ReturnId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - VendorId = table.Column(type: "integer", nullable: false), - WarehouseId = table.Column(type: "integer", nullable: false), - ReasonCodeId = table.Column(type: "integer", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_purchase_returns", x => x.ReturnId); - table.ForeignKey( - name: "FK_purchase_returns_reason_codes_ReasonCodeId", - column: x => x.ReasonCodeId, - principalTable: "reason_codes", - principalColumn: "ReasonCodeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_purchase_returns_users_CreatedBy", - column: x => x.CreatedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_purchase_returns_vendors_VendorId", - column: x => x.VendorId, - principalTable: "vendors", - principalColumn: "VendorId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_purchase_returns_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "requisitions", - columns: table => new - { - RequisitionId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - RequestedBy = table.Column(type: "integer", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_requisitions", x => x.RequisitionId); - table.ForeignKey( - name: "FK_requisitions_users_RequestedBy", - column: x => x.RequestedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "stock_adjustments", - columns: table => new - { - AdjustmentId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - WarehouseId = table.Column(type: "integer", nullable: false), - ReasonCodeId = table.Column(type: "integer", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_stock_adjustments", x => x.AdjustmentId); - table.ForeignKey( - name: "FK_stock_adjustments_reason_codes_ReasonCodeId", - column: x => x.ReasonCodeId, - principalTable: "reason_codes", - principalColumn: "ReasonCodeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_adjustments_users_CreatedBy", - column: x => x.CreatedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_adjustments_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "stock_counts", - columns: table => new - { - CountId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - WarehouseId = table.Column(type: "integer", nullable: false), - CountType = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_stock_counts", x => x.CountId); - table.ForeignKey( - name: "FK_stock_counts_users_CreatedBy", - column: x => x.CreatedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_counts_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "stock_transfers", - columns: table => new - { - TransferId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - SrcWarehouseId = table.Column(type: "integer", nullable: false), - DestWarehouseId = table.Column(type: "integer", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_stock_transfers", x => x.TransferId); - table.ForeignKey( - name: "FK_stock_transfers_users_CreatedBy", - column: x => x.CreatedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_transfers_warehouses_DestWarehouseId", - column: x => x.DestWarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_transfers_warehouses_SrcWarehouseId", - column: x => x.SrcWarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "sales_invoices", - columns: table => new - { - SalesInvoiceId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - InvoiceNo = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - InvoiceDate = 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), - CustomerSnapshotTaxNo = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - WarehouseId = table.Column(type: "integer", nullable: false), - InvoiceType = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "B2C"), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Draft"), - Subtotal = 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), - RoundOff = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - NetPayable = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - PaidAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - BalanceAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatorUserId = table.Column(type: "integer", nullable: true), - 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_sales_invoices", x => x.SalesInvoiceId); - table.ForeignKey( - name: "FK_sales_invoices_customers_CustomerId", - column: x => x.CustomerId, - principalTable: "customers", - principalColumn: "CustomerId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_sales_invoices_users_CreatorUserId", - column: x => x.CreatorUserId, - principalTable: "users", - principalColumn: "UserId"); - table.ForeignKey( - name: "FK_sales_invoices_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "sales_slips", - columns: table => new - { - SalesSlipId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - SlipNo = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - SlipDate = 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), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Draft"), - Subtotal = 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), - PaidAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - BalanceAmount = 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_sales_slips", x => x.SalesSlipId); - table.ForeignKey( - name: "FK_sales_slips_customers_CustomerId", - column: x => x.CustomerId, - principalTable: "customers", - principalColumn: "CustomerId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_sales_slips_users_CashierUserId", - column: x => x.CashierUserId, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_sales_slips_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "batches", - columns: table => new - { - BatchId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ItemId = table.Column(type: "integer", nullable: false), - BatchNo = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - ExpiryDate = table.Column(type: "date", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_batches", x => x.BatchId); - table.ForeignKey( - name: "FK_batches_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "item_reorders", - columns: table => new - { - ReorderId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ItemId = table.Column(type: "integer", nullable: false), - WarehouseId = table.Column(type: "integer", nullable: false), - ReorderPoint = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - ReorderQty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_item_reorders", x => x.ReorderId); - table.ForeignKey( - name: "FK_item_reorders_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_item_reorders_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "serials", - columns: table => new - { - SerialId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ItemId = table.Column(type: "integer", nullable: false), - SerialNo = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_serials", x => x.SerialId); - table.ForeignKey( - name: "FK_serials_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "uom_conversions", - columns: table => new - { - ConversionId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ItemId = table.Column(type: "integer", nullable: false), - FromUomId = table.Column(type: "integer", nullable: false), - ToUomId = table.Column(type: "integer", nullable: false), - Factor = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_uom_conversions", x => x.ConversionId); - table.ForeignKey( - name: "FK_uom_conversions_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_uom_conversions_uoms_FromUomId", - column: x => x.FromUomId, - principalTable: "uoms", - principalColumn: "UomId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_uom_conversions_uoms_ToUomId", - column: x => x.ToUomId, - principalTable: "uoms", - principalColumn: "UomId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "role_permissions", - columns: table => new - { - RoleId = table.Column(type: "integer", nullable: false), - PermissionId = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_role_permissions", x => new { x.RoleId, x.PermissionId }); - table.ForeignKey( - name: "FK_role_permissions_permissions_PermissionId", - column: x => x.PermissionId, - principalTable: "permissions", - principalColumn: "PermissionId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_role_permissions_roles_RoleId", - column: x => x.RoleId, - principalTable: "roles", - principalColumn: "RoleId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "purchase_orders", - columns: table => new - { - PoId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - VendorId = table.Column(type: "integer", nullable: false), - RequisitionId = table.Column(type: "integer", nullable: true), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - ApprovalRequired = table.Column(type: "boolean", nullable: false), - CreatedBy = table.Column(type: "integer", 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_purchase_orders", x => x.PoId); - table.ForeignKey( - name: "FK_purchase_orders_requisitions_RequisitionId", - column: x => x.RequisitionId, - principalTable: "requisitions", - principalColumn: "RequisitionId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_purchase_orders_users_CreatedBy", - column: x => x.CreatedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_purchase_orders_vendors_VendorId", - column: x => x.VendorId, - principalTable: "vendors", - principalColumn: "VendorId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "requisition_lines", - columns: table => new - { - ReqLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - RequisitionId = table.Column(type: "integer", nullable: false), - ItemId = table.Column(type: "integer", nullable: false), - Qty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - RequiredBy = table.Column(type: "date", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_requisition_lines", x => x.ReqLineId); - table.ForeignKey( - name: "FK_requisition_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_requisition_lines_requisitions_RequisitionId", - column: x => x.RequisitionId, - principalTable: "requisitions", - principalColumn: "RequisitionId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "rfqs", - columns: table => new - { - RfqId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - RequisitionId = table.Column(type: "integer", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_rfqs", x => x.RfqId); - table.ForeignKey( - name: "FK_rfqs_requisitions_RequisitionId", - column: x => x.RequisitionId, - principalTable: "requisitions", - principalColumn: "RequisitionId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "stock_count_lines", - columns: table => new - { - CountLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - CountId = table.Column(type: "integer", nullable: false), - ItemId = table.Column(type: "integer", nullable: false), - BinId = table.Column(type: "integer", nullable: true), - SystemQty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - CountedQty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true), - Variance = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_stock_count_lines", x => x.CountLineId); - table.ForeignKey( - name: "FK_stock_count_lines_bins_BinId", - column: x => x.BinId, - principalTable: "bins", - principalColumn: "BinId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_count_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_count_lines_stock_counts_CountId", - column: x => x.CountId, - principalTable: "stock_counts", - principalColumn: "CountId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "sales_invoice_lines", - columns: table => new - { - SalesInvoiceLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - SalesInvoiceId = 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), - FreeQty = 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), - BaseCost = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - PriceSource = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - DiscountMode = table.Column(type: "integer", nullable: false), - DiscountPct = table.Column(type: "numeric(9,4)", precision: 9, scale: 4, nullable: false), - DiscountAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - NetUnitPrice = 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), - TaxPct = table.Column(type: "numeric(9,4)", precision: 9, scale: 4, nullable: false), - TaxAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - IsFreeIssue = table.Column(type: "boolean", nullable: false), - ParentLineId = table.Column(type: "integer", nullable: true), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_sales_invoice_lines", x => x.SalesInvoiceLineId); - table.ForeignKey( - name: "FK_sales_invoice_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_sales_invoice_lines_sales_invoices_SalesInvoiceId", - column: x => x.SalesInvoiceId, - principalTable: "sales_invoices", - principalColumn: "SalesInvoiceId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_sales_invoice_lines_uoms_UomId", - column: x => x.UomId, - principalTable: "uoms", - principalColumn: "UomId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_sales_invoice_lines_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "sales_slip_lines", - columns: table => new - { - SalesSlipLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - SalesSlipId = 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), - FreeQty = 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), - BaseCost = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - PriceSource = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - DiscountMode = table.Column(type: "integer", nullable: false), - DiscountPct = table.Column(type: "numeric(9,4)", precision: 9, scale: 4, nullable: false), - DiscountAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - NetUnitPrice = 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), - TaxPct = table.Column(type: "numeric(9,4)", precision: 9, scale: 4, nullable: false), - TaxAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - IsFreeIssue = table.Column(type: "boolean", nullable: false), - ParentLineId = table.Column(type: "integer", nullable: true), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_sales_slip_lines", x => x.SalesSlipLineId); - table.ForeignKey( - name: "FK_sales_slip_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_sales_slip_lines_sales_slips_SalesSlipId", - column: x => x.SalesSlipId, - principalTable: "sales_slips", - principalColumn: "SalesSlipId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_sales_slip_lines_uoms_UomId", - column: x => x.UomId, - principalTable: "uoms", - principalColumn: "UomId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_sales_slip_lines_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "stock_adjustment_lines", - columns: table => new - { - AdjLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - AdjustmentId = table.Column(type: "integer", nullable: false), - ItemId = table.Column(type: "integer", nullable: false), - BinId = table.Column(type: "integer", nullable: true), - BatchId = table.Column(type: "integer", nullable: true), - SerialId = table.Column(type: "integer", nullable: true), - QtyDelta = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_stock_adjustment_lines", x => x.AdjLineId); - table.ForeignKey( - name: "FK_stock_adjustment_lines_batches_BatchId", - column: x => x.BatchId, - principalTable: "batches", - principalColumn: "BatchId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_adjustment_lines_bins_BinId", - column: x => x.BinId, - principalTable: "bins", - principalColumn: "BinId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_adjustment_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_adjustment_lines_serials_SerialId", - column: x => x.SerialId, - principalTable: "serials", - principalColumn: "SerialId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_adjustment_lines_stock_adjustments_AdjustmentId", - column: x => x.AdjustmentId, - principalTable: "stock_adjustments", - principalColumn: "AdjustmentId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "stock_ledger", - columns: table => new - { - LedgerId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ItemId = table.Column(type: "integer", nullable: false), - WarehouseId = table.Column(type: "integer", nullable: false), - BinId = table.Column(type: "integer", nullable: true), - BatchId = table.Column(type: "integer", nullable: true), - SerialId = table.Column(type: "integer", nullable: true), - UserId = table.Column(type: "integer", nullable: false), - Direction = table.Column(type: "character varying(5)", maxLength: 5, nullable: false), - QtyBase = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - UnitCost = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false), - Value = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - RunningBalance = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - SourceDocType = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), - SourceDocId = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_stock_ledger", x => x.LedgerId); - table.ForeignKey( - name: "FK_stock_ledger_batches_BatchId", - column: x => x.BatchId, - principalTable: "batches", - principalColumn: "BatchId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_ledger_bins_BinId", - column: x => x.BinId, - principalTable: "bins", - principalColumn: "BinId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_ledger_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_ledger_serials_SerialId", - column: x => x.SerialId, - principalTable: "serials", - principalColumn: "SerialId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_ledger_users_UserId", - column: x => x.UserId, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_ledger_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "stock_transfer_lines", - columns: table => new - { - TransferLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - TransferId = table.Column(type: "integer", nullable: false), - ItemId = table.Column(type: "integer", nullable: false), - SrcBinId = table.Column(type: "integer", nullable: true), - DestBinId = table.Column(type: "integer", nullable: true), - BatchId = table.Column(type: "integer", nullable: true), - SerialId = table.Column(type: "integer", nullable: true), - Qty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - UnitCost = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: true), - QtyReceived = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_stock_transfer_lines", x => x.TransferLineId); - table.ForeignKey( - name: "FK_stock_transfer_lines_batches_BatchId", - column: x => x.BatchId, - principalTable: "batches", - principalColumn: "BatchId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_transfer_lines_bins_DestBinId", - column: x => x.DestBinId, - principalTable: "bins", - principalColumn: "BinId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_transfer_lines_bins_SrcBinId", - column: x => x.SrcBinId, - principalTable: "bins", - principalColumn: "BinId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_transfer_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_transfer_lines_serials_SerialId", - column: x => x.SerialId, - principalTable: "serials", - principalColumn: "SerialId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_transfer_lines_stock_transfers_TransferId", - column: x => x.TransferId, - principalTable: "stock_transfers", - principalColumn: "TransferId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "grns", - columns: table => new - { - GrnId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - PoId = table.Column(type: "integer", nullable: true), - VendorId = table.Column(type: "integer", nullable: false), - WarehouseId = table.Column(type: "integer", nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - PostedAt = table.Column(type: "timestamp with time zone", nullable: true), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_grns", x => x.GrnId); - table.ForeignKey( - name: "FK_grns_purchase_orders_PoId", - column: x => x.PoId, - principalTable: "purchase_orders", - principalColumn: "PoId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_grns_users_CreatedBy", - column: x => x.CreatedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_grns_vendors_VendorId", - column: x => x.VendorId, - principalTable: "vendors", - principalColumn: "VendorId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_grns_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "po_lines", - columns: table => new - { - PoLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - PoId = 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), - Tax = table.Column(type: "numeric(9,4)", precision: 9, scale: 4, nullable: false), - QtyReceived = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_po_lines", x => x.PoLineId); - table.ForeignKey( - name: "FK_po_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_po_lines_purchase_orders_PoId", - column: x => x.PoId, - principalTable: "purchase_orders", - principalColumn: "PoId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_po_lines_uoms_UomId", - column: x => x.UomId, - principalTable: "uoms", - principalColumn: "UomId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_po_lines_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "rfq_lines", - columns: table => new - { - RfqLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - RfqId = table.Column(type: "integer", nullable: false), - ItemId = table.Column(type: "integer", nullable: false), - Qty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_rfq_lines", x => x.RfqLineId); - table.ForeignKey( - name: "FK_rfq_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_rfq_lines_rfqs_RfqId", - column: x => x.RfqId, - principalTable: "rfqs", - principalColumn: "RfqId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "vendor_quotations", - columns: table => new - { - QuotationId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - RfqId = table.Column(type: "integer", nullable: false), - VendorId = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_vendor_quotations", x => x.QuotationId); - table.ForeignKey( - name: "FK_vendor_quotations_rfqs_RfqId", - column: x => x.RfqId, - principalTable: "rfqs", - principalColumn: "RfqId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_vendor_quotations_vendors_VendorId", - column: x => x.VendorId, - principalTable: "vendors", - principalColumn: "VendorId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "grn_lines", - columns: table => new - { - GrnLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - GrnId = table.Column(type: "integer", nullable: false), - PoLineId = table.Column(type: "integer", nullable: true), - ItemId = table.Column(type: "integer", nullable: false), - UomId = table.Column(type: "integer", nullable: false), - BinId = table.Column(type: "integer", nullable: true), - BatchId = table.Column(type: "integer", nullable: true), - Qty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - UnitCost = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false), - PoUnitPrice = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: true), - DiscountPct = table.Column(type: "numeric(9,4)", precision: 9, scale: 4, nullable: false), - NetUnitCost = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false), - VatPct = table.Column(type: "numeric(9,4)", precision: 9, scale: 4, nullable: false), - VatAmount = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - ReceivedValue = 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), - HoldStatus = table.Column(type: "character varying(20)", maxLength: 20, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_grn_lines", x => x.GrnLineId); - table.ForeignKey( - name: "FK_grn_lines_batches_BatchId", - column: x => x.BatchId, - principalTable: "batches", - principalColumn: "BatchId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_grn_lines_bins_BinId", - column: x => x.BinId, - principalTable: "bins", - principalColumn: "BinId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_grn_lines_grns_GrnId", - column: x => x.GrnId, - principalTable: "grns", - principalColumn: "GrnId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_grn_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_grn_lines_po_lines_PoLineId", - column: x => x.PoLineId, - principalTable: "po_lines", - principalColumn: "PoLineId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_grn_lines_uoms_UomId", - column: x => x.UomId, - principalTable: "uoms", - principalColumn: "UomId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "vendor_quotation_lines", - columns: table => new - { - QuotationLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - QuotationId = table.Column(type: "integer", nullable: false), - ItemId = table.Column(type: "integer", nullable: false), - UnitPrice = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - LeadDays = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_vendor_quotation_lines", x => x.QuotationLineId); - table.ForeignKey( - name: "FK_vendor_quotation_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_vendor_quotation_lines_vendor_quotations_QuotationId", - column: x => x.QuotationId, - principalTable: "vendor_quotations", - principalColumn: "QuotationId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "purchase_return_lines", - columns: table => new - { - ReturnLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ReturnId = table.Column(type: "integer", nullable: false), - GrnLineId = table.Column(type: "integer", nullable: true), - ItemId = table.Column(type: "integer", nullable: false), - Qty = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_purchase_return_lines", x => x.ReturnLineId); - table.ForeignKey( - name: "FK_purchase_return_lines_grn_lines_GrnLineId", - column: x => x.GrnLineId, - principalTable: "grn_lines", - principalColumn: "GrnLineId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_purchase_return_lines_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_purchase_return_lines_purchase_returns_ReturnId", - column: x => x.ReturnId, - principalTable: "purchase_returns", - principalColumn: "ReturnId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "stock_layers", - columns: table => new - { - LayerId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ItemId = table.Column(type: "integer", nullable: false), - WarehouseId = table.Column(type: "integer", nullable: false), - BatchId = table.Column(type: "integer", nullable: true), - SerialId = table.Column(type: "integer", nullable: true), - GrnLineId = table.Column(type: "integer", nullable: true), - QtyReceived = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - QtyRemaining = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - UnitCost = table.Column(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false), - ReceiptDate = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_stock_layers", x => x.LayerId); - table.ForeignKey( - name: "FK_stock_layers_batches_BatchId", - column: x => x.BatchId, - principalTable: "batches", - principalColumn: "BatchId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_layers_grn_lines_GrnLineId", - column: x => x.GrnLineId, - principalTable: "grn_lines", - principalColumn: "GrnLineId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_layers_items_ItemId", - column: x => x.ItemId, - principalTable: "items", - principalColumn: "ItemId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_layers_serials_SerialId", - column: x => x.SerialId, - principalTable: "serials", - principalColumn: "SerialId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_stock_layers_warehouses_WarehouseId", - column: x => x.WarehouseId, - principalTable: "warehouses", - principalColumn: "WarehouseId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_attendance_records", - columns: table => new - { - AttendanceRecordId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - AttendanceUploadBatchId = table.Column(type: "integer", nullable: true), - EmployeeId = table.Column(type: "integer", nullable: false), - AttendanceDate = table.Column(type: "timestamp with time zone", nullable: false), - CheckIn = table.Column(type: "interval", nullable: true), - CheckOut = table.Column(type: "interval", nullable: true), - WorkShiftId = table.Column(type: "integer", nullable: false), - WorkingMinutes = table.Column(type: "integer", nullable: false), - LateMinutes = table.Column(type: "integer", nullable: false), - EarlyLeaveMinutes = table.Column(type: "integer", nullable: false), - OvertimeMinutes = table.Column(type: "integer", nullable: false), - AttendanceStatus = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - RowValidationStatus = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - DuplicateOfAttendanceRecordId = table.Column(type: "integer", nullable: true), - Notes = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - IsManualOverride = table.Column(type: "boolean", nullable: false), - EditedBy = table.Column(type: "integer", nullable: true), - EditedAt = table.Column(type: "timestamp with time zone", nullable: true), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_attendance_records", x => x.AttendanceRecordId); - table.ForeignKey( - name: "FK_hr_attendance_records_hr_attendance_upload_batches_Attendan~", - column: x => x.AttendanceUploadBatchId, - principalTable: "hr_attendance_upload_batches", - principalColumn: "AttendanceUploadBatchId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_hr_attendance_records_hr_work_shifts_WorkShiftId", - column: x => x.WorkShiftId, - principalTable: "hr_work_shifts", - principalColumn: "WorkShiftId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_departments", - columns: table => new - { - DepartmentId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Code = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - Name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - ParentDepartmentId = table.Column(type: "integer", nullable: true), - HeadEmployeeId = table.Column(type: "integer", nullable: true), - BranchId = table.Column(type: "integer", 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_hr_departments", x => x.DepartmentId); - table.ForeignKey( - name: "FK_hr_departments_hr_branches_BranchId", - column: x => x.BranchId, - principalTable: "hr_branches", - principalColumn: "BranchId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_departments_hr_departments_ParentDepartmentId", - column: x => x.ParentDepartmentId, - principalTable: "hr_departments", - principalColumn: "DepartmentId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_employees", - columns: table => new - { - EmployeeId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EmployeeCode = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - FullName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - Nic = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), - DateOfBirth = table.Column(type: "timestamp with time zone", nullable: true), - Gender = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), - Nationality = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - ProfilePhotoPath = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - Email = table.Column(type: "character varying(320)", maxLength: 320, nullable: true), - PersonalMobile = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), - AddressLine1 = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - AddressLine2 = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - City = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - PostalCode = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), - Country = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - EmergencyContactName = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - EmergencyContactRelationship = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - EmergencyContactPhone = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), - HireDate = table.Column(type: "timestamp with time zone", nullable: false), - ConfirmationDate = table.Column(type: "timestamp with time zone", nullable: true), - LastWorkingDate = table.Column(type: "timestamp with time zone", nullable: true), - DepartmentId = table.Column(type: "integer", nullable: false), - DesignationId = table.Column(type: "integer", nullable: false), - EmploymentTypeId = table.Column(type: "integer", nullable: false), - BranchId = table.Column(type: "integer", nullable: true), - WorkShiftId = table.Column(type: "integer", nullable: false), - ReportingManagerId = table.Column(type: "integer", nullable: true), - EpfNumber = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), - EtfNumber = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), - TaxIdentificationNumber = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), - UserId = table.Column(type: "integer", nullable: true), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Active"), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - UpdatedBy = table.Column(type: "integer", nullable: true), - UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_employees", x => x.EmployeeId); - table.ForeignKey( - name: "FK_hr_employees_hr_branches_BranchId", - column: x => x.BranchId, - principalTable: "hr_branches", - principalColumn: "BranchId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_employees_hr_departments_DepartmentId", - column: x => x.DepartmentId, - principalTable: "hr_departments", - principalColumn: "DepartmentId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_employees_hr_designations_DesignationId", - column: x => x.DesignationId, - principalTable: "hr_designations", - principalColumn: "DesignationId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_employees_hr_employees_ReportingManagerId", - column: x => x.ReportingManagerId, - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_employees_hr_employment_types_EmploymentTypeId", - column: x => x.EmploymentTypeId, - principalTable: "hr_employment_types", - principalColumn: "EmploymentTypeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_employees_hr_work_shifts_WorkShiftId", - column: x => x.WorkShiftId, - principalTable: "hr_work_shifts", - principalColumn: "WorkShiftId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_employees_users_UserId", - column: x => x.UserId, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_employee_bank_details", - columns: table => new - { - EmployeeBankDetailId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EmployeeId = table.Column(type: "integer", nullable: false), - BankName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - BranchName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - AccountNumber = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - AccountHolderName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - SwiftCode = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), - IsPrimary = table.Column(type: "boolean", nullable: false), - 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_hr_employee_bank_details", x => x.EmployeeBankDetailId); - table.ForeignKey( - name: "FK_hr_employee_bank_details_hr_employees_EmployeeId", - column: x => x.EmployeeId, - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "hr_employee_documents", - columns: table => new - { - EmployeeDocumentId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EmployeeId = table.Column(type: "integer", nullable: false), - HrDocumentTypeId = table.Column(type: "integer", nullable: false), - OriginalFileName = table.Column(type: "character varying(260)", maxLength: 260, nullable: false), - StoredFileName = table.Column(type: "character varying(260)", maxLength: 260, nullable: false), - RelativePath = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - ContentType = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - SizeBytes = table.Column(type: "bigint", nullable: false), - IssueDate = table.Column(type: "timestamp with time zone", nullable: true), - ExpiryDate = table.Column(type: "timestamp with time zone", nullable: true), - Notes = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - UploadedBy = table.Column(type: "integer", nullable: false), - UploadedAt = table.Column(type: "timestamp with time zone", nullable: false), - VerifiedBy = table.Column(type: "integer", nullable: true), - VerifiedAt = table.Column(type: "timestamp with time zone", nullable: true), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Active"), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_employee_documents", x => x.EmployeeDocumentId); - table.ForeignKey( - name: "FK_hr_employee_documents_hr_document_types_HrDocumentTypeId", - column: x => x.HrDocumentTypeId, - principalTable: "hr_document_types", - principalColumn: "HrDocumentTypeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_employee_documents_hr_employees_EmployeeId", - column: x => x.EmployeeId, - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "hr_employee_loans", - columns: table => new - { - EmployeeLoanId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - EmployeeId = table.Column(type: "integer", nullable: false), - LoanKind = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - PrincipalAmount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), - InterestRate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - InstallmentAmount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), - NumberOfInstallments = table.Column(type: "integer", nullable: false), - StartYear = table.Column(type: "integer", nullable: false), - StartMonth = table.Column(type: "integer", nullable: false), - OutstandingBalance = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - ApprovedBy = table.Column(type: "integer", nullable: false), - ApprovedAt = table.Column(type: "timestamp with time zone", nullable: false), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_employee_loans", x => x.EmployeeLoanId); - table.ForeignKey( - name: "FK_hr_employee_loans_hr_employees_EmployeeId", - column: x => x.EmployeeId, - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_employee_salary_structures", - columns: table => new - { - EmployeeSalaryStructureId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EmployeeId = table.Column(type: "integer", nullable: false), - EffectiveFrom = table.Column(type: "timestamp with time zone", nullable: false), - EffectiveTo = table.Column(type: "timestamp with time zone", nullable: true), - BasicSalary = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), - Currency = table.Column(type: "character varying(3)", maxLength: 3, nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - ApprovedBy = table.Column(type: "integer", nullable: false), - ApprovedAt = table.Column(type: "timestamp with time zone", nullable: false), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_employee_salary_structures", x => x.EmployeeSalaryStructureId); - table.ForeignKey( - name: "FK_hr_employee_salary_structures_hr_employees_EmployeeId", - column: x => x.EmployeeId, - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_leave_balances", - columns: table => new - { - LeaveBalanceId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EmployeeId = table.Column(type: "integer", nullable: false), - LeaveTypeId = table.Column(type: "integer", nullable: false), - Year = table.Column(type: "integer", nullable: false), - EntitledDays = table.Column(type: "numeric(6,2)", precision: 6, scale: 2, nullable: false), - TakenDays = table.Column(type: "numeric(6,2)", precision: 6, scale: 2, nullable: false), - CarriedForwardDays = table.Column(type: "numeric(6,2)", precision: 6, scale: 2, nullable: false), - AdjustmentDays = table.Column(type: "numeric(6,2)", precision: 6, scale: 2, nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false), - UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_leave_balances", x => x.LeaveBalanceId); - table.ForeignKey( - name: "FK_hr_leave_balances_hr_employees_EmployeeId", - column: x => x.EmployeeId, - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_leave_balances_hr_leave_types_LeaveTypeId", - column: x => x.LeaveTypeId, - principalTable: "hr_leave_types", - principalColumn: "LeaveTypeId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_leave_requests", - columns: table => new - { - LeaveRequestId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - DocNo = table.Column(type: "character varying(30)", maxLength: 30, nullable: false), - EmployeeId = table.Column(type: "integer", nullable: false), - LeaveTypeId = table.Column(type: "integer", nullable: false), - StartDate = table.Column(type: "timestamp with time zone", nullable: false), - EndDate = table.Column(type: "timestamp with time zone", nullable: false), - DaysCount = table.Column(type: "numeric(6,2)", precision: 6, scale: 2, nullable: false), - Reason = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - ApprovedBy = table.Column(type: "integer", nullable: true), - ApprovedAt = table.Column(type: "timestamp with time zone", nullable: true), - RejectionReason = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - CreatedBy = table.Column(type: "integer", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_leave_requests", x => x.LeaveRequestId); - table.ForeignKey( - name: "FK_hr_leave_requests_hr_employees_EmployeeId", - column: x => x.EmployeeId, - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_leave_requests_hr_leave_types_LeaveTypeId", - column: x => x.LeaveTypeId, - principalTable: "hr_leave_types", - principalColumn: "LeaveTypeId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_payroll_lines", - columns: table => new - { - PayrollLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - PayrollRunId = table.Column(type: "integer", nullable: false), - EmployeeId = table.Column(type: "integer", nullable: false), - BasicSalary = table.Column(type: "numeric(18,2)", nullable: false), - TotalAllowances = table.Column(type: "numeric(18,2)", nullable: false), - OvertimeAmount = table.Column(type: "numeric(18,2)", nullable: false), - GrossSalary = table.Column(type: "numeric(18,2)", nullable: false), - LateDeductionAmount = table.Column(type: "numeric(18,2)", nullable: false), - NoPayAmount = table.Column(type: "numeric(18,2)", nullable: false), - LoanDeductionAmount = table.Column(type: "numeric(18,2)", nullable: false), - EpfEmployeeAmount = table.Column(type: "numeric(18,2)", nullable: false), - EpfEmployerAmount = table.Column(type: "numeric(18,2)", nullable: false), - EtfEmployerAmount = table.Column(type: "numeric(18,2)", nullable: false), - TaxAmount = table.Column(type: "numeric(18,2)", nullable: false), - OtherDeductionsAmount = table.Column(type: "numeric(18,2)", nullable: false), - NetSalary = table.Column(type: "numeric(18,2)", nullable: false), - WorkingDays = table.Column(type: "integer", nullable: false), - PresentDays = table.Column(type: "integer", nullable: false), - AbsentDays = table.Column(type: "integer", nullable: false), - LeaveDays = table.Column(type: "integer", nullable: false), - OtMinutesTotal = table.Column(type: "integer", nullable: false), - LateMinutesTotal = table.Column(type: "integer", nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_payroll_lines", x => x.PayrollLineId); - table.ForeignKey( - name: "FK_hr_payroll_lines_hr_employees_EmployeeId", - column: x => x.EmployeeId, - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_hr_payroll_lines_hr_payroll_runs_PayrollRunId", - column: x => x.PayrollRunId, - principalTable: "hr_payroll_runs", - principalColumn: "PayrollRunId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "hr_loan_installments", - columns: table => new - { - LoanInstallmentId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EmployeeLoanId = table.Column(type: "integer", nullable: false), - InstallmentNumber = table.Column(type: "integer", nullable: false), - DueYear = table.Column(type: "integer", nullable: false), - DueMonth = table.Column(type: "integer", nullable: false), - ScheduledAmount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), - PaidAmount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: true), - PayrollRunId = table.Column(type: "integer", nullable: true), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_loan_installments", x => x.LoanInstallmentId); - table.ForeignKey( - name: "FK_hr_loan_installments_hr_employee_loans_EmployeeLoanId", - column: x => x.EmployeeLoanId, - principalTable: "hr_employee_loans", - principalColumn: "EmployeeLoanId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_hr_loan_installments_hr_payroll_runs_PayrollRunId", - column: x => x.PayrollRunId, - principalTable: "hr_payroll_runs", - principalColumn: "PayrollRunId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_employee_salary_structure_lines", - columns: table => new - { - EmployeeSalaryStructureLineId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - EmployeeSalaryStructureId = table.Column(type: "integer", nullable: false), - SalaryComponentId = table.Column(type: "integer", nullable: false), - Amount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_employee_salary_structure_lines", x => x.EmployeeSalaryStructureLineId); - table.ForeignKey( - name: "FK_hr_employee_salary_structure_lines_hr_employee_salary_struc~", - column: x => x.EmployeeSalaryStructureId, - principalTable: "hr_employee_salary_structures", - principalColumn: "EmployeeSalaryStructureId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_hr_employee_salary_structure_lines_hr_salary_components_Sal~", - column: x => x.SalaryComponentId, - principalTable: "hr_salary_components", - principalColumn: "SalaryComponentId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_payroll_line_components", - columns: table => new - { - PayrollLineComponentId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - PayrollLineId = table.Column(type: "integer", nullable: false), - ComponentCategory = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - SalaryComponentId = table.Column(type: "integer", nullable: true), - Label = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - Amount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false), - SortOrder = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_payroll_line_components", x => x.PayrollLineComponentId); - table.ForeignKey( - name: "FK_hr_payroll_line_components_hr_payroll_lines_PayrollLineId", - column: x => x.PayrollLineId, - principalTable: "hr_payroll_lines", - principalColumn: "PayrollLineId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_hr_payroll_line_components_hr_salary_components_SalaryCompo~", - column: x => x.SalaryComponentId, - principalTable: "hr_salary_components", - principalColumn: "SalaryComponentId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "hr_payslips", - columns: table => new - { - PayslipId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - PayrollLineId = table.Column(type: "integer", nullable: false), - GeneratedAt = table.Column(type: "timestamp with time zone", nullable: false), - ReleasedAt = table.Column(type: "timestamp with time zone", nullable: true), - ReleasedBy = table.Column(type: "integer", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_hr_payslips", x => x.PayslipId); - table.ForeignKey( - name: "FK_hr_payslips_hr_payroll_lines_PayrollLineId", - column: x => x.PayrollLineId, - principalTable: "hr_payroll_lines", - principalColumn: "PayrollLineId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.InsertData( - table: "nav_items", - columns: new[] { "NavItemId", "Code", "Href", "Icon", "Label", "SortOrder" }, - values: new object[,] - { - { 1, "dashboard", "/dashboard", null, "Dashboard", 1 }, - { 2, "products", "/dashboard/products", null, "Products", 2 }, - { 3, "vendors", "/dashboard/vendors", null, "Vendors", 3 }, - { 4, "procurement", "/dashboard/procurement", null, "Procurement", 4 }, - { 5, "receiving", "/dashboard/receiving/grn", null, "Receiving", 5 }, - { 6, "stock", "/dashboard/stock", null, "Stock", 6 }, - { 7, "warehouses", "/dashboard/warehouse", null, "Warehouses", 7 }, - { 8, "orders", "/dashboard/orders", null, "Orders", 8 }, - { 9, "settings", "/dashboard/settings", null, "Settings", 9 }, - { 10, "help", "/dashboard/help", null, "Help", 10 } - }); - - migrationBuilder.InsertData( - table: "users", - columns: new[] { "UserId", "auth_user_id", "DisplayName", "Email", "RoleId", "Status", "Username" }, - values: new object[] { 1, null, "System", null, null, "Active", "system" }); - - migrationBuilder.InsertData( - table: "permissions", - columns: new[] { "PermissionId", "Code", "NavItemId", "SubNavItemId" }, - values: new object[,] - { - { 1, "NAV:dashboard", 1, null }, - { 2, "NAV:products", 2, null }, - { 3, "NAV:vendors", 3, null }, - { 4, "NAV:procurement", 4, null }, - { 5, "NAV:receiving", 5, null }, - { 6, "NAV:stock", 6, null }, - { 7, "NAV:warehouses", 7, null }, - { 8, "NAV:orders", 8, null }, - { 9, "NAV:settings", 9, null }, - { 10, "NAV:help", 10, null } - }); - - migrationBuilder.InsertData( - table: "sub_nav_items", - columns: new[] { "SubNavItemId", "Code", "Href", "Icon", "Label", "NavItemId", "SortOrder" }, - values: new object[,] - { - { 1, "products.item", "/dashboard/products", null, "Item", 2, 1 }, - { 2, "products.category", "/dashboard/products/categories", null, "Category", 2, 2 }, - { 3, "products.brand", "/dashboard/products/brands", null, "Brand", 2, 3 }, - { 4, "products.item-type", "/dashboard/products/item-types", null, "Item Type", 2, 4 }, - { 5, "products.uom", "/dashboard/products/uoms", null, "UOM", 2, 5 }, - { 6, "products.configuration", "/dashboard/products/settings", null, "Configuration", 2, 6 }, - { 7, "settings.roles", "/dashboard/settings/roles", null, "Roles", 9, 1 }, - { 8, "settings.users", "/dashboard/settings/users", null, "Users", 9, 2 }, - { 9, "procurement.requisitions", "/dashboard/procurement/requisitions", null, "Requisitions", 4, 1 }, - { 10, "procurement.rfqs", "/dashboard/procurement/rfqs", null, "RFQs", 4, 2 }, - { 11, "procurement.purchase-orders", "/dashboard/procurement/purchase-orders", null, "Purchase Orders", 4, 3 }, - { 12, "procurement.purchase-returns", "/dashboard/procurement/purchase-returns", null, "Purchase Returns", 4, 4 } - }); - - migrationBuilder.InsertData( - table: "permissions", - columns: new[] { "PermissionId", "Code", "NavItemId", "SubNavItemId" }, - values: new object[,] - { - { 11, "NAV:products.item", null, 1 }, - { 12, "NAV:products.category", null, 2 }, - { 13, "NAV:products.brand", null, 3 }, - { 14, "NAV:products.item-type", null, 4 }, - { 15, "NAV:products.uom", null, 5 }, - { 16, "NAV:products.configuration", null, 6 }, - { 17, "NAV:settings.roles", null, 7 }, - { 18, "NAV:settings.users", null, 8 }, - { 19, "NAV:procurement.requisitions", null, 9 }, - { 20, "NAV:procurement.rfqs", null, 10 }, - { 21, "NAV:procurement.purchase-orders", null, 11 }, - { 22, "NAV:procurement.purchase-returns", null, 12 } - }); - - migrationBuilder.CreateIndex( - name: "IX_audit_logs_CreatedAt", - table: "audit_logs", - column: "CreatedAt"); - - migrationBuilder.CreateIndex( - name: "IX_audit_logs_EntityType_EntityId", - table: "audit_logs", - columns: new[] { "EntityType", "EntityId" }); - - migrationBuilder.CreateIndex( - name: "IX_audit_logs_UserId", - table: "audit_logs", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_batches_ItemId_BatchNo", - table: "batches", - columns: new[] { "ItemId", "BatchNo" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_bins_WarehouseId_Code", - table: "bins", - columns: new[] { "WarehouseId", "Code" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_brands_Name", - table: "brands", - column: "Name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_brands_Status", - table: "brands", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_categories_Name", - table: "categories", - column: "Name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_categories_Status", - table: "categories", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_customers_CustomerCode", - table: "customers", - column: "CustomerCode", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_customers_CustomerType", - table: "customers", - column: "CustomerType"); - - migrationBuilder.CreateIndex( - name: "IX_customers_DefaultWarehouseId", - table: "customers", - column: "DefaultWarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_customers_Status", - table: "customers", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_grn_lines_BatchId", - table: "grn_lines", - column: "BatchId"); - - migrationBuilder.CreateIndex( - name: "IX_grn_lines_BinId", - table: "grn_lines", - column: "BinId"); - - migrationBuilder.CreateIndex( - name: "IX_grn_lines_GrnId", - table: "grn_lines", - column: "GrnId"); - - migrationBuilder.CreateIndex( - name: "IX_grn_lines_ItemId", - table: "grn_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_grn_lines_PoLineId", - table: "grn_lines", - column: "PoLineId"); - - migrationBuilder.CreateIndex( - name: "IX_grn_lines_UomId", - table: "grn_lines", - column: "UomId"); - - migrationBuilder.CreateIndex( - name: "IX_grns_CreatedBy", - table: "grns", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_grns_DocNo", - table: "grns", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_grns_PoId", - table: "grns", - column: "PoId"); - - migrationBuilder.CreateIndex( - name: "IX_grns_Status", - table: "grns", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_grns_VendorId", - table: "grns", - column: "VendorId"); - - migrationBuilder.CreateIndex( - name: "IX_grns_WarehouseId", - table: "grns", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_attendance_records_AttendanceUploadBatchId", - table: "hr_attendance_records", - column: "AttendanceUploadBatchId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_attendance_records_EmployeeId_AttendanceDate", - table: "hr_attendance_records", - columns: new[] { "EmployeeId", "AttendanceDate" }); - - migrationBuilder.CreateIndex( - name: "IX_hr_attendance_records_WorkShiftId", - table: "hr_attendance_records", - column: "WorkShiftId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_attendance_upload_batches_DocNo", - table: "hr_attendance_upload_batches", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_attendance_upload_batches_PeriodStart_PeriodEnd", - table: "hr_attendance_upload_batches", - columns: new[] { "PeriodStart", "PeriodEnd" }); - - migrationBuilder.CreateIndex( - name: "IX_hr_attendance_upload_batches_Status", - table: "hr_attendance_upload_batches", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_branches_Code", - table: "hr_branches", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_branches_Status", - table: "hr_branches", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_departments_BranchId", - table: "hr_departments", - column: "BranchId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_departments_Code", - table: "hr_departments", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_departments_HeadEmployeeId", - table: "hr_departments", - column: "HeadEmployeeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_departments_ParentDepartmentId", - table: "hr_departments", - column: "ParentDepartmentId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_departments_Status", - table: "hr_departments", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_designations_Code", - table: "hr_designations", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_designations_Status", - table: "hr_designations", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_document_types_Code", - table: "hr_document_types", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_document_types_Status", - table: "hr_document_types", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_bank_details_EmployeeId", - table: "hr_employee_bank_details", - column: "EmployeeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_documents_EmployeeId", - table: "hr_employee_documents", - column: "EmployeeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_documents_ExpiryDate", - table: "hr_employee_documents", - column: "ExpiryDate"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_documents_HrDocumentTypeId", - table: "hr_employee_documents", - column: "HrDocumentTypeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_loans_DocNo", - table: "hr_employee_loans", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_loans_EmployeeId", - table: "hr_employee_loans", - column: "EmployeeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_loans_Status", - table: "hr_employee_loans", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_salary_structure_lines_EmployeeSalaryStructureId", - table: "hr_employee_salary_structure_lines", - column: "EmployeeSalaryStructureId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_salary_structure_lines_SalaryComponentId", - table: "hr_employee_salary_structure_lines", - column: "SalaryComponentId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employee_salary_structures_EmployeeId_EffectiveTo", - table: "hr_employee_salary_structures", - columns: new[] { "EmployeeId", "EffectiveTo" }); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_BranchId", - table: "hr_employees", - column: "BranchId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_DepartmentId", - table: "hr_employees", - column: "DepartmentId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_DesignationId", - table: "hr_employees", - column: "DesignationId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_Email", - table: "hr_employees", - column: "Email"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_EmployeeCode", - table: "hr_employees", - column: "EmployeeCode", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_EmploymentTypeId", - table: "hr_employees", - column: "EmploymentTypeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_ReportingManagerId", - table: "hr_employees", - column: "ReportingManagerId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_Status", - table: "hr_employees", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_UserId", - table: "hr_employees", - column: "UserId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_employees_WorkShiftId", - table: "hr_employees", - column: "WorkShiftId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_employment_types_Code", - table: "hr_employment_types", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_employment_types_Status", - table: "hr_employment_types", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_balances_EmployeeId_LeaveTypeId_Year", - table: "hr_leave_balances", - columns: new[] { "EmployeeId", "LeaveTypeId", "Year" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_balances_LeaveTypeId", - table: "hr_leave_balances", - column: "LeaveTypeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_requests_DocNo", - table: "hr_leave_requests", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_requests_EmployeeId", - table: "hr_leave_requests", - column: "EmployeeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_requests_LeaveTypeId", - table: "hr_leave_requests", - column: "LeaveTypeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_requests_StartDate_EndDate", - table: "hr_leave_requests", - columns: new[] { "StartDate", "EndDate" }); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_requests_Status", - table: "hr_leave_requests", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_types_Code", - table: "hr_leave_types", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_leave_types_Status", - table: "hr_leave_types", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_loan_installments_DueYear_DueMonth", - table: "hr_loan_installments", - columns: new[] { "DueYear", "DueMonth" }); - - migrationBuilder.CreateIndex( - name: "IX_hr_loan_installments_EmployeeLoanId", - table: "hr_loan_installments", - column: "EmployeeLoanId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_loan_installments_PayrollRunId", - table: "hr_loan_installments", - column: "PayrollRunId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_line_components_PayrollLineId", - table: "hr_payroll_line_components", - column: "PayrollLineId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_line_components_SalaryComponentId", - table: "hr_payroll_line_components", - column: "SalaryComponentId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_lines_EmployeeId", - table: "hr_payroll_lines", - column: "EmployeeId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_lines_PayrollRunId_EmployeeId", - table: "hr_payroll_lines", - columns: new[] { "PayrollRunId", "EmployeeId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_runs_BranchId", - table: "hr_payroll_runs", - column: "BranchId"); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_runs_DocNo", - table: "hr_payroll_runs", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_runs_PeriodYear_PeriodMonth_BranchId", - table: "hr_payroll_runs", - columns: new[] { "PeriodYear", "PeriodMonth", "BranchId" }); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_runs_Status", - table: "hr_payroll_runs", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_payroll_statutory_settings_EffectiveFrom", - table: "hr_payroll_statutory_settings", - column: "EffectiveFrom"); - - migrationBuilder.CreateIndex( - name: "IX_hr_payslips_PayrollLineId", - table: "hr_payslips", - column: "PayrollLineId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_salary_components_Code", - table: "hr_salary_components", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_salary_components_Status", - table: "hr_salary_components", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_hr_tax_slabs_EffectiveFrom", - table: "hr_tax_slabs", - column: "EffectiveFrom"); - - migrationBuilder.CreateIndex( - name: "IX_hr_work_shifts_Code", - table: "hr_work_shifts", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_hr_work_shifts_Status", - table: "hr_work_shifts", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_item_reorders_ItemId_WarehouseId", - table: "item_reorders", - columns: new[] { "ItemId", "WarehouseId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_item_reorders_WarehouseId", - table: "item_reorders", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_item_types_Name", - table: "item_types", - column: "Name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_item_types_Status", - table: "item_types", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_items_BaseUomId", - table: "items", - column: "BaseUomId"); - - migrationBuilder.CreateIndex( - name: "IX_items_BrandId", - table: "items", - column: "BrandId"); - - migrationBuilder.CreateIndex( - name: "IX_items_CategoryId", - table: "items", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_items_DefaultVendorId", - table: "items", - column: "DefaultVendorId"); - - migrationBuilder.CreateIndex( - name: "IX_items_Sku", - table: "items", - column: "Sku", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_items_Status", - table: "items", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_items_SubCategoryId", - table: "items", - column: "SubCategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_journal_entry_stubs_SourceDocType_SourceDocId", - table: "journal_entry_stubs", - columns: new[] { "SourceDocType", "SourceDocId" }); - - migrationBuilder.CreateIndex( - name: "IX_nav_items_Code", - table: "nav_items", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_number_sequences_doc_type_year", - table: "number_sequences", - columns: new[] { "doc_type", "year" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_permissions_Code", - table: "permissions", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_permissions_NavItemId", - table: "permissions", - column: "NavItemId"); - - migrationBuilder.CreateIndex( - name: "IX_permissions_SubNavItemId", - table: "permissions", - column: "SubNavItemId"); - - migrationBuilder.CreateIndex( - name: "IX_po_lines_ItemId", - table: "po_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_po_lines_PoId", - table: "po_lines", - column: "PoId"); - - migrationBuilder.CreateIndex( - name: "IX_po_lines_UomId", - table: "po_lines", - column: "UomId"); - - migrationBuilder.CreateIndex( - name: "IX_po_lines_WarehouseId", - table: "po_lines", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_product_config_UpdatedBy", - table: "product_config", - column: "UpdatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_orders_CreatedBy", - table: "purchase_orders", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_orders_DocNo", - table: "purchase_orders", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_purchase_orders_RequisitionId", - table: "purchase_orders", - column: "RequisitionId"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_orders_Status", - table: "purchase_orders", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_orders_VendorId", - table: "purchase_orders", - column: "VendorId"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_return_lines_GrnLineId", - table: "purchase_return_lines", - column: "GrnLineId"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_return_lines_ItemId", - table: "purchase_return_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_return_lines_ReturnId", - table: "purchase_return_lines", - column: "ReturnId"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_returns_CreatedBy", - table: "purchase_returns", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_returns_DocNo", - table: "purchase_returns", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_purchase_returns_ReasonCodeId", - table: "purchase_returns", - column: "ReasonCodeId"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_returns_VendorId", - table: "purchase_returns", - column: "VendorId"); - - migrationBuilder.CreateIndex( - name: "IX_purchase_returns_WarehouseId", - table: "purchase_returns", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_reason_codes_Context_Code", - table: "reason_codes", - columns: new[] { "Context", "Code" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_requisition_lines_ItemId", - table: "requisition_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_requisition_lines_RequisitionId", - table: "requisition_lines", - column: "RequisitionId"); - - migrationBuilder.CreateIndex( - name: "IX_requisitions_DocNo", - table: "requisitions", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_requisitions_RequestedBy", - table: "requisitions", - column: "RequestedBy"); - - migrationBuilder.CreateIndex( - name: "IX_requisitions_Status", - table: "requisitions", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_rfq_lines_ItemId", - table: "rfq_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_rfq_lines_RfqId", - table: "rfq_lines", - column: "RfqId"); - - migrationBuilder.CreateIndex( - name: "IX_rfqs_DocNo", - table: "rfqs", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_rfqs_RequisitionId", - table: "rfqs", - column: "RequisitionId"); - - migrationBuilder.CreateIndex( - name: "IX_role_permissions_PermissionId", - table: "role_permissions", - column: "PermissionId"); - - migrationBuilder.CreateIndex( - name: "IX_roles_auth_role_id", - table: "roles", - column: "auth_role_id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_roles_Code", - table: "roles", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoice_lines_ItemId", - table: "sales_invoice_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoice_lines_SalesInvoiceId", - table: "sales_invoice_lines", - column: "SalesInvoiceId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoice_lines_UomId", - table: "sales_invoice_lines", - column: "UomId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoice_lines_WarehouseId", - table: "sales_invoice_lines", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoices_CreatorUserId", - table: "sales_invoices", - column: "CreatorUserId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoices_CustomerId", - table: "sales_invoices", - column: "CustomerId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoices_InvoiceDate", - table: "sales_invoices", - column: "InvoiceDate"); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoices_InvoiceNo", - table: "sales_invoices", - column: "InvoiceNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoices_Status", - table: "sales_invoices", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_sales_invoices_WarehouseId", - table: "sales_invoices", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slip_lines_ItemId", - table: "sales_slip_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slip_lines_SalesSlipId", - table: "sales_slip_lines", - column: "SalesSlipId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slip_lines_UomId", - table: "sales_slip_lines", - column: "UomId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slip_lines_WarehouseId", - table: "sales_slip_lines", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slips_CashierUserId", - table: "sales_slips", - column: "CashierUserId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slips_CustomerId", - table: "sales_slips", - column: "CustomerId"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slips_SlipDate", - table: "sales_slips", - column: "SlipDate"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slips_SlipNo", - table: "sales_slips", - column: "SlipNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_sales_slips_Status", - table: "sales_slips", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_sales_slips_WarehouseId", - table: "sales_slips", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_serials_ItemId_SerialNo", - table: "serials", - columns: new[] { "ItemId", "SerialNo" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustment_lines_AdjustmentId", - table: "stock_adjustment_lines", - column: "AdjustmentId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustment_lines_BatchId", - table: "stock_adjustment_lines", - column: "BatchId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustment_lines_BinId", - table: "stock_adjustment_lines", - column: "BinId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustment_lines_ItemId", - table: "stock_adjustment_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustment_lines_SerialId", - table: "stock_adjustment_lines", - column: "SerialId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustments_CreatedBy", - table: "stock_adjustments", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustments_DocNo", - table: "stock_adjustments", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustments_ReasonCodeId", - table: "stock_adjustments", - column: "ReasonCodeId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_adjustments_WarehouseId", - table: "stock_adjustments", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_count_lines_BinId", - table: "stock_count_lines", - column: "BinId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_count_lines_CountId", - table: "stock_count_lines", - column: "CountId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_count_lines_ItemId", - table: "stock_count_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_counts_CreatedBy", - table: "stock_counts", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_stock_counts_DocNo", - table: "stock_counts", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_stock_counts_Status", - table: "stock_counts", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_stock_counts_WarehouseId", - table: "stock_counts", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_layers_BatchId", - table: "stock_layers", - column: "BatchId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_layers_GrnLineId", - table: "stock_layers", - column: "GrnLineId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_layers_ItemId_WarehouseId_ReceiptDate_LayerId", - table: "stock_layers", - columns: new[] { "ItemId", "WarehouseId", "ReceiptDate", "LayerId" }); - - migrationBuilder.CreateIndex( - name: "IX_stock_layers_SerialId", - table: "stock_layers", - column: "SerialId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_layers_WarehouseId", - table: "stock_layers", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_ledger_BatchId", - table: "stock_ledger", - column: "BatchId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_ledger_BinId", - table: "stock_ledger", - column: "BinId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_ledger_ItemId_WarehouseId_CreatedAt", - table: "stock_ledger", - columns: new[] { "ItemId", "WarehouseId", "CreatedAt" }); - - migrationBuilder.CreateIndex( - name: "IX_stock_ledger_ItemId_WarehouseId_LedgerId", - table: "stock_ledger", - columns: new[] { "ItemId", "WarehouseId", "LedgerId" }); - - migrationBuilder.CreateIndex( - name: "IX_stock_ledger_SerialId", - table: "stock_ledger", - column: "SerialId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_ledger_SourceDocType_SourceDocId", - table: "stock_ledger", - columns: new[] { "SourceDocType", "SourceDocId" }); - - migrationBuilder.CreateIndex( - name: "IX_stock_ledger_UserId", - table: "stock_ledger", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_ledger_WarehouseId", - table: "stock_ledger", - column: "WarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfer_lines_BatchId", - table: "stock_transfer_lines", - column: "BatchId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfer_lines_DestBinId", - table: "stock_transfer_lines", - column: "DestBinId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfer_lines_ItemId", - table: "stock_transfer_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfer_lines_SerialId", - table: "stock_transfer_lines", - column: "SerialId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfer_lines_SrcBinId", - table: "stock_transfer_lines", - column: "SrcBinId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfer_lines_TransferId", - table: "stock_transfer_lines", - column: "TransferId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfers_CreatedBy", - table: "stock_transfers", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfers_DestWarehouseId", - table: "stock_transfers", - column: "DestWarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfers_DocNo", - table: "stock_transfers", - column: "DocNo", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfers_SrcWarehouseId", - table: "stock_transfers", - column: "SrcWarehouseId"); - - migrationBuilder.CreateIndex( - name: "IX_stock_transfers_Status", - table: "stock_transfers", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_sub_nav_items_Code", - table: "sub_nav_items", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_sub_nav_items_NavItemId", - table: "sub_nav_items", - column: "NavItemId"); - - migrationBuilder.CreateIndex( - name: "IX_subcategories_CategoryId_Name", - table: "subcategories", - columns: new[] { "CategoryId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_subcategories_Status", - table: "subcategories", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_uom_conversions_FromUomId", - table: "uom_conversions", - column: "FromUomId"); - - migrationBuilder.CreateIndex( - name: "IX_uom_conversions_ItemId_FromUomId_ToUomId", - table: "uom_conversions", - columns: new[] { "ItemId", "FromUomId", "ToUomId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_uom_conversions_ToUomId", - table: "uom_conversions", - column: "ToUomId"); - - migrationBuilder.CreateIndex( - name: "IX_uoms_Name", - table: "uoms", - column: "Name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_users_auth_user_id", - table: "users", - column: "auth_user_id", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_users_Email", - table: "users", - column: "Email", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_users_RoleId", - table: "users", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "IX_users_Username", - table: "users", - column: "Username", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_vendor_quotation_lines_ItemId", - table: "vendor_quotation_lines", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_vendor_quotation_lines_QuotationId", - table: "vendor_quotation_lines", - column: "QuotationId"); - - migrationBuilder.CreateIndex( - name: "IX_vendor_quotations_RfqId_VendorId", - table: "vendor_quotations", - columns: new[] { "RfqId", "VendorId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_vendor_quotations_VendorId", - table: "vendor_quotations", - column: "VendorId"); - - migrationBuilder.CreateIndex( - name: "IX_vendors_Code", - table: "vendors", - column: "Code", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_vendors_Status", - table: "vendors", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_warehouses_Code", - table: "warehouses", - column: "Code", - unique: true); - - migrationBuilder.AddForeignKey( - name: "FK_hr_attendance_records_hr_employees_EmployeeId", - table: "hr_attendance_records", - column: "EmployeeId", - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_hr_departments_hr_employees_HeadEmployeeId", - table: "hr_departments", - column: "HeadEmployeeId", - principalTable: "hr_employees", - principalColumn: "EmployeeId", - onDelete: ReferentialAction.Restrict); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_hr_employees_users_UserId", - table: "hr_employees"); - - migrationBuilder.DropForeignKey( - name: "FK_hr_departments_hr_employees_HeadEmployeeId", - table: "hr_departments"); - - migrationBuilder.DropTable( - name: "audit_logs"); - - migrationBuilder.DropTable( - name: "hr_attendance_records"); - - migrationBuilder.DropTable( - name: "hr_employee_bank_details"); - - migrationBuilder.DropTable( - name: "hr_employee_documents"); - - migrationBuilder.DropTable( - name: "hr_employee_salary_structure_lines"); - - migrationBuilder.DropTable( - name: "hr_leave_balances"); - - migrationBuilder.DropTable( - name: "hr_leave_requests"); - - migrationBuilder.DropTable( - name: "hr_loan_installments"); - - migrationBuilder.DropTable( - name: "hr_payroll_line_components"); - - migrationBuilder.DropTable( - name: "hr_payroll_statutory_settings"); - - migrationBuilder.DropTable( - name: "hr_payslips"); - - migrationBuilder.DropTable( - name: "hr_tax_slabs"); - - migrationBuilder.DropTable( - name: "item_reorders"); - - migrationBuilder.DropTable( - name: "item_types"); - - migrationBuilder.DropTable( - name: "journal_entry_stubs"); - - migrationBuilder.DropTable( - name: "number_sequences"); - - migrationBuilder.DropTable( - name: "product_config"); - - migrationBuilder.DropTable( - name: "purchase_return_lines"); - - migrationBuilder.DropTable( - name: "requisition_lines"); - - migrationBuilder.DropTable( - name: "rfq_lines"); - - migrationBuilder.DropTable( - name: "role_permissions"); - - migrationBuilder.DropTable( - name: "sales_invoice_lines"); - - migrationBuilder.DropTable( - name: "sales_slip_lines"); - - migrationBuilder.DropTable( - name: "stock_adjustment_lines"); - - migrationBuilder.DropTable( - name: "stock_count_lines"); - - migrationBuilder.DropTable( - name: "stock_layers"); - - migrationBuilder.DropTable( - name: "stock_ledger"); - - migrationBuilder.DropTable( - name: "stock_transfer_lines"); - - migrationBuilder.DropTable( - name: "uom_conversions"); - - migrationBuilder.DropTable( - name: "vendor_quotation_lines"); - - migrationBuilder.DropTable( - name: "hr_attendance_upload_batches"); - - migrationBuilder.DropTable( - name: "hr_document_types"); - - migrationBuilder.DropTable( - name: "hr_employee_salary_structures"); - - migrationBuilder.DropTable( - name: "hr_leave_types"); - - migrationBuilder.DropTable( - name: "hr_employee_loans"); - - migrationBuilder.DropTable( - name: "hr_salary_components"); - - migrationBuilder.DropTable( - name: "hr_payroll_lines"); - - migrationBuilder.DropTable( - name: "purchase_returns"); - - migrationBuilder.DropTable( - name: "permissions"); - - migrationBuilder.DropTable( - name: "sales_invoices"); - - migrationBuilder.DropTable( - name: "sales_slips"); - - migrationBuilder.DropTable( - name: "stock_adjustments"); - - migrationBuilder.DropTable( - name: "stock_counts"); - - migrationBuilder.DropTable( - name: "grn_lines"); - - migrationBuilder.DropTable( - name: "serials"); - - migrationBuilder.DropTable( - name: "stock_transfers"); - - migrationBuilder.DropTable( - name: "vendor_quotations"); - - migrationBuilder.DropTable( - name: "hr_payroll_runs"); - - migrationBuilder.DropTable( - name: "sub_nav_items"); - - migrationBuilder.DropTable( - name: "customers"); - - migrationBuilder.DropTable( - name: "reason_codes"); - - migrationBuilder.DropTable( - name: "batches"); - - migrationBuilder.DropTable( - name: "bins"); - - migrationBuilder.DropTable( - name: "grns"); - - migrationBuilder.DropTable( - name: "po_lines"); - - migrationBuilder.DropTable( - name: "rfqs"); - - migrationBuilder.DropTable( - name: "nav_items"); - - migrationBuilder.DropTable( - name: "items"); - - migrationBuilder.DropTable( - name: "purchase_orders"); - - migrationBuilder.DropTable( - name: "warehouses"); - - migrationBuilder.DropTable( - name: "brands"); - - migrationBuilder.DropTable( - name: "subcategories"); - - migrationBuilder.DropTable( - name: "uoms"); - - migrationBuilder.DropTable( - name: "requisitions"); - - migrationBuilder.DropTable( - name: "vendors"); - - migrationBuilder.DropTable( - name: "categories"); - - migrationBuilder.DropTable( - name: "users"); - - migrationBuilder.DropTable( - name: "roles"); - - migrationBuilder.DropTable( - name: "hr_employees"); - - migrationBuilder.DropTable( - name: "hr_departments"); - - migrationBuilder.DropTable( - name: "hr_designations"); - - migrationBuilder.DropTable( - name: "hr_employment_types"); - - migrationBuilder.DropTable( - name: "hr_work_shifts"); - - migrationBuilder.DropTable( - name: "hr_branches"); - } - } -} diff --git a/Backend/ERPCore/Migrations/20260801000000_AddCompanyProfile.Designer.cs b/Backend/ERPCore/Migrations/20260801000000_AddCompanyProfile.Designer.cs deleted file mode 100644 index 7f21eac..0000000 --- a/Backend/ERPCore/Migrations/20260801000000_AddCompanyProfile.Designer.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -using ERPCore.Infra.Persistence; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ERPCore.Migrations -{ - [DbContext(typeof(ErpDbContext))] - [Migration("20260801000000_AddCompanyProfile")] - partial class AddCompanyProfile - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - // This designer is kept minimal because the repo does not regenerate migrations here. - // EF tooling only needs the migration metadata to exist; the active model snapshot - // is updated separately. - } - } -} diff --git a/Backend/ERPCore/Migrations/20260801000000_AddCompanyProfile.cs b/Backend/ERPCore/Migrations/20260801000000_AddCompanyProfile.cs deleted file mode 100644 index 961452f..0000000 --- a/Backend/ERPCore/Migrations/20260801000000_AddCompanyProfile.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ERPCore.Migrations -{ - /// - public partial class AddCompanyProfile : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "company_profile", - columns: table => new - { - CompanyProfileId = table.Column(type: "integer", nullable: false), - LegalName = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - TradeName = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - LogoUrl = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - TaxRegistrationNo = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - VatRegistrationNo = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - AddressLine1 = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - AddressLine2 = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - City = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - Country = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - Phone = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - Email = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - BankName = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - BankBranch = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - AccountName = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - AccountNumber = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - SwiftCode = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - FooterNote = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true), - UpdatedBy = table.Column(type: "integer", nullable: true), - xmin = table.Column(type: "xid", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_company_profile", x => x.CompanyProfileId); - table.CheckConstraint("ck_company_profile_singleton", "\"CompanyProfileId\" = 1"); - table.ForeignKey( - name: "FK_company_profile_users_UpdatedBy", - column: x => x.UpdatedBy, - principalTable: "users", - principalColumn: "UserId", - onDelete: ReferentialAction.Restrict); - }); - - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "company_profile"); - } - } -} diff --git a/Backend/ERPCore/Program.cs b/Backend/ERPCore/Program.cs index 8b2f945..ca937fb 100644 --- a/Backend/ERPCore/Program.cs +++ b/Backend/ERPCore/Program.cs @@ -16,7 +16,9 @@ using ERPCore.Services.Stock; using ERPCore.System.Errors; using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.OpenApi; +using Npgsql; using Serilog; var builder = WebApplication.CreateBuilder(args); @@ -32,7 +34,10 @@ builder.Services.AddControllers() // EF Core + PostgreSQL builder.Services.AddDbContext(o => - o.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))); +{ + o.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")); + o.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning)); +}); // ProblemDetails (RFC 7807) + domain-exception mapping builder.Services.AddProblemDetails(); @@ -78,7 +83,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); +//builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -103,6 +108,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -180,6 +186,7 @@ var app = builder.Build(); using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); + // await EnsureMigrationBaselineAsync(db); await db.Database.MigrateAsync(); try { @@ -205,3 +212,4 @@ app.UseAuthorization(); app.MapControllers(); app.MapHealthChecks("/health"); app.Run(); + diff --git a/Backend/ERPCore/Services/BundleSaleService.cs b/Backend/ERPCore/Services/BundleSaleService.cs new file mode 100644 index 0000000..1532844 --- /dev/null +++ b/Backend/ERPCore/Services/BundleSaleService.cs @@ -0,0 +1,289 @@ +using ERPCore.Domain; +using ERPCore.Domain.Entities; +using ERPCore.Domain.Enums; +using ERPCore.Dtos.Common; +using ERPCore.Dtos.Sales; +using ERPCore.Infra.Auth; +using ERPCore.Infra.UoW; +using ERPCore.Repositories.Interfaces; +using ERPCore.Services.Interfaces; +using ERPCore.Services.Stock; +using ERPCore.System.Errors; +using Microsoft.EntityFrameworkCore; + +namespace ERPCore.Services; + +public sealed class BundleSaleService : IBundleSaleService +{ + private readonly IRepository _templates; + private readonly IRepository _bundles; + private readonly IRepository _customers; + private readonly IRepository _items; + private readonly IRepository _uoms; + private readonly IRepository _warehouses; + private readonly IRepository _users; + private readonly ISalesPricingService _pricing; + private readonly IFifoCostingService _fifo; + private readonly ICurrentUser _currentUser; + private readonly INumberSequenceService _numbers; + private readonly IUnitOfWork _uow; + + public BundleSaleService( + IRepository bundles, + IRepository templates, + IRepository customers, + IRepository items, + IRepository uoms, + IRepository warehouses, + IRepository users, + ISalesPricingService pricing, + IFifoCostingService fifo, + ICurrentUser currentUser, + INumberSequenceService numbers, + IUnitOfWork uow) + { + _templates = templates; + _bundles = bundles; + _customers = customers; + _items = items; + _uoms = uoms; + _warehouses = warehouses; + _users = users; + _pricing = pricing; + _fifo = fifo; + _currentUser = currentUser; + _numbers = numbers; + _uow = uow; + } + + public async Task> ListTemplatesAsync(PageQuery query, CancellationToken ct = default) + { + IQueryable q = _templates.Query().AsNoTracking().Include(x => x.Lines); + if (!string.IsNullOrWhiteSpace(query.Q)) + { + var term = query.Q.Trim(); + q = q.Where(x => EF.Functions.ILike(x.TemplateCode, $"%{term}%") || EF.Functions.ILike(x.TemplateName, $"%{term}%") || EF.Functions.ILike(x.Description ?? "", $"%{term}%")); + } + var total = await q.CountAsync(ct); + var rows = await q.OrderByDescending(x => x.BundleSaleTemplateId).Skip(query.Skip).Take(query.PageSize).ToListAsync(ct); + return PagedResponse.Create(rows.Select(x => new BundleSaleTemplateSummaryDto( + x.BundleSaleTemplateId, x.TemplateCode, x.TemplateName, x.Description, x.Status, x.Lines.Count, x.CreatedAt, x.UpdatedAt)).ToList(), query.Page, query.PageSize, total); + } + + public async Task GetTemplateAsync(int bundleSaleTemplateId, CancellationToken ct = default) + { + var template = await _templates.Query().AsNoTracking().Include(x => x.Lines).FirstOrDefaultAsync(x => x.BundleSaleTemplateId == bundleSaleTemplateId, ct); + return template is null ? null : new BundleSaleTemplateDto( + template.BundleSaleTemplateId, + template.TemplateCode, + template.TemplateName, + template.Description, + template.Status, + template.CreatedAt, + template.UpdatedAt, + template.Lines.OrderBy(x => x.SortOrder).Select(x => new BundleSaleTemplateLineDto( + x.BundleSaleTemplateLineId, x.ItemId, x.UomId, x.WarehouseId, x.Qty, x.UnitPrice, x.IncludeInBundle, x.SortOrder)).ToList()); + } + + public async Task> ListAsync(PageQuery query, int? customerId, int? warehouseId, CancellationToken ct = default) + { + IQueryable q = _bundles.Query().AsNoTracking().Include(x => x.Lines); + if (!string.IsNullOrWhiteSpace(query.Q)) + { + var term = query.Q.Trim(); + q = q.Where(x => EF.Functions.ILike(x.BundleNo, $"%{term}%") || EF.Functions.ILike(x.BundleName, $"%{term}%") || EF.Functions.ILike(x.BundleCode, $"%{term}%")); + } + if (customerId is not null) q = q.Where(x => x.CustomerId == customerId); + if (warehouseId is not null) q = q.Where(x => x.WarehouseId == warehouseId); + var total = await q.CountAsync(ct); + var rows = await q.OrderByDescending(x => x.BundleSaleId).Skip(query.Skip).Take(query.PageSize).ToListAsync(ct); + return PagedResponse.Create(rows.Select(MapSummary).ToList(), query.Page, query.PageSize, total); + } + + public async Task GetAsync(int bundleSaleId, CancellationToken ct = default) + { + var bundle = await _bundles.Query().AsNoTracking().Include(x => x.Lines).FirstOrDefaultAsync(x => x.BundleSaleId == bundleSaleId, ct); + return bundle is null ? null : Map(bundle); + } + + public async Task CheckPostingAsync(int bundleSaleId, CancellationToken ct = default) + { + var bundle = await _bundles.Query().AsNoTracking().Include(x => x.Lines).FirstOrDefaultAsync(x => x.BundleSaleId == bundleSaleId, ct) + ?? throw new NotFoundException($"Bundle sale {bundleSaleId} was not found."); + if (bundle.Status != BundleSaleStatus.Draft) + return new BundleSalePostingCheckDto(bundle.BundleSaleId, bundle.BundleNo, bundle.Status, false, Array.Empty()); + + var issues = new List(); + foreach (var line in bundle.Lines.Where(l => l.IncludeInBundle)) + { + var available = await _fifo.GetOnHandAsync(line.ItemId, line.WarehouseId, ct); + if (available >= line.Qty) continue; + var item = await _items.Query().AsNoTracking().Where(x => x.ItemId == line.ItemId).Select(x => new { x.Sku, x.Name }).FirstAsync(ct); + issues.Add(new BundleSalePostingIssueDto(line.BundleSaleLineId, line.ItemId, item.Sku, item.Name, line.WarehouseId, line.Qty, available, line.Qty - available)); + } + return new BundleSalePostingCheckDto(bundle.BundleSaleId, bundle.BundleNo, bundle.Status, issues.Count == 0, issues); + } + + public async Task CreateAsync(CreateBundleSaleRequest request, CancellationToken ct = default) + { + await ValidateReferencesAsync(request.CustomerId, request.WarehouseId, request.CashierUserId, request.BundleSaleTemplateId, ct); + var template = await _templates.Query().AsNoTracking().Include(x => x.Lines) + .FirstAsync(x => x.BundleSaleTemplateId == request.BundleSaleTemplateId, ct); + var bundle = new BundleSale + { + BundleNo = await _numbers.NextAsync(DocumentTypes.BundleSale, ct), + BundleDate = DateTime.UtcNow, + CustomerId = request.CustomerId, + WarehouseId = request.WarehouseId, + CashierUserId = request.CashierUserId, + BundleSaleTemplateId = request.BundleSaleTemplateId, + BundleName = request.BundleName, + BundleCode = string.Empty, + Status = BundleSaleStatus.Draft, + CreatedAt = DateTime.UtcNow + }; + bundle.CustomerSnapshotName = await _customers.Query().Where(x => x.CustomerId == request.CustomerId).Select(x => x.DisplayName ?? x.Name).FirstAsync(ct); + bundle.Lines = await BuildLinesAsync(template, request.Lines, ct); + Recalculate(bundle, request.BundlePrice); + bundle.BundleCode = $"{bundle.BundleNo}-B"; + await _bundles.AddAsync(bundle, ct); + bundle.ConcurrencyStamp = 1; + await _uow.SaveChangesAsync(ct); + return Map(bundle); + } + + public async Task UpdateAsync(int bundleSaleId, UpdateBundleSaleRequest request, CancellationToken ct = default) + { + var bundle = await _bundles.Query().Include(x => x.Lines).FirstOrDefaultAsync(x => x.BundleSaleId == bundleSaleId, ct) + ?? throw new NotFoundException($"Bundle sale {bundleSaleId} was not found."); + if (bundle.Status != BundleSaleStatus.Draft) + throw new ConflictException($"Bundle sale {bundleSaleId} is {bundle.Status} and cannot be edited."); + + await ValidateReferencesAsync(request.CustomerId, request.WarehouseId, request.CashierUserId, request.BundleSaleTemplateId, ct); + var template = await _templates.Query().AsNoTracking().Include(x => x.Lines) + .FirstAsync(x => x.BundleSaleTemplateId == request.BundleSaleTemplateId, ct); + bundle.CustomerId = request.CustomerId; + bundle.WarehouseId = request.WarehouseId; + bundle.CashierUserId = request.CashierUserId; + bundle.BundleSaleTemplateId = request.BundleSaleTemplateId; + bundle.BundleName = request.BundleName; + bundle.CustomerSnapshotName = await _customers.Query().Where(x => x.CustomerId == request.CustomerId).Select(x => x.DisplayName ?? x.Name).FirstAsync(ct); + bundle.Lines.Clear(); + foreach (var line in await BuildLinesAsync(template, request.Lines, ct)) bundle.Lines.Add(line); + Recalculate(bundle, request.BundlePrice); + bundle.UpdatedAt = DateTime.UtcNow; + bundle.ConcurrencyStamp++; + await _uow.SaveChangesAsync(ct); + return Map(bundle); + } + + public async Task PostAsync(int bundleSaleId, CancellationToken ct = default) + { + var bundle = await _bundles.Query().Include(x => x.Lines).FirstOrDefaultAsync(x => x.BundleSaleId == bundleSaleId, ct) + ?? throw new NotFoundException($"Bundle sale {bundleSaleId} was not found."); + if (bundle.Status != BundleSaleStatus.Draft) + throw new ConflictException($"Bundle sale {bundleSaleId} is {bundle.Status} and cannot be posted."); + + var check = await CheckPostingAsync(bundleSaleId, ct); + if (!check.CanPost) + throw new ConflictException("Resolve stock shortages before posting this bundle sale."); + + var posted = await _uow.ExecuteInTransactionAsync(async token => + { + foreach (var line in bundle.Lines.Where(l => l.IncludeInBundle)) + { + var consumed = await _fifo.ConsumeAsync(line.ItemId, line.WarehouseId, null, line.Qty, token); + var cost = consumed.Count == 0 ? 0m : consumed.Sum(x => x.Qty * x.UnitCost) / consumed.Sum(x => x.Qty); + await _fifo.PostLedgerAsync(line.ItemId, line.WarehouseId, null, null, null, _currentUser.AuditUserId, + Direction.Out, line.Qty, cost, 0m, nameof(BundleSale), bundle.BundleSaleId, DateTime.UtcNow, token); + } + bundle.Status = BundleSaleStatus.Posted; + bundle.UpdatedAt = DateTime.UtcNow; + bundle.ConcurrencyStamp++; + return bundle; + }, ct); + return Map(posted); + } + + public async Task CancelAsync(int bundleSaleId, CancellationToken ct = default) + { + var bundle = await _bundles.Query().Include(x => x.Lines).FirstOrDefaultAsync(x => x.BundleSaleId == bundleSaleId, ct) + ?? throw new NotFoundException($"Bundle sale {bundleSaleId} was not found."); + if (bundle.Status != BundleSaleStatus.Draft) + throw new ConflictException($"Bundle sale {bundleSaleId} is {bundle.Status} and cannot be cancelled."); + bundle.Status = BundleSaleStatus.Cancelled; + bundle.UpdatedAt = DateTime.UtcNow; + bundle.ConcurrencyStamp++; + await _uow.SaveChangesAsync(ct); + return Map(bundle); + } + + private async Task ValidateReferencesAsync(int customerId, int warehouseId, int cashierUserId, int templateId, CancellationToken ct) + { + if (!await _customers.Query().AnyAsync(x => x.CustomerId == customerId, ct)) + throw new NotFoundException($"Customer {customerId} was not found."); + if (!await _warehouses.Query().AnyAsync(x => x.WarehouseId == warehouseId, ct)) + throw new NotFoundException($"Warehouse {warehouseId} was not found."); + if (!await _users.Query().AnyAsync(x => x.UserId == cashierUserId, ct)) + throw new NotFoundException($"User {cashierUserId} was not found."); + if (!await _templates.Query().AnyAsync(x => x.BundleSaleTemplateId == templateId, ct)) + throw new NotFoundException($"Bundle template {templateId} was not found."); + } + + private async Task> BuildLinesAsync(BundleSaleTemplate template, IReadOnlyList requestLines, CancellationToken ct) + { + var lines = new List(); + var sourceLines = requestLines.Count > 0 + ? requestLines.OrderBy(x => x.SortOrder).ToList() + : template.Lines.OrderBy(x => x.SortOrder).Select(x => new CreateBundleSaleTemplateLineRequest + { + ItemId = x.ItemId, + UomId = x.UomId, + WarehouseId = x.WarehouseId, + Qty = x.Qty, + UnitPrice = x.UnitPrice, + IncludeInBundle = x.IncludeInBundle, + SortOrder = x.SortOrder + }).ToList(); + + foreach (var r in sourceLines) + { + var item = await _items.Query().AsNoTracking().FirstAsync(x => x.ItemId == r.ItemId, ct); + var resolved = await _pricing.ResolveAsync(r.ItemId, r.WarehouseId, r.UnitPrice, true, ct); + lines.Add(new BundleSaleLine + { + ItemId = r.ItemId, + Description = item.Name, + Qty = r.Qty, + UomId = r.UomId, + WarehouseId = r.WarehouseId, + UnitPrice = resolved.UnitPrice, + LineTotal = r.Qty * resolved.UnitPrice, + IncludeInBundle = r.IncludeInBundle, + IsComponent = true, + ParentLineId = null + }); + } + return lines; + } + + private static void Recalculate(BundleSale bundle, decimal bundlePrice) + { + bundle.ComponentSubtotal = bundle.Lines.Where(x => x.IncludeInBundle).Sum(x => x.LineTotal); + bundle.BundlePrice = bundlePrice; + bundle.MarginAmount = bundle.BundlePrice - bundle.ComponentSubtotal; + bundle.DiscountTotal = Math.Max(0m, bundle.ComponentSubtotal - bundle.BundlePrice); + bundle.TaxTotal = 0m; + bundle.GrandTotal = bundle.BundlePrice + bundle.TaxTotal; + } + + private static BundleSaleSummaryDto MapSummary(BundleSale x) => new( + x.BundleSaleId, x.BundleNo, x.BundleDate, x.CustomerId, x.CustomerSnapshotName, x.WarehouseId, x.BundleName, x.BundleCode, x.Status, x.ComponentSubtotal, x.BundlePrice, x.GrandTotal, x.CreatedAt); + + private static BundleSaleDto Map(BundleSale x) => new( + x.BundleSaleId, x.BundleNo, x.BundleDate, x.CustomerId, x.CustomerSnapshotName, x.WarehouseId, x.CashierUserId, x.BundleSaleTemplateId, + x.BundleName, x.BundleCode, x.Status, x.ComponentSubtotal, x.BundlePrice, x.MarginAmount, x.DiscountTotal, x.TaxTotal, x.GrandTotal, + x.CreatedAt, x.UpdatedAt, + x.Lines.Select(l => new BundleSaleLineDto(l.BundleSaleLineId, l.ItemId, l.Description, l.Qty, l.UomId, l.WarehouseId, l.UnitPrice, l.LineTotal, l.IncludeInBundle, l.IsComponent, l.ParentLineId)).ToList()); + +} diff --git a/Backend/ERPCore/Services/Interfaces/IBundleSaleService.cs b/Backend/ERPCore/Services/Interfaces/IBundleSaleService.cs new file mode 100644 index 0000000..b67ee2f --- /dev/null +++ b/Backend/ERPCore/Services/Interfaces/IBundleSaleService.cs @@ -0,0 +1,18 @@ +using ERPCore.Common.Http; +using ERPCore.Dtos.Common; +using ERPCore.Dtos.Sales; + +namespace ERPCore.Services.Interfaces; + +public interface IBundleSaleService +{ + Task> ListTemplatesAsync(PageQuery query, CancellationToken ct = default); + Task GetTemplateAsync(int bundleSaleTemplateId, CancellationToken ct = default); + Task> ListAsync(PageQuery query, int? customerId, int? warehouseId, CancellationToken ct = default); + Task GetAsync(int bundleSaleId, CancellationToken ct = default); + Task CheckPostingAsync(int bundleSaleId, CancellationToken ct = default); + Task CreateAsync(CreateBundleSaleRequest request, CancellationToken ct = default); + Task UpdateAsync(int bundleSaleId, UpdateBundleSaleRequest request, CancellationToken ct = default); + Task PostAsync(int bundleSaleId, CancellationToken ct = default); + Task CancelAsync(int bundleSaleId, CancellationToken ct = default); +} diff --git a/Backend/ERPCore/Services/Interfaces/ICompanyProfileService.cs b/Backend/ERPCore/Services/Interfaces/ICompanyProfileService.cs deleted file mode 100644 index c63ddec..0000000 --- a/Backend/ERPCore/Services/Interfaces/ICompanyProfileService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using ERPCore.Common.Http; -using ERPCore.Dtos.Config; - -namespace ERPCore.Services.Interfaces; - -public interface ICompanyProfileService -{ - Task> GetAsync(CancellationToken ct = default); - Task> UpdateAsync(UpdateCompanyProfileRequest request, uint expectedRowVersion, CancellationToken ct = default); -} diff --git a/Frontend/erp-system/app/dashboard/sales/bundles/[id]/page.tsx b/Frontend/erp-system/app/dashboard/sales/bundles/[id]/page.tsx new file mode 100644 index 0000000..3efe88f --- /dev/null +++ b/Frontend/erp-system/app/dashboard/sales/bundles/[id]/page.tsx @@ -0,0 +1,355 @@ +"use client" + +import { useEffect, useMemo, useState } from "react" +import Link from "next/link" +import { useParams, useRouter } from "next/navigation" +import { ArrowLeft, CheckCircle2, Edit, Minus, Plus, Printer, Save, XCircle } from "lucide-react" + +import { bundleApi } from "@/lib/api/bundles" +import { itemsApi } from "@/lib/api/items" +import { uomsApi } from "@/lib/api/uoms" +import { errorMessage } from "@/lib/error-map" +import { Button, buttonVariants } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { cn } from "@/lib/utils" +import { BundleSale, BundleSaleTemplateSummary, BundleSaleTemplateLine, UpdateBundleSaleRequest } from "@/types/bundles" +import { customersApi } from "@/lib/api/customers" +import { warehousesApi } from "@/lib/api/warehouses" +import { usersApi } from "@/lib/api/users" +import { Customer } from "@/types/customers" +import { ItemListItem, Uom, Warehouse } from "@/types/master-data" +import { ManagedUser } from "@/types/users" + +type EditableLine = BundleSaleTemplateLine & { key: string } + +function statusClass(status: BundleSale["status"]) { + switch (status) { + case "Draft": + return "border-amber-200 bg-amber-50 text-amber-800" + case "Posted": + return "border-emerald-200 bg-emerald-50 text-emerald-800" + case "Cancelled": + return "border-rose-200 bg-rose-50 text-rose-800" + } +} + +export default function BundleSaleDetailPage() { + const router = useRouter() + const params = useParams<{ id: string }>() + const bundleSaleId = Number(params.id) + const [bundle, setBundle] = useState(null) + const [editing, setEditing] = useState(false) + const [templates, setTemplates] = useState([]) + const [customers, setCustomers] = useState([]) + const [items, setItems] = useState([]) + const [uoms, setUoms] = useState([]) + const [warehouses, setWarehouses] = useState([]) + const [users, setUsers] = useState([]) + const [customerId, setCustomerId] = useState(null) + const [warehouseId, setWarehouseId] = useState(null) + const [cashierUserId, setCashierUserId] = useState(null) + const [templateId, setTemplateId] = useState(null) + const [bundleName, setBundleName] = useState("") + const [bundlePrice, setBundlePrice] = useState(0) + const [allowPriceOverride, setAllowPriceOverride] = useState(false) + const [lines, setLines] = useState([]) + const [error, setError] = useState(null) + const [busy, setBusy] = useState(false) + + useEffect(() => { + if (!Number.isFinite(bundleSaleId)) { + setError(`Invalid bundle id '${params.id}'.`) + return + } + Promise.all([ + bundleApi.getBundle(bundleSaleId), + bundleApi.listTemplates({ pageSize: 200 }), + customersApi.list({ pageSize: 200 }), + itemsApi.list({ pageSize: 200 }), + uomsApi.list({ pageSize: 200 }), + warehousesApi.list({ pageSize: 200 }), + usersApi.list({ pageSize: 200 }), + ]) + .then(([bundleRes, templateRes, custRes, itemRes, uomRes, whRes, userRes]) => { + const data = bundleRes + setBundle(data) + setTemplates(templateRes.items) + setCustomers(custRes.items) + setItems(itemRes.items) + setUoms(uomRes.items) + setWarehouses(whRes.items) + setUsers(userRes.items) + setCustomerId(data.customerId) + setWarehouseId(data.warehouseId) + setCashierUserId(data.cashierUserId) + setTemplateId(data.bundleSaleTemplateId) + setBundleName(data.bundleName) + setBundlePrice(data.bundlePrice) + setLines( + data.lines.map((line) => ({ + key: `${line.bundleSaleLineId}`, + bundleSaleTemplateLineId: line.bundleSaleLineId, + itemId: line.itemId, + uomId: line.uomId, + warehouseId: line.warehouseId, + qty: line.qty, + unitPrice: line.unitPrice, + includeInBundle: line.includeInBundle, + sortOrder: line.bundleSaleLineId, + })) + ) + }) + .catch((err) => setError(errorMessage(err))) + }, [bundleSaleId, params.id]) + + const templateLabel = useMemo(() => templates.find((t) => t.bundleSaleTemplateId === templateId)?.templateName ?? "Template", [templates, templateId]) + const componentSubtotal = useMemo(() => lines.reduce((sum, line) => sum + Number(line.qty || 0) * Number(line.unitPrice || 0), 0), [lines]) + const isDraft = bundle?.status === "Draft" + const canEdit = isDraft + + function updateLine(key: string, patch: Partial) { + setLines((prev) => prev.map((line) => (line.key === key ? { ...line, ...patch } : line))) + } + + function addLine() { + const source = lines[lines.length - 1] + if (!source) return + setLines((prev) => [...prev, { ...source, key: crypto.randomUUID() }]) + } + + function removeLine(key: string) { + setLines((prev) => (prev.length === 1 ? prev : prev.filter((line) => line.key !== key))) + } + + async function saveBundle() { + if (!bundle || !customerId || !warehouseId || !cashierUserId || !templateId) return + setBusy(true) + setError(null) + try { + const request: UpdateBundleSaleRequest = { + customerId, + warehouseId, + cashierUserId, + bundleSaleTemplateId: templateId, + bundleName, + bundlePrice, + allowPriceOverride, + lines: lines.map(({ key, ...line }) => line), + } + const res = await bundleApi.updateBundle(bundle.bundleSaleId, request) + setBundle(res) + setEditing(false) + router.refresh() + } catch (err) { + setError(errorMessage(err)) + } finally { + setBusy(false) + } + } + + async function postBundle() { + if (!bundle) return + setBusy(true) + setError(null) + try { + const check = await bundleApi.checkBundlePosting(bundle.bundleSaleId) + if (!check.canPost) { + setError("Resolve stock shortages before posting this bundle.") + return + } + const updated = await bundleApi.postBundle(bundle.bundleSaleId) + setBundle({ ...bundle, ...updated }) + } catch (err) { + setError(errorMessage(err)) + } finally { + setBusy(false) + } + } + + async function cancelBundle() { + if (!bundle) return + setBusy(true) + setError(null) + try { + const updated = await bundleApi.cancelBundle(bundle.bundleSaleId) + setBundle({ ...bundle, ...updated }) + } catch (err) { + setError(errorMessage(err)) + } finally { + setBusy(false) + } + } + + if (error && !bundle) return
{error}
+ if (!bundle) return
Loading bundle sale...
+ + const printHref = `/print/sales/bundles/${bundle.bundleSaleId}` + + return ( +
+
+
+ + + +
+

{bundle.bundleNo}

+

{bundle.bundleName}

+
+
+
+ + + Print + + {canEdit ? ( + editing ? ( + + ) : ( + + ) + ) : null} + {isDraft ? ( + <> + + + + ) : null} +
+
+ + {error ?
{error}
: null} + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + setBundleName(e.target.value)} disabled={!editing || !isDraft} /> +
+
+ + setBundlePrice(Number(e.target.value))} disabled={!editing || !isDraft} /> +
+
+
+ +
+
+
+

Component breakdown

+

{editing ? "Edit the component lines and save." : "Read-only until you enter edit mode."}

+
+ {editing && isDraft ? : {bundle.status}} +
+
+ + + + Item + UOM + Qty + Unit price + Include + {editing && isDraft ? : null} + + + + {lines.map((line) => ( + + + + + + + + updateLine(line.key, { qty: Number(e.target.value) })} disabled={!editing || !isDraft} className="text-right" /> + updateLine(line.key, { unitPrice: Number(e.target.value) })} disabled={!editing || !isDraft} className="text-right" /> + {line.includeInBundle ? "Yes" : "No"} + {editing && isDraft ? : null} + + ))} + +
+
+
+ +
+
+
Component subtotal
{componentSubtotal.toFixed(2)}
+
Bundle price
{bundlePrice.toFixed(2)}
+
Margin
{(bundlePrice - componentSubtotal).toFixed(2)}
+
+
+
+ ) +} diff --git a/Frontend/erp-system/app/dashboard/sales/bundles/new/page.tsx b/Frontend/erp-system/app/dashboard/sales/bundles/new/page.tsx new file mode 100644 index 0000000..42337bf --- /dev/null +++ b/Frontend/erp-system/app/dashboard/sales/bundles/new/page.tsx @@ -0,0 +1,288 @@ +"use client" + +import { useEffect, useMemo, useState } from "react" +import { useRouter, useSearchParams } from "next/navigation" +import Link from "next/link" +import { ArrowLeft, Minus, Plus, Save } from "lucide-react" + +import { bundleApi } from "@/lib/api/bundles" +import { customersApi } from "@/lib/api/customers" +import { itemsApi } from "@/lib/api/items" +import { uomsApi } from "@/lib/api/uoms" +import { warehousesApi } from "@/lib/api/warehouses" +import { usersApi } from "@/lib/api/users" +import { errorMessage } from "@/lib/error-map" +import { Button, buttonVariants } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { cn } from "@/lib/utils" +import { toast } from "@/components/ui/toast" +import { Customer } from "@/types/customers" +import { ItemListItem, Uom, Warehouse } from "@/types/master-data" +import { ManagedUser } from "@/types/users" +import { BundleSaleTemplate, BundleSaleTemplateLine, BundleSaleTemplateSummary, CreateBundleSaleRequest } from "@/types/bundles" + +type EditableLine = BundleSaleTemplateLine & { key: string } + +const blankLine = (source: BundleSaleTemplateLine): EditableLine => ({ ...source, key: crypto.randomUUID() }) + +export default function NewBundleSalePage() { + const router = useRouter() + const searchParams = useSearchParams() + const templateFromQuery = searchParams.get("templateId") + const [customers, setCustomers] = useState([]) + const [items, setItems] = useState([]) + const [uoms, setUoms] = useState([]) + const [warehouses, setWarehouses] = useState([]) + const [users, setUsers] = useState([]) + const [templates, setTemplates] = useState([]) + const [template, setTemplate] = useState(null) + const [customerId, setCustomerId] = useState(null) + const [warehouseId, setWarehouseId] = useState(null) + const [cashierUserId, setCashierUserId] = useState(null) + const [templateId, setTemplateId] = useState(templateFromQuery ? Number(templateFromQuery) : null) + const [bundleName, setBundleName] = useState("Demo Bundle") + const [bundlePrice, setBundlePrice] = useState(0) + const [allowPriceOverride, setAllowPriceOverride] = useState(false) + const [lines, setLines] = useState([]) + const [loading, setLoading] = useState(true) + const [saving, setSaving] = useState(false) + const [submitError, setSubmitError] = useState(null) + + useEffect(() => { + Promise.all([ + customersApi.list({ pageSize: 200 }), + itemsApi.list({ pageSize: 200 }), + uomsApi.list({ pageSize: 200 }), + warehousesApi.list({ pageSize: 200 }), + usersApi.list({ pageSize: 200 }), + bundleApi.listTemplates({ pageSize: 200 }), + ]) + .then(([cust, itemRes, uomRes, whRes, userRes, templateRes]) => { + setCustomers(cust.items) + setItems(itemRes.items) + setUoms(uomRes.items) + setWarehouses(whRes.items) + setUsers(userRes.items) + setTemplates(templateRes.items) + setCustomerId(cust.items[0]?.customerId ?? null) + setWarehouseId(whRes.items[0]?.warehouseId ?? null) + setCashierUserId(userRes.items[0]?.userId ?? null) + setTemplateId((current) => current ?? templateRes.items[0]?.bundleSaleTemplateId ?? null) + }) + .catch((err) => setSubmitError(errorMessage(err))) + .finally(() => setLoading(false)) + }, []) + + useEffect(() => { + if (!templateId) return + bundleApi.getTemplate(templateId).then((res) => { + setTemplate(res) + setLines(res.lines.map(blankLine)) + setBundlePrice(res.lines.reduce((sum, line) => sum + line.qty * line.unitPrice, 0)) + }).catch((err) => setSubmitError(errorMessage(err))) + }, [templateId]) + + const templateLabel = useMemo(() => template?.templateName ?? "Select template", [template]) + const componentSubtotal = useMemo(() => lines.reduce((sum, line) => sum + Number(line.qty || 0) * Number(line.unitPrice || 0), 0), [lines]) + + function updateLine(key: string, patch: Partial) { + setLines((prev) => prev.map((line) => (line.key === key ? { ...line, ...patch } : line))) + } + + function addLine() { + const source = lines[lines.length - 1] ?? template?.lines[0] + if (!source) return + setLines((prev) => [...prev, blankLine(source)]) + } + + function removeLine(key: string) { + setLines((prev) => (prev.length === 1 ? prev : prev.filter((line) => line.key !== key))) + } + + async function submit() { + if (!customerId || !warehouseId || !cashierUserId || !templateId || !template) { + setSubmitError("Select customer, warehouse, cashier, and bundle template.") + return + } + if (lines.length === 0) { + setSubmitError("Add at least one bundle component line.") + return + } + setSaving(true) + setSubmitError(null) + try { + const request: CreateBundleSaleRequest = { + customerId, + warehouseId, + cashierUserId, + bundleSaleTemplateId: templateId, + bundleName, + bundlePrice, + allowPriceOverride, + lines: lines.map(({ key, ...line }) => line), + } + const res = await bundleApi.createBundle(request) + toast.success("Bundle saved", res.bundleNo) + router.push(`/dashboard/sales/bundles/${res.bundleSaleId}`) + } catch (err) { + setSubmitError(errorMessage(err)) + } finally { + setSaving(false) + } + } + + if (loading) return
Loading masters...
+ + return ( +
+
+ + + +
+

Create bundle sale

+

Create a fixed bundle from a stored template.

+
+
+ + {submitError ?
{submitError}
: null} + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + setBundleName(e.target.value)} /> +
+
+ + setBundlePrice(Number(e.target.value))} /> +
+
+ + +
+
+
+ +
+
+
+

Editable component rows

+

These rows are sent to the backend and stored with the bundle.

+
+ +
+
+ + + + Item + UOM + Qty + Unit price + Include + + + + + {lines.map((line) => ( + + + + + + + + updateLine(line.key, { qty: Number(e.target.value) })} className="text-right" /> + updateLine(line.key, { unitPrice: Number(e.target.value) })} className="text-right" /> + {line.includeInBundle ? "Yes" : "No"} + + + + + ))} + +
+
+
+ +
+
+
Component subtotal
{componentSubtotal.toFixed(2)}
+
Bundle price
{bundlePrice.toFixed(2)}
+
Margin
{(bundlePrice - componentSubtotal).toFixed(2)}
+
+
+ +
+ Cancel + +
+
+ ) +} diff --git a/Frontend/erp-system/app/dashboard/sales/bundles/page.tsx b/Frontend/erp-system/app/dashboard/sales/bundles/page.tsx new file mode 100644 index 0000000..927fdc0 --- /dev/null +++ b/Frontend/erp-system/app/dashboard/sales/bundles/page.tsx @@ -0,0 +1,292 @@ +"use client" + +import { useEffect, useMemo, useState } from "react" +import Link from "next/link" +import { ChevronLeft, ChevronRight, Eye, Filter, FileText, Plus, Printer } from "lucide-react" + +import { bundleApi } from "@/lib/api/bundles" +import { customersApi } from "@/lib/api/customers" +import { warehousesApi } from "@/lib/api/warehouses" +import { errorMessage } from "@/lib/error-map" +import { Button, buttonVariants } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { Input } from "@/components/ui/input" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Skeleton } from "@/components/ui/skeleton" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { PaginationMeta } from "@/types/common" +import { Customer } from "@/types/customers" +import { Warehouse } from "@/types/master-data" +import { BundleSaleStatus, BundleSaleSummary } from "@/types/bundles" +import { cn } from "@/lib/utils" + +type StatusFilter = BundleSaleStatus | "All" + +const PAGE_SIZE = 10 +const tabs = ["All", "Draft", "Posted", "Cancelled"] as const + +function statusClass(status: BundleSaleStatus) { + switch (status) { + case "Draft": + return "border-amber-200 bg-amber-50 text-amber-800" + case "Posted": + return "border-emerald-200 bg-emerald-50 text-emerald-800" + case "Cancelled": + return "border-rose-200 bg-rose-50 text-rose-800" + } +} + +export default function BundleSalesPage() { + const [rows, setRows] = useState(null) + const [pagination, setPagination] = useState(null) + const [error, setError] = useState(null) + const [status, setStatus] = useState("All") + const [customerId, setCustomerId] = useState(null) + const [warehouseId, setWarehouseId] = useState(null) + const [searchInput, setSearchInput] = useState("") + const [query, setQuery] = useState("") + const [page, setPage] = useState(1) + const [showFilters, setShowFilters] = useState(false) + const [customers, setCustomers] = useState([]) + const [warehouses, setWarehouses] = useState([]) + + useEffect(() => { + const timeout = setTimeout(() => setQuery(searchInput.trim()), 300) + return () => clearTimeout(timeout) + }, [searchInput]) + + useEffect(() => setPage(1), [query, status, customerId, warehouseId]) + + useEffect(() => { + Promise.all([customersApi.list({ pageSize: 200 }), warehousesApi.list({ pageSize: 200 })]) + .then(([cust, whRes]) => { + setCustomers(cust.items) + setWarehouses(whRes.items) + }) + .catch((err) => setError(errorMessage(err))) + }, []) + + useEffect(() => { + setError(null) + bundleApi + .listBundles({ + page, + pageSize: PAGE_SIZE, + status: status === "All" ? undefined : status, + q: query || undefined, + customerId: customerId ?? undefined, + warehouseId: warehouseId ?? undefined, + }) + .then((res) => { + setRows(res.items) + setPagination(res.pagination) + }) + .catch((err) => setError(errorMessage(err))) + }, [page, status, query, customerId, warehouseId]) + + const visibleRows = useMemo(() => rows ?? [], [rows]) + const hasFilters = status !== "All" || query.length > 0 || customerId !== null || warehouseId !== null + const bundleTotal = visibleRows.reduce((sum, row) => sum + row.grandTotal, 0) + const printHref = `/print/sales/bundles?status=${encodeURIComponent(status)}&q=${encodeURIComponent(query)}&customerId=${customerId ?? ""}&warehouseId=${warehouseId ?? ""}` + + return ( +
+
+
+

Bundle Sales

+

Fixed bundle register with draft, posted, and cancelled states.

+
+
+ + + Print batch + + + + New Bundle + +
+
+ +
+
+
+ {tabs.map((t) => ( + + ))} +
+
+ setSearchInput(e.target.value)} placeholder="Filter by bundle, code, or customer" className="h-12 w-full lg:max-w-sm" /> + +
+
+ + {showFilters && ( +
+
+
Customer
+ +
+
+
Warehouse
+ +
+
+ +
+
+ )} + + {error &&
{error}
} + + {!error && rows === null && ( +
+ {Array.from({ length: 5 }).map((_, i) => ( + + ))} +
+ )} + + {!error && rows !== null && visibleRows.length === 0 && ( +
+ +

{hasFilters ? "No bundle sales match your filters." : "No bundle sales yet."}

+
+ )} + + {!error && rows !== null && visibleRows.length > 0 && ( + <> +
+ + + + Bundle + Customer + Date + Price + Grand + Status + View + + + + {visibleRows.map((row) => ( + + + + {row.bundleNo} + + + {row.customerSnapshotName} + {new Date(row.createdAt).toLocaleDateString()} + {row.bundlePrice.toFixed(2)} + {row.grandTotal.toFixed(2)} + + + {row.status} + + + +
+ + + + + + +
+
+
+ ))} +
+
+
+ +
+
+
+
Rows loaded
+
{visibleRows.length}
+
+
+
Grand total
+
{bundleTotal.toFixed(2)}
+
+
+
+ + {pagination && pagination.totalPages > 1 && ( +
+

+ Showing {(pagination.page - 1) * pagination.pageSize + 1}-{Math.min(pagination.page * pagination.pageSize, pagination.totalItems)} of {pagination.totalItems} +

+
+ + + Page {pagination.page} of {pagination.totalPages} + + +
+
+ )} + + )} +
+
+ ) +} diff --git a/Frontend/erp-system/app/dashboard/sales/bundles/register/page.tsx b/Frontend/erp-system/app/dashboard/sales/bundles/register/page.tsx new file mode 100644 index 0000000..ade96a5 --- /dev/null +++ b/Frontend/erp-system/app/dashboard/sales/bundles/register/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from "next/navigation" + +export default function BundleRegisterPage() { + redirect("/dashboard/sales/bundles") +} diff --git a/Frontend/erp-system/app/dashboard/sales/bundles/reports/page.tsx b/Frontend/erp-system/app/dashboard/sales/bundles/reports/page.tsx new file mode 100644 index 0000000..b6022c6 --- /dev/null +++ b/Frontend/erp-system/app/dashboard/sales/bundles/reports/page.tsx @@ -0,0 +1,27 @@ +"use client" + +import Link from "next/link" +import { ArrowLeft, FileText } from "lucide-react" + +import { buttonVariants } from "@/components/ui/button" +import { cn } from "@/lib/utils" + +export default function BundleReportsPage() { + return ( +
+
+ + + +
+

Bundle Reports

+

Bundle-level reporting will be added after the backend module is wired.

+
+
+
+ + This screen is a placeholder for bundle sales reporting. +
+
+ ) +} diff --git a/Frontend/erp-system/app/dashboard/sales/free-issues/new/page.tsx b/Frontend/erp-system/app/dashboard/sales/free-issues/new/page.tsx index 8e1bf9c..2dced6d 100644 --- a/Frontend/erp-system/app/dashboard/sales/free-issues/new/page.tsx +++ b/Frontend/erp-system/app/dashboard/sales/free-issues/new/page.tsx @@ -182,12 +182,13 @@ export default function NewFreeIssuePage() { discountValue: Number(line.discountValue), taxPct: Number(line.taxPct), isFreeIssue: line.isFreeIssue, - parentLineId: line.parentLineId || null, + parentLineId: line.parentLineId ?? null, })), } if (editingRowId) { const latest = await salesApi.getFreeIssue(editingRowId) + if (!latest.etag) throw new Error("Missing ETag for free issue update.") await salesApi.updateFreeIssue(editingRowId, payload, latest.etag) toast.success("Free issue updated") setEditingRowId(null) diff --git a/Frontend/erp-system/app/dashboard/sales/invoices/[id]/page.tsx b/Frontend/erp-system/app/dashboard/sales/invoices/[id]/page.tsx index 113ec6d..269be9b 100644 --- a/Frontend/erp-system/app/dashboard/sales/invoices/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/sales/invoices/[id]/page.tsx @@ -5,7 +5,6 @@ import Link from "next/link" import { useRouter } from "next/navigation" import { ArrowLeft, Minus, Plus, Printer, Save, Send, X } from "lucide-react" -import { companyApi } from "@/lib/api/company" import { salesApi } from "@/lib/api/sales" import { customersApi } from "@/lib/api/customers" import { itemsApi } from "@/lib/api/items" @@ -14,7 +13,6 @@ import { warehousesApi } from "@/lib/api/warehouses" import { errorMessage } from "@/lib/error-map" import { cn } from "@/lib/utils" import { getSuggestedUnitPrice } from "@/lib/sales-line-utils" -import { CompanyProfile } from "@/types/company" import { Customer } from "@/types/customers" import { ItemListItem, Uom, Warehouse } from "@/types/master-data" import { CreateSalesInvoiceLineRequest, SalesInvoice, SalesInvoicePostingCheck, SalesInvoiceStatus, SalesInvoiceType } from "@/types/sales" @@ -64,7 +62,6 @@ export default function SalesInvoiceDetailPage({ params }: { params: Promise<{ i const invoiceId = Number(resolvedParams.id) const [invoice, setInvoice] = useState(null) - const [company, setCompany] = useState(null) const [customers, setCustomers] = useState([]) const [items, setItems] = useState([]) const [uoms, setUoms] = useState([]) @@ -86,15 +83,13 @@ export default function SalesInvoiceDetailPage({ params }: { params: Promise<{ i } Promise.all([ - companyApi.getProfile(), customersApi.list({ pageSize: 200 }), itemsApi.list({ pageSize: 200 }), uomsApi.list({ pageSize: 200 }), warehousesApi.list({ pageSize: 200 }), salesApi.getInvoice(invoiceId), ]) - .then(([companyRes, customerRes, itemRes, uomRes, warehouseRes, doc]) => { - setCompany(companyRes.data) + .then(([customerRes, itemRes, uomRes, warehouseRes, doc]) => { setCustomers(customerRes.items) setItems(itemRes.items) setUoms(uomRes.items) @@ -269,7 +264,12 @@ export default function SalesInvoiceDetailPage({ params }: { params: Promise<{ i

{invoice.invoiceNo}

- + Print @@ -281,9 +281,9 @@ export default function SalesInvoiceDetailPage({ params }: { params: Promise<{ i
-
Sales Invoice
-

{invoice.invoiceNo}

-
+
Sales Invoice
+

{invoice.invoiceNo}

+
Status: {invoice.status} Type: {invoice.invoiceType} @@ -291,12 +291,8 @@ export default function SalesInvoiceDetailPage({ params }: { params: Promise<{ i
-
{company?.tradeName ?? company?.legalName ?? "ERP Core Trading"}
-
- {company?.addressLine1 ?? ""} - {company?.city ? `, ${company.city}` : ""} -
- {company?.taxRegistrationNo ?
Tax No: {company.taxRegistrationNo}
: null} +
ERP Core Trading
+
Company details are not configured for this invoice view.
@@ -418,7 +414,7 @@ export default function SalesInvoiceDetailPage({ params }: { params: Promise<{ i
Notes
-

{company?.footerNote ?? "Standard invoice template view."}

+

Standard invoice template view.

diff --git a/Frontend/erp-system/app/dashboard/sales/invoices/[id]/print/page.tsx b/Frontend/erp-system/app/dashboard/sales/invoices/[id]/print/page.tsx index 6fca4fb..c86302d 100644 --- a/Frontend/erp-system/app/dashboard/sales/invoices/[id]/print/page.tsx +++ b/Frontend/erp-system/app/dashboard/sales/invoices/[id]/print/page.tsx @@ -5,7 +5,6 @@ import Link from "next/link" import { ArrowLeft, Printer } from "lucide-react" import { salesApi } from "@/lib/api/sales" -import { companyApi } from "@/lib/api/company" import { customersApi } from "@/lib/api/customers" import { itemsApi } from "@/lib/api/items" import { uomsApi } from "@/lib/api/uoms" @@ -16,14 +15,12 @@ import { Skeleton } from "@/components/ui/skeleton" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { cn } from "@/lib/utils" import { Customer } from "@/types/customers" -import { CompanyProfile } from "@/types/company" import { ItemListItem, Uom, Warehouse } from "@/types/master-data" import { SalesInvoice } from "@/types/sales" export default function SalesInvoicePrintPage({ params }: { params: { id: string } }) { const invoiceId = Number(params.id) const [invoice, setInvoice] = useState(null) - const [company, setCompany] = useState(null) const [customers, setCustomers] = useState([]) const [items, setItems] = useState([]) const [uoms, setUoms] = useState([]) @@ -36,15 +33,13 @@ export default function SalesInvoicePrintPage({ params }: { params: { id: string return } Promise.all([ - companyApi.getProfile(), customersApi.list({ pageSize: 200 }), itemsApi.list({ pageSize: 200 }), uomsApi.list({ pageSize: 200 }), warehousesApi.list({ pageSize: 200 }), salesApi.getInvoice(invoiceId), ]) - .then(([companyRes, cust, itemRes, uomRes, whRes, doc]) => { - setCompany(companyRes.data) + .then(([cust, itemRes, uomRes, whRes, doc]) => { setCustomers(cust.items) setItems(itemRes.items) setUoms(uomRes.items) @@ -94,10 +89,8 @@ export default function SalesInvoicePrintPage({ params }: { params: { id: string
Status: {invoice.status} · Type: {invoice.invoiceType}
-
{company?.tradeName ?? company?.legalName ?? "ERP Core Trading"}
- {company?.logoUrl ? {company.tradeName : null} -
{company?.addressLine1}{company?.city ? `, ${company.city}` : ""}
- {company?.taxRegistrationNo ?
Tax No: {company.taxRegistrationNo}
: null} +
ERP Core Trading
+
Company details are not configured for this print view.
Invoice date: {new Date(invoice.invoiceDate).toLocaleDateString()}
Printed: {new Date().toLocaleString()}
Free qty total: {freeQtyTotal.toFixed(2)}
@@ -181,9 +174,7 @@ export default function SalesInvoicePrintPage({ params }: { params: { id: string
Notes
-

- {company?.footerNote ?? "Standard invoice print view."} -

+

Standard invoice print view.

Totals
@@ -199,19 +190,6 @@ export default function SalesInvoicePrintPage({ params }: { params: { id: string
- {company ? ( -
-
Bank Details
-
-
Bank {company.bankName ?? "—"}
-
Branch {company.bankBranch ?? "—"}
-
Account Name {company.accountName ?? "—"}
-
Account No {company.accountNumber ?? "—"}
-
SWIFT {company.swiftCode ?? "—"}
-
VAT {company.vatRegistrationNo ?? "—"}
-
-
- ) : null}
) diff --git a/Frontend/erp-system/app/dashboard/sales/invoices/new/page.tsx b/Frontend/erp-system/app/dashboard/sales/invoices/new/page.tsx index 6da9053..4b84e07 100644 --- a/Frontend/erp-system/app/dashboard/sales/invoices/new/page.tsx +++ b/Frontend/erp-system/app/dashboard/sales/invoices/new/page.tsx @@ -99,17 +99,16 @@ export default function NewSalesInvoicePage() { ]) setActiveFocSchemes( freeIssueRes.items.flatMap((issue) => { - const firstLine = issue.lines?.[0] - if (!firstLine) return [] - const item = itemRes.items.find((candidate) => candidate.itemId === firstLine.itemId) + if (!issue.itemId) return [] + const item = itemRes.items.find((candidate) => candidate.itemId === issue.itemId) const warehouse = whRes.items.find((candidate) => candidate.warehouseId === issue.warehouseId) return [ { id: issue.salesSlipId, slipNo: issue.slipNo, - schemeLabel: `Buy ${firstLine.qty} Get ${firstLine.freeQty || 0}`, + schemeLabel: issue.schemeLabel, warehouseName: warehouse?.name ?? `Warehouse ${issue.warehouseId}`, - productLabel: `${item?.sku ?? `SKU-${firstLine.itemId}`} - ${item?.name ?? firstLine.itemName ?? `Item ${firstLine.itemId}`}`, + productLabel: `${item?.sku ?? issue.itemSku} - ${item?.name ?? issue.itemName}`, }, ] }), diff --git a/Frontend/erp-system/app/dashboard/sales/invoices/page.tsx b/Frontend/erp-system/app/dashboard/sales/invoices/page.tsx index 5e306e3..d439ef7 100644 --- a/Frontend/erp-system/app/dashboard/sales/invoices/page.tsx +++ b/Frontend/erp-system/app/dashboard/sales/invoices/page.tsx @@ -69,6 +69,7 @@ export default function SalesInvoicesPage() { const grossTotal = visibleRows.reduce((sum, row) => sum + row.totals.subtotal, 0) const discountTotal = visibleRows.reduce((sum, row) => sum + row.totals.discountTotal, 0) const netTotal = visibleRows.reduce((sum, row) => sum + row.totals.grandTotal, 0) + const printHref = `/print/sales/invoices?status=${encodeURIComponent(status)}&q=${encodeURIComponent(query)}` return (
@@ -78,10 +79,15 @@ export default function SalesInvoicesPage() {

Invoice register with filters, posting flow, and settlement tracking.

- + New Invoice diff --git a/Frontend/erp-system/app/dashboard/sales/slips/[id]/page.tsx b/Frontend/erp-system/app/dashboard/sales/slips/[id]/page.tsx index 3d7f552..9a50c88 100644 --- a/Frontend/erp-system/app/dashboard/sales/slips/[id]/page.tsx +++ b/Frontend/erp-system/app/dashboard/sales/slips/[id]/page.tsx @@ -2,7 +2,7 @@ import { use, useEffect, useMemo, useState } from "react" import Link from "next/link" -import { ArrowLeft, Minus, Plus, Save, Send, X } from "lucide-react" +import { ArrowLeft, Minus, Plus, Printer, Save, Send, X } from "lucide-react" import { salesApi } from "@/lib/api/sales" import { customersApi } from "@/lib/api/customers" @@ -251,6 +251,15 @@ export default function SalesSlipDetailPage({ params }: { params: Promise<{ id:
+ + + Print + diff --git a/Frontend/erp-system/app/dashboard/sales/slips/page.tsx b/Frontend/erp-system/app/dashboard/sales/slips/page.tsx index 98806e3..ad31b4a 100644 --- a/Frontend/erp-system/app/dashboard/sales/slips/page.tsx +++ b/Frontend/erp-system/app/dashboard/sales/slips/page.tsx @@ -69,6 +69,7 @@ export default function SalesSlipsPage() { const grossTotal = visibleRows.reduce((sum, row) => sum + row.totals.subtotal, 0) const discountTotal = visibleRows.reduce((sum, row) => sum + row.totals.discountTotal, 0) const netTotal = visibleRows.reduce((sum, row) => sum + row.totals.grandTotal, 0) + const printHref = `/print/sales/slips?status=${encodeURIComponent(status)}&q=${encodeURIComponent(query)}` return (
@@ -78,10 +79,15 @@ export default function SalesSlipsPage() {

Counter sales register with posting and cancellation flow.

- + New Slip diff --git a/Frontend/erp-system/app/layout.tsx b/Frontend/erp-system/app/layout.tsx index 73ba6c1..28ad97b 100644 --- a/Frontend/erp-system/app/layout.tsx +++ b/Frontend/erp-system/app/layout.tsx @@ -27,6 +27,7 @@ export default function RootLayout({ diff --git a/Frontend/erp-system/app/print/sales/bundles/[id]/page.tsx b/Frontend/erp-system/app/print/sales/bundles/[id]/page.tsx new file mode 100644 index 0000000..1c834ad --- /dev/null +++ b/Frontend/erp-system/app/print/sales/bundles/[id]/page.tsx @@ -0,0 +1,74 @@ +"use client" + +import { useEffect, useState } from "react" +import { useParams } from "next/navigation" +import { Printer } from "lucide-react" + +import { bundleApi } from "@/lib/api/bundles" +import { errorMessage } from "@/lib/error-map" +import { Button } from "@/components/ui/button" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { BundleSale } from "@/types/bundles" + +export default function BundlePrintPage() { + const params = useParams<{ id: string }>() + const bundleSaleId = Number(params.id) + const [bundle, setBundle] = useState(null) + const [error, setError] = useState(null) + + useEffect(() => { + if (!Number.isFinite(bundleSaleId)) { + setError(`Invalid bundle id '${params.id}'.`) + return + } + bundleApi.getBundle(bundleSaleId).then((res) => setBundle(res)).catch((err) => setError(errorMessage(err))) + }, [bundleSaleId, params.id]) + + if (error && !bundle) return
{error}
+ if (!bundle) return
Loading bundle print...
+ + return ( +
+
+ +
+
+
Bundle Sales
+

{bundle.bundleNo}

+

{bundle.bundleName}

+
+
+
Customer
{bundle.customerSnapshotName}
+
Warehouse
{bundle.warehouseId}
+
Status
{bundle.status}
+
+
+ + + + Item + Description + Qty + Price + Total + + + + {bundle.lines.map((line) => ( + + {line.itemId} + {line.description} + {line.qty.toFixed(2)} + {line.unitPrice.toFixed(2)} + {line.lineTotal.toFixed(2)} + + ))} + +
+
+
+ ) +} diff --git a/Frontend/erp-system/app/print/sales/bundles/page.tsx b/Frontend/erp-system/app/print/sales/bundles/page.tsx new file mode 100644 index 0000000..ac0db97 --- /dev/null +++ b/Frontend/erp-system/app/print/sales/bundles/page.tsx @@ -0,0 +1,90 @@ +"use client" + +import { useEffect, useState } from "react" +import { useSearchParams } from "next/navigation" +import { Printer } from "lucide-react" + +import { bundleApi } from "@/lib/api/bundles" +import { errorMessage } from "@/lib/error-map" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { BundleSaleSummary } from "@/types/bundles" + +function statusClass(status: BundleSaleSummary["status"]) { + switch (status) { + case "Draft": + return "border-amber-200 bg-amber-50 text-amber-800" + case "Posted": + return "border-emerald-200 bg-emerald-50 text-emerald-800" + case "Cancelled": + return "border-rose-200 bg-rose-50 text-rose-800" + } +} + +export default function BundleBatchPrintPage() { + const searchParams = useSearchParams() + const status = searchParams.get("status") ?? "All" + const query = searchParams.get("q") ?? "" + const [rows, setRows] = useState(null) + const [error, setError] = useState(null) + + useEffect(() => { + bundleApi.listBundles({ page: 1, pageSize: 200 }).then((res) => setRows(res.items)).catch((err) => setError(errorMessage(err))) + }, []) + + const visibleRows = rows?.filter((row) => { + const matchesStatus = status === "All" || row.status === status + const matchesQuery = `${row.bundleNo} ${row.customerSnapshotName} ${row.bundleName}`.toLowerCase().includes(query.toLowerCase()) + return matchesStatus && matchesQuery + }) + + if (error && !rows) return
{error}
+ if (!rows) return
Loading bundle print data...
+ + return ( +
+
+ +
+
+
Bundle Sales
+

Bundle Batch Print

+

Printed register snapshot of current bundle sales.

+
+
+ + + + Bundle + Customer + Date + Price + Grand + Status + + + + {visibleRows?.map((row) => ( + + {row.bundleNo} + {row.customerSnapshotName} + {new Date(row.createdAt).toLocaleDateString()} + {row.bundlePrice.toFixed(2)} + {row.grandTotal.toFixed(2)} + + + {row.status} + + + + ))} + +
+
+
+ ) +} diff --git a/Frontend/erp-system/app/print/sales/invoices/[id]/page.tsx b/Frontend/erp-system/app/print/sales/invoices/[id]/page.tsx new file mode 100644 index 0000000..629418d --- /dev/null +++ b/Frontend/erp-system/app/print/sales/invoices/[id]/page.tsx @@ -0,0 +1,148 @@ +"use client" + +import { use, useEffect, useMemo, useState } from "react" +import { Printer } from "lucide-react" + +import { salesApi } from "@/lib/api/sales" +import { customersApi } from "@/lib/api/customers" +import { itemsApi } from "@/lib/api/items" +import { uomsApi } from "@/lib/api/uoms" +import { warehousesApi } from "@/lib/api/warehouses" +import { errorMessage } from "@/lib/error-map" +import { Button } from "@/components/ui/button" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { Customer } from "@/types/customers" +import { ItemListItem, Uom, Warehouse } from "@/types/master-data" +import { SalesInvoice } from "@/types/sales" + +export default function SalesInvoicePrintPage({ params }: { params: Promise<{ id: string }> }) { + const resolvedParams = use(params) + const invoiceId = Number(resolvedParams.id) + const [invoice, setInvoice] = useState(null) + const [customers, setCustomers] = useState([]) + const [items, setItems] = useState([]) + const [uoms, setUoms] = useState([]) + const [warehouses, setWarehouses] = useState([]) + const [error, setError] = useState(null) + + useEffect(() => { + if (!Number.isFinite(invoiceId)) { + setError(`Invalid invoice id '${resolvedParams.id}'.`) + return + } + + Promise.all([ + customersApi.list({ pageSize: 200 }), + itemsApi.list({ pageSize: 200 }), + uomsApi.list({ pageSize: 200 }), + warehousesApi.list({ pageSize: 200 }), + salesApi.getInvoice(invoiceId), + ]) + .then(([cust, itemRes, uomRes, whRes, doc]) => { + setCustomers(cust.items) + setItems(itemRes.items) + setUoms(uomRes.items) + setWarehouses(whRes.items) + setInvoice(doc.data) + }) + .catch((err) => setError(errorMessage(err))) + }, [resolvedParams.id, invoiceId]) + + const freeQtyTotal = useMemo(() => invoice?.totals.freeQtyTotal ?? 0, [invoice]) + + if (error && !invoice) { + return
{error}
+ } + + if (!invoice) { + return
{error ?? "Invoice print data is loading or unavailable."}
+ } + + const customer = customers.find((c) => c.customerId === invoice.customerId) + const warehouse = warehouses.find((w) => w.warehouseId === invoice.warehouseId) + + return ( +
+
+ +
+ +
+
+
Sales Invoice
+

{invoice.invoiceNo}

+
Status: {invoice.status} · Type: {invoice.invoiceType}
+
+
+
ERP Core Trading
+
Invoice print view
+
Invoice date: {new Date(invoice.invoiceDate).toLocaleDateString()}
+
Printed: {new Date().toLocaleString()}
+
Free qty total: {freeQtyTotal.toFixed(2)}
+
+
+ +
+
+
Customer
+
{invoice.customerSnapshotName}
+
Customer ID: {invoice.customerId}
+ {invoice.customerSnapshotTaxNo ?
Tax No: {invoice.customerSnapshotTaxNo}
: null} + {customer?.displayName ?
Customer: {customer.displayName}
: null} +
+
+
Warehouse
+
{warehouse?.name ?? `#${invoice.warehouseId}`}
+
Code: {warehouse?.code ?? invoice.warehouseId}
+
+
+
Totals
+
+
Subtotal
{invoice.totals.subtotal.toFixed(2)}
+
Discount
{invoice.totals.discountTotal.toFixed(2)}
+
Free qty
{freeQtyTotal.toFixed(2)}
+
Tax
{invoice.totals.taxTotal.toFixed(2)}
+
Net payable
{invoice.totals.netPayable.toFixed(2)}
+
+
+
+ +
+ + + + Item + UOM + Qty + Free + Unit price + Discount + Tax + Line total + + + + {invoice.lines.map((line) => ( + + +
{line.description}
+
SKU {items.find((i) => i.itemId === line.itemId)?.sku ?? `#${line.itemId}`}
+
+ {uoms.find((u) => u.uomId === line.uomId)?.name ?? `#${line.uomId}`} + {line.qty.toFixed(2)} + {line.freeQty > 0 ? line.freeQty.toFixed(2) : "—"} + {line.unitPrice.toFixed(2)} + {line.discountAmount.toFixed(2)} + {line.taxAmount.toFixed(2)} + {line.lineTotal.toFixed(2)} +
+ ))} +
+
+
+
+ ) +} diff --git a/Frontend/erp-system/app/print/sales/invoices/page.tsx b/Frontend/erp-system/app/print/sales/invoices/page.tsx new file mode 100644 index 0000000..ab16f55 --- /dev/null +++ b/Frontend/erp-system/app/print/sales/invoices/page.tsx @@ -0,0 +1,107 @@ +"use client" + +import { useEffect, useState } from "react" +import { useSearchParams } from "next/navigation" +import { Printer } from "lucide-react" + +import { salesApi } from "@/lib/api/sales" +import { errorMessage } from "@/lib/error-map" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { SalesInvoiceSummary } from "@/types/sales" + +function statusClass(status: SalesInvoiceSummary["status"]) { + switch (status) { + case "Draft": + return "border-amber-200 bg-amber-50 text-amber-800" + case "Posted": + return "border-emerald-200 bg-emerald-50 text-emerald-800" + case "Cancelled": + return "border-rose-200 bg-rose-50 text-rose-800" + } +} + +export default function SalesInvoiceBatchPrintPage() { + const searchParams = useSearchParams() + const status = searchParams.get("status") ?? "All" + const query = searchParams.get("q") ?? "" + const [rows, setRows] = useState(null) + const [error, setError] = useState(null) + + useEffect(() => { + salesApi + .listInvoices({ page: 1, pageSize: 200 }) + .then((res) => setRows(res.items)) + .catch((err) => setError(errorMessage(err))) + }, []) + + const visibleRows = rows?.filter((row) => { + const matchesStatus = status === "All" || row.status === status + const matchesQuery = + `${row.invoiceNo} ${row.customerSnapshotName}`.toLowerCase().includes(query.toLowerCase()) + return matchesStatus && matchesQuery + }) + + if (error && !rows) { + return
{error}
+ } + + if (!rows) { + return
{error ?? "Invoice batch print data is loading or unavailable."}
+ } + + return ( +
+
+ +
+ +
+
Sales Invoices
+

Invoice Batch Print

+

Printed register snapshot of current invoices.

+
+ +
+ + + + Invoice + Customer + Date + Due + Lines + Gross + Discount + Net + Status + + + + {visibleRows?.map((row) => ( + + {row.invoiceNo} + {row.customerSnapshotName} + {new Date(row.createdAt).toLocaleDateString()} + {new Date(row.invoiceDate).toLocaleDateString()} + {row.totals.freeQtyTotal.toFixed(2)} + {row.totals.subtotal.toFixed(2)} + -{row.totals.discountTotal.toFixed(2)} + {row.totals.grandTotal.toFixed(2)} + + + {row.status} + + + + ))} + +
+
+
+ ) +} diff --git a/Frontend/erp-system/app/print/sales/slips/[id]/page.tsx b/Frontend/erp-system/app/print/sales/slips/[id]/page.tsx new file mode 100644 index 0000000..24ca5db --- /dev/null +++ b/Frontend/erp-system/app/print/sales/slips/[id]/page.tsx @@ -0,0 +1,144 @@ +"use client" + +import { use, useEffect, useMemo, useState } from "react" +import { Printer } from "lucide-react" + +import { salesApi } from "@/lib/api/sales" +import { customersApi } from "@/lib/api/customers" +import { itemsApi } from "@/lib/api/items" +import { uomsApi } from "@/lib/api/uoms" +import { warehousesApi } from "@/lib/api/warehouses" +import { usersApi } from "@/lib/api/users" +import { errorMessage } from "@/lib/error-map" +import { Button } from "@/components/ui/button" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { Customer } from "@/types/customers" +import { ItemListItem, Uom, Warehouse } from "@/types/master-data" +import { ManagedUser } from "@/types/users" +import { SalesSlip } from "@/types/sales" + +export default function SalesSlipPrintPage({ params }: { params: Promise<{ id: string }> }) { + const resolvedParams = use(params) + const slipId = Number(resolvedParams.id) + const [slip, setSlip] = useState(null) + const [customers, setCustomers] = useState([]) + const [items, setItems] = useState([]) + const [uoms, setUoms] = useState([]) + const [warehouses, setWarehouses] = useState([]) + const [users, setUsers] = useState([]) + const [error, setError] = useState(null) + + useEffect(() => { + if (!Number.isFinite(slipId)) { + setError(`Invalid slip id '${resolvedParams.id}'.`) + return + } + + Promise.all([ + customersApi.list({ pageSize: 200 }), + itemsApi.list({ pageSize: 200 }), + uomsApi.list({ pageSize: 200 }), + warehousesApi.list({ pageSize: 200 }), + usersApi.list({ pageSize: 200 }), + salesApi.getSlip(slipId), + ]) + .then(([cust, itemRes, uomRes, whRes, userRes, doc]) => { + setCustomers(cust.items) + setItems(itemRes.items) + setUoms(uomRes.items) + setWarehouses(whRes.items) + setUsers(userRes.items) + setSlip(doc.data) + }) + .catch((err) => setError(errorMessage(err))) + }, [resolvedParams.id, slipId]) + + const subtotal = useMemo(() => slip?.totals.subtotal ?? 0, [slip]) + + if (error && !slip) { + return
{error}
+ } + + if (!slip) { + return
{error ?? "Slip print data is loading or unavailable."}
+ } + + const customer = customers.find((c) => c.customerId === slip.customerId) + const warehouse = warehouses.find((w) => w.warehouseId === slip.warehouseId) + + return ( +
+
+ +
+ +
+
Sales Slip
+

{slip.slipNo}

+
Status: {slip.status} · Date: {new Date(slip.slipDate).toLocaleDateString()}
+
+ +
+
+
Customer
+
{slip.customerSnapshotName}
+
Customer ID: {slip.customerId}
+ {customer?.displayName ?
Customer: {customer.displayName}
: null} +
+
+
Warehouse
+
{warehouse?.name ?? `#${slip.warehouseId}`}
+
Code: {warehouse?.code ?? slip.warehouseId}
+
+
+
Totals
+
+
Subtotal
{slip.totals.subtotal.toFixed(2)}
+
Discount
{slip.totals.discountTotal.toFixed(2)}
+
Free qty
{slip.totals.freeQtyTotal.toFixed(2)}
+
Net total
{slip.totals.grandTotal.toFixed(2)}
+
+
+
+ +
+ + + + Item + UOM + Qty + Free + Unit price + Line total + + + + {slip.lines.map((line) => ( + + +
{line.description}
+
SKU {items.find((i) => i.itemId === line.itemId)?.sku ?? `#${line.itemId}`}
+
+ {uoms.find((u) => u.uomId === line.uomId)?.name ?? `#${line.uomId}`} + {line.qty.toFixed(0)} + {line.freeQty > 0 ? line.freeQty.toFixed(0) : "—"} + {line.unitPrice.toFixed(2)} + {line.lineTotal.toFixed(2)} +
+ ))} +
+
+
+ +
+
Cashier
+
{users.find((u) => u.userId === slip.cashierUserId)?.displayName ?? `#${slip.cashierUserId}`}
+
Subtotal: {subtotal.toFixed(2)}
+
+
+ ) +} diff --git a/Frontend/erp-system/app/print/sales/slips/page.tsx b/Frontend/erp-system/app/print/sales/slips/page.tsx new file mode 100644 index 0000000..0c941b4 --- /dev/null +++ b/Frontend/erp-system/app/print/sales/slips/page.tsx @@ -0,0 +1,105 @@ +"use client" + +import { useEffect, useState } from "react" +import { useSearchParams } from "next/navigation" +import { Printer } from "lucide-react" + +import { salesApi } from "@/lib/api/sales" +import { errorMessage } from "@/lib/error-map" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { SalesSlipSummary } from "@/types/sales" + +function statusClass(status: SalesSlipSummary["status"]) { + switch (status) { + case "Draft": + return "border-amber-200 bg-amber-50 text-amber-800" + case "Posted": + return "border-emerald-200 bg-emerald-50 text-emerald-800" + case "Cancelled": + return "border-rose-200 bg-rose-50 text-rose-800" + } +} + +export default function SalesSlipBatchPrintPage() { + const searchParams = useSearchParams() + const status = searchParams.get("status") ?? "All" + const query = searchParams.get("q") ?? "" + const [rows, setRows] = useState(null) + const [error, setError] = useState(null) + + useEffect(() => { + salesApi + .listSlips({ page: 1, pageSize: 200 }) + .then((res) => setRows(res.items)) + .catch((err) => setError(errorMessage(err))) + }, []) + + const visibleRows = rows?.filter((row) => { + const matchesStatus = status === "All" || row.status === status + const matchesQuery = + `${row.slipNo} ${row.customerSnapshotName}`.toLowerCase().includes(query.toLowerCase()) + return matchesStatus && matchesQuery + }) + + if (error && !rows) { + return
{error}
+ } + + if (!rows) { + return
{error ?? "Slip batch print data is loading or unavailable."}
+ } + + return ( +
+
+ +
+ +
+
Sales Slips
+

Slip Batch Print

+

Printed register snapshot of current slips.

+
+ +
+ + + + Slip + Customer + Date + Status + Lines + Gross + Discount + Net + + + + {visibleRows?.map((row) => ( + + {row.slipNo} + {row.customerSnapshotName} + {new Date(row.createdAt).toLocaleDateString()} + + + {row.status} + + + {row.totals.freeQtyTotal.toFixed(2)} + {row.totals.subtotal.toFixed(2)} + -{row.totals.discountTotal.toFixed(2)} + {row.totals.grandTotal.toFixed(2)} + + ))} + +
+
+
+ ) +} diff --git a/Frontend/erp-system/components/Layouts/AppSidebar.tsx b/Frontend/erp-system/components/Layouts/AppSidebar.tsx index a286926..5585562 100644 --- a/Frontend/erp-system/components/Layouts/AppSidebar.tsx +++ b/Frontend/erp-system/components/Layouts/AppSidebar.tsx @@ -110,6 +110,7 @@ const navItems: { children: [ { title: "Invoices", code: "sales.invoices", href: "/dashboard/sales/invoices", icon: FileText }, { title: "Slips", code: "sales.slips", href: "/dashboard/sales/slips", icon: ShoppingCart }, + { title: "Bundle Sales", code: "sales.bundle-sales", href: "/dashboard/sales/bundles", icon: Boxes }, { title: "Free Issues", code: "sales.free-issues", href: "/dashboard/sales/free-issues", icon: PackageX }, { title: "Reports", code: "sales.reports", href: "/dashboard/sales/reports", icon: FileBarChart }, ], diff --git a/Frontend/erp-system/lib/api/bundles.ts b/Frontend/erp-system/lib/api/bundles.ts new file mode 100644 index 0000000..9400d3f --- /dev/null +++ b/Frontend/erp-system/lib/api/bundles.ts @@ -0,0 +1,49 @@ +import { apiRequest, buildQuery } from "@/lib/api-client" +import { PagedResponse } from "@/types/common" +import { + BundleSale, + BundleSalePostingCheck, + BundleSaleSummary, + BundleSaleTemplate, + BundleSaleTemplateSummary, + CreateBundleSaleRequest, + UpdateBundleSaleRequest, +} from "@/types/bundles" + +export const bundleApi = { + listBundles(params: { page?: number; pageSize?: number; status?: string; customerId?: number; warehouseId?: number; q?: string } = {}): Promise> { + return apiRequest>(`/bundle-sales${buildQuery(params)}`) + }, + + getBundle(bundleSaleId: number): Promise { + return apiRequest(`/bundle-sales/${bundleSaleId}`) + }, + + createBundle(request: CreateBundleSaleRequest): Promise { + return apiRequest("/bundle-sales", { method: "POST", body: request }) + }, + + updateBundle(bundleSaleId: number, request: UpdateBundleSaleRequest): Promise { + return apiRequest(`/bundle-sales/${bundleSaleId}`, { method: "PUT", body: request }) + }, + + postBundle(bundleSaleId: number): Promise { + return apiRequest(`/bundle-sales/${bundleSaleId}/post`, { method: "POST" }) + }, + + cancelBundle(bundleSaleId: number): Promise { + return apiRequest(`/bundle-sales/${bundleSaleId}/cancel`, { method: "POST" }) + }, + + checkBundlePosting(bundleSaleId: number): Promise { + return apiRequest(`/bundle-sales/${bundleSaleId}/posting-check`) + }, + + listTemplates(params: { page?: number; pageSize?: number; q?: string } = {}): Promise> { + return apiRequest>(`/bundle-sales/templates${buildQuery(params)}`) + }, + + getTemplate(bundleSaleTemplateId: number): Promise { + return apiRequest(`/bundle-sales/templates/${bundleSaleTemplateId}`) + }, +} diff --git a/Frontend/erp-system/types/bundles.ts b/Frontend/erp-system/types/bundles.ts new file mode 100644 index 0000000..d5d8ae7 --- /dev/null +++ b/Frontend/erp-system/types/bundles.ts @@ -0,0 +1,114 @@ +import { EntityStatus } from "@/types/common" + +export type BundleSaleStatus = "Draft" | "Posted" | "Cancelled" + +export interface BundleSaleTemplateLine { + bundleSaleTemplateLineId: number + itemId: number + uomId: number + warehouseId: number + qty: number + unitPrice: number + includeInBundle: boolean + sortOrder: number +} + +export interface BundleSaleTemplateSummary { + bundleSaleTemplateId: number + templateCode: string + templateName: string + description: string | null + status: EntityStatus + lineCount: number + createdAt: string + updatedAt: string | null +} + +export interface BundleSaleTemplate { + bundleSaleTemplateId: number + templateCode: string + templateName: string + description: string | null + status: EntityStatus + createdAt: string + updatedAt: string | null + lines: BundleSaleTemplateLine[] +} + +export interface BundleSaleLine { + bundleSaleLineId: number + itemId: number + description: string + qty: number + uomId: number + warehouseId: number + unitPrice: number + lineTotal: number + includeInBundle: boolean + isComponent: boolean + parentLineId: number | null +} + +export interface BundleSaleTotals { + componentSubtotal: number + bundlePrice: number + marginAmount: number + discountTotal: number + taxTotal: number + grandTotal: number +} + +export interface BundleSaleSummary { + bundleSaleId: number + bundleNo: string + bundleDate: string + customerId: number + customerSnapshotName: string + warehouseId: number + bundleName: string + bundleCode: string + status: BundleSaleStatus + componentSubtotal: number + bundlePrice: number + grandTotal: number + createdAt: string +} + +export interface BundleSale extends BundleSaleSummary, BundleSaleTotals { + cashierUserId: number + bundleSaleTemplateId: number + updatedAt: string | null + lines: BundleSaleLine[] +} + +export interface BundleSalePostingIssue { + bundleSaleLineId: number + itemId: number + itemSku: string + itemName: string + warehouseId: number + requestedQty: number + availableQty: number + shortQty: number +} + +export interface BundleSalePostingCheck { + bundleSaleId: number + bundleNo: string + status: BundleSaleStatus + canPost: boolean + issues: BundleSalePostingIssue[] +} + +export interface CreateBundleSaleRequest { + customerId: number + warehouseId: number + cashierUserId: number + bundleSaleTemplateId: number + bundleName: string + bundlePrice: number + allowPriceOverride: boolean + lines: BundleSaleTemplateLine[] +} + +export type UpdateBundleSaleRequest = CreateBundleSaleRequest diff --git a/docs/14-BACKEND-SALES-API.md b/docs/14-BACKEND-SALES-API.md index a683434..a6a1b3b 100644 --- a/docs/14-BACKEND-SALES-API.md +++ b/docs/14-BACKEND-SALES-API.md @@ -1,6 +1,6 @@ # 14 · BACKEND — Sales API Reference -> **Authoritative for:** sales API contracts for invoices, slips, free issues, and sales reports. +> **Authoritative for:** sales API contracts for invoices, slips, bundle sales, free issues, and sales reports. > **Navigation:** start from `00-CORE.md`. Sales business rules live in `docs/SALES_MODULE_PLAN.md` and the sales-related backend progress is tracked in `Backend/PROGRESS.md`. > **Scope:** this document covers the sales endpoints currently implemented in ERPCore. Free issue is modeled as a sales-slip alias, not a separate table. @@ -132,9 +132,62 @@ Before posting, the UI calls `GET /api/v1/sales-slips/{salesSlipId}/posting-chec ### `POST /api/v1/sales-slips/{salesSlipId}/cancel` Cancels a draft slip. +--- + +## 4. Bundle Sales + +Bundle sales are a separate sales document family for fixed bundle compositions. + +### `GET /api/v1/bundle-sales` +Query: +- `page` +- `pageSize` +- `q` +- `customerId` +- `warehouseId` + +Returns a paged list of `BundleSaleSummaryDto`. + +### `GET /api/v1/bundle-sales/{bundleSaleId}` +Returns `BundleSaleDto`. + +### `GET /api/v1/bundle-sales/{bundleSaleId}/posting-check` +Validates component stock before posting. + +### `POST /api/v1/bundle-sales` +Creates a draft bundle sale from a fixed template. + +Request: +```json +{ + "customerId": 2, + "warehouseId": 1, + "cashierUserId": 1, + "bundleSaleTemplateId": 1, + "bundleName": "Summer Promo Pack", + "bundleCode": "BND-001", + "bundlePrice": 2500, + "allowPriceOverride": true +} +``` + +### `PUT /api/v1/bundle-sales/{bundleSaleId}` +Updates a draft bundle sale. Requires `If-Match`. + +### `POST /api/v1/bundle-sales/{bundleSaleId}/post` +Posts the bundle and consumes stock from the included component lines. + +### `POST /api/v1/bundle-sales/{bundleSaleId}/cancel` +Cancels a draft bundle sale. + +Business rule: +- bundle composition is fixed by template lines +- posting consumes component stock, not a synthetic bundle stock item +- print pages should show both the bundle summary and the component breakdown + --- -## 4. Free Issues +## 5. Free Issues Free issue is a business alias over sales slips. There is no separate free-issue table in the current schema. @@ -165,7 +218,7 @@ Business rule: --- -## 5. Sales Reports +## 6. Sales Reports ### `GET /api/v1/reports/sales` Returns the report catalog. @@ -217,8 +270,9 @@ Validation rule: --- -## 6. Notes +## 7. Notes - The sales report service reads both invoices and slips where relevant. - Free issue reporting is derived from the same sales document lines. +- Bundle sales are treated as a separate fixed-composition document family. - There is no separate free-issue table in the current schema. diff --git a/docs/15-BACKEND-SALES-BUNDLES.md b/docs/15-BACKEND-SALES-BUNDLES.md new file mode 100644 index 0000000..40da017 --- /dev/null +++ b/docs/15-BACKEND-SALES-BUNDLES.md @@ -0,0 +1,136 @@ +# 15 · BACKEND — Bundle Sales API + +> **Authoritative for:** fixed-composition bundle sales, templates, posting, and print data. +> **Navigation:** start from `00-CORE.md`. This module follows the same repository/UoW/ETag/audit patterns as invoices and slips. + +--- + +## 1. Concept + +Bundle sales are a separate sales document family for fixed bundle compositions. + +Rules: +- a bundle sale is created from a bundle template +- the bundle template defines fixed component stock lines +- posting consumes stock from the component items, not from a synthetic bundle SKU +- the bundle header carries the commercial sale value +- print views show both bundle summary and component breakdown + +--- + +## 2. API + +### `GET /api/v1/bundle-sales` +Query: +- `page` +- `pageSize` +- `q` +- `customerId` +- `warehouseId` + +### `GET /api/v1/bundle-sales/{bundleSaleId}` +Returns the bundle sale header and all component lines. + +### `GET /api/v1/bundle-sales/{bundleSaleId}/posting-check` +Validates component stock before posting. + +### `POST /api/v1/bundle-sales` +Creates a draft bundle sale from a fixed bundle template. + +### `PUT /api/v1/bundle-sales/{bundleSaleId}` +Updates a draft bundle sale. Requires `If-Match`. + +### `POST /api/v1/bundle-sales/{bundleSaleId}/post` +Consumes stock from included component lines and marks the bundle as posted. + +### `POST /api/v1/bundle-sales/{bundleSaleId}/cancel` +Cancels a draft bundle sale. + +--- + +## 3. Template Rules + +- bundle templates are fixed in composition +- each template line maps to one component stock item +- component quantities are expanded into the sale draft at creation time +- price override is allowed only when the caller is permitted by business rules + +--- + +## 4. Data Model + +### `BundleSaleTemplate` +- `BundleSaleTemplateId` +- `TemplateCode` +- `TemplateName` +- `Description` +- `Status` +- `CreatedAt` +- `UpdatedAt` +- `RowVersion` + +### `BundleSaleTemplateLine` +- `BundleSaleTemplateLineId` +- `BundleSaleTemplateId` +- `ItemId` +- `UomId` +- `WarehouseId` +- `Qty` +- `UnitPrice` +- `IncludeInBundle` +- `SortOrder` + +### `BundleSale` +- `BundleSaleId` +- `BundleNo` +- `BundleDate` +- `CustomerId` +- `CustomerSnapshotName` +- `WarehouseId` +- `CashierUserId` +- `BundleSaleTemplateId` +- `BundleName` +- `BundleCode` +- `Status` +- `ComponentSubtotal` +- `BundlePrice` +- `MarginAmount` +- `DiscountTotal` +- `TaxTotal` +- `GrandTotal` +- `CreatedAt` +- `UpdatedAt` +- `RowVersion` + +### `BundleSaleLine` +- `BundleSaleLineId` +- `BundleSaleId` +- `ItemId` +- `Description` +- `Qty` +- `UomId` +- `WarehouseId` +- `UnitPrice` +- `LineTotal` +- `IncludeInBundle` +- `IsComponent` +- `ParentLineId` +- `RowVersion` + +--- + +## 5. Posting + +Posting behavior: +- validate each included component line has sufficient stock +- consume FIFO layers from the component items +- write stock ledger rows for each component +- mark the bundle as posted in the same transaction + +--- + +## 6. Notes + +- This module is intentionally separate from invoices and slips. +- Bundle sales are for fixed compositions only in this phase. +- Print views should mirror the existing sales document print behavior without the dashboard shell. diff --git a/docs/SALES_MODULE_PLAN.md b/docs/SALES_MODULE_PLAN.md index fc2038d..861e318 100644 --- a/docs/SALES_MODULE_PLAN.md +++ b/docs/SALES_MODULE_PLAN.md @@ -282,6 +282,8 @@ Add richer commercial features after Phase 1 is stable and tested. - price lists - promotions - free issue schemes +- bundle sales templates +- bundle sales documents - reservations - payment allocation - approval flow @@ -304,6 +306,18 @@ Promotional header. #### `PromotionRule` Buy-X-get-Y, discount, or reward rules. +#### `BundleSaleTemplate` +Fixed bundle composition definition. + +#### `BundleSaleTemplateLine` +Component stock items and quantities inside a bundle template. + +#### `BundleSale` +Posted or draft bundle sale header. + +#### `BundleSaleLine` +Component lines expanded from a bundle template. + #### `FreeIssueScheme` Separate free issue header.