Files
zentral/src/backend/Zentral.Infrastructure/Data/ZentralDbContext.cs

1009 lines
38 KiB
C#

using Zentral.Domain.Entities;
using Zentral.Domain.Entities.Warehouse;
using Zentral.Domain.Entities.Purchases;
using Zentral.Domain.Entities.Sales;
using Zentral.Domain.Entities.Production;
using Zentral.Domain.Entities.HR;
using Zentral.Domain.Entities.Communications;
using Microsoft.EntityFrameworkCore;
namespace Zentral.Infrastructure.Data;
public class ZentralDbContext : DbContext
{
public ZentralDbContext(DbContextOptions<ZentralDbContext> options) : base(options)
{
}
public DbSet<Cliente> Clienti => Set<Cliente>();
public DbSet<Location> Location => Set<Location>();
public DbSet<Evento> Eventi => Set<Evento>();
public DbSet<TipoEvento> TipiEvento => Set<TipoEvento>();
public DbSet<TipoPasto> TipiPasto => Set<TipoPasto>();
public DbSet<TipoOspite> TipiOspite => Set<TipoOspite>();
public DbSet<TipoRisorsa> TipiRisorsa => Set<TipoRisorsa>();
public DbSet<TipoMateriale> TipiMateriale => Set<TipoMateriale>();
public DbSet<CodiceCategoria> CodiciCategoria => Set<CodiceCategoria>();
public DbSet<Risorsa> Risorse => Set<Risorsa>();
public DbSet<Articolo> Articoli => Set<Articolo>();
public DbSet<EventoDettaglioOspiti> EventiDettaglioOspiti => Set<EventoDettaglioOspiti>();
public DbSet<EventoDettaglioPrelievo> EventiDettaglioPrelievo => Set<EventoDettaglioPrelievo>();
public DbSet<EventoDettaglioRisorsa> EventiDettaglioRisorse => Set<EventoDettaglioRisorsa>();
public DbSet<EventoAcconto> EventiAcconti => Set<EventoAcconto>();
public DbSet<EventoAltroCosto> EventiAltriCosti => Set<EventoAltroCosto>();
public DbSet<EventoAllegato> EventiAllegati => Set<EventoAllegato>();
public DbSet<EventoDegustazione> EventiDegustazioni => Set<EventoDegustazione>();
public DbSet<Configurazione> Configurazioni => Set<Configurazione>();
public DbSet<Utente> Utenti => Set<Utente>();
public DbSet<UserDashboardPreference> UserDashboardPreferences => Set<UserDashboardPreference>();
// Report entities
public DbSet<ReportTemplate> ReportTemplates => Set<ReportTemplate>();
public DbSet<ReportFont> ReportFonts => Set<ReportFont>();
public DbSet<ReportImage> ReportImages => Set<ReportImage>();
public DbSet<VirtualDataset> VirtualDatasets => Set<VirtualDataset>();
// App system entities
public DbSet<App> Apps => Set<App>();
public DbSet<AppSubscription> AppSubscriptions => Set<AppSubscription>();
// Auto Code system
public DbSet<AutoCode> AutoCodes => Set<AutoCode>();
// Custom Fields system
public DbSet<CustomFieldDefinition> CustomFieldDefinitions => Set<CustomFieldDefinition>();
// Warehouse module entities
public DbSet<WarehouseLocation> WarehouseLocations => Set<WarehouseLocation>();
public DbSet<WarehouseArticle> WarehouseArticles => Set<WarehouseArticle>();
public DbSet<WarehouseArticleCategory> WarehouseArticleCategories => Set<WarehouseArticleCategory>();
public DbSet<ArticleBatch> ArticleBatches => Set<ArticleBatch>();
public DbSet<ArticleSerial> ArticleSerials => Set<ArticleSerial>();
public DbSet<ArticleBarcode> ArticleBarcodes => Set<ArticleBarcode>();
public DbSet<StockLevel> StockLevels => Set<StockLevel>();
public DbSet<StockMovement> StockMovements => Set<StockMovement>();
public DbSet<StockMovementLine> StockMovementLines => Set<StockMovementLine>();
public DbSet<MovementReason> MovementReasons => Set<MovementReason>();
public DbSet<StockValuation> StockValuations => Set<StockValuation>();
public DbSet<StockValuationLayer> StockValuationLayers => Set<StockValuationLayer>();
public DbSet<InventoryCount> InventoryCounts => Set<InventoryCount>();
public DbSet<InventoryCountLine> InventoryCountLines => Set<InventoryCountLine>();
// Purchases module entities
public DbSet<Supplier> Suppliers => Set<Supplier>();
public DbSet<PurchaseOrder> PurchaseOrders => Set<PurchaseOrder>();
public DbSet<PurchaseOrderLine> PurchaseOrderLines => Set<PurchaseOrderLine>();
// Sales module entities
public DbSet<SalesOrder> SalesOrders => Set<SalesOrder>();
public DbSet<SalesOrderLine> SalesOrderLines => Set<SalesOrderLine>();
// Production module entities
public DbSet<BillOfMaterials> BillOfMaterials => Set<BillOfMaterials>();
public DbSet<BillOfMaterialsComponent> BillOfMaterialsComponents => Set<BillOfMaterialsComponent>();
public DbSet<ProductionOrder> ProductionOrders => Set<ProductionOrder>();
public DbSet<ProductionOrderComponent> ProductionOrderComponents => Set<ProductionOrderComponent>();
public DbSet<WorkCenter> WorkCenters => Set<WorkCenter>();
public DbSet<ProductionCycle> ProductionCycles => Set<ProductionCycle>();
public DbSet<ProductionCyclePhase> ProductionCyclePhases => Set<ProductionCyclePhase>();
public DbSet<ProductionOrderPhase> ProductionOrderPhases => Set<ProductionOrderPhase>();
public DbSet<MrpSuggestion> MrpSuggestions => Set<MrpSuggestion>();
// Personale module entities
public DbSet<Dipendente> Dipendenti => Set<Dipendente>();
public DbSet<Contratto> Contratti => Set<Contratto>();
public DbSet<Assenza> Assenze => Set<Assenza>();
public DbSet<Pagamento> Pagamenti => Set<Pagamento>();
public DbSet<Rimborso> Rimborsi => Set<Rimborso>();
// Communications module entities
public DbSet<EmailLog> EmailLogs => Set<EmailLog>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// ===============================================
// PERSONALE MODULE ENTITIES
// ===============================================
modelBuilder.Entity<Dipendente>(entity =>
{
entity.ToTable("Dipendenti");
entity.HasIndex(e => e.CodiceFiscale).IsUnique();
});
modelBuilder.Entity<Contratto>(entity =>
{
entity.ToTable("Contratti");
entity.Property(e => e.RetribuzioneLorda).HasPrecision(18, 2);
entity.HasOne(e => e.Dipendente)
.WithMany(d => d.Contratti)
.HasForeignKey(e => e.DipendenteId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<Assenza>(entity =>
{
entity.ToTable("Assenze");
entity.HasOne(e => e.Dipendente)
.WithMany(d => d.Assenze)
.HasForeignKey(e => e.DipendenteId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<Pagamento>(entity =>
{
entity.ToTable("Pagamenti");
entity.Property(e => e.ImportoNetto).HasPrecision(18, 2);
entity.HasOne(e => e.Dipendente)
.WithMany(d => d.Pagamenti)
.HasForeignKey(e => e.DipendenteId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<Rimborso>(entity =>
{
entity.ToTable("Rimborsi");
entity.Property(e => e.Importo).HasPrecision(18, 2);
entity.HasOne(e => e.Dipendente)
.WithMany(d => d.Rimborsi)
.HasForeignKey(e => e.DipendenteId)
.OnDelete(DeleteBehavior.Cascade);
});
// Cliente
modelBuilder.Entity<Cliente>(entity =>
{
entity.HasIndex(e => e.RagioneSociale);
entity.HasIndex(e => e.PartitaIva);
});
// Location
modelBuilder.Entity<Location>(entity =>
{
entity.HasIndex(e => e.Nome);
});
// Evento
modelBuilder.Entity<Evento>(entity =>
{
entity.HasIndex(e => e.DataEvento);
entity.HasIndex(e => e.Stato);
entity.HasIndex(e => e.Codice);
entity.HasOne(e => e.Cliente)
.WithMany(c => c.Eventi)
.HasForeignKey(e => e.ClienteId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.Location)
.WithMany(l => l.Eventi)
.HasForeignKey(e => e.LocationId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.TipoEvento)
.WithMany(t => t.Eventi)
.HasForeignKey(e => e.TipoEventoId)
.OnDelete(DeleteBehavior.SetNull);
});
// TipoEvento
modelBuilder.Entity<TipoEvento>(entity =>
{
entity.HasOne(e => e.TipoPasto)
.WithMany(t => t.TipiEvento)
.HasForeignKey(e => e.TipoPastoId)
.OnDelete(DeleteBehavior.SetNull);
});
// Articolo
modelBuilder.Entity<Articolo>(entity =>
{
entity.HasIndex(e => e.Codice).IsUnique();
entity.HasOne(e => e.TipoMateriale)
.WithMany(t => t.Articoli)
.HasForeignKey(e => e.TipoMaterialeId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.Categoria)
.WithMany(c => c.Articoli)
.HasForeignKey(e => e.CategoriaId)
.OnDelete(DeleteBehavior.SetNull);
});
// Risorsa
modelBuilder.Entity<Risorsa>(entity =>
{
entity.HasOne(e => e.TipoRisorsa)
.WithMany(t => t.Risorse)
.HasForeignKey(e => e.TipoRisorsaId)
.OnDelete(DeleteBehavior.SetNull);
});
// EventoDettaglioOspiti
modelBuilder.Entity<EventoDettaglioOspiti>(entity =>
{
entity.HasOne(e => e.Evento)
.WithMany(ev => ev.DettagliOspiti)
.HasForeignKey(e => e.EventoId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.TipoOspite)
.WithMany(t => t.DettagliOspiti)
.HasForeignKey(e => e.TipoOspiteId)
.OnDelete(DeleteBehavior.Cascade);
});
// EventoDettaglioPrelievo
modelBuilder.Entity<EventoDettaglioPrelievo>(entity =>
{
entity.HasOne(e => e.Evento)
.WithMany(ev => ev.DettagliPrelievo)
.HasForeignKey(e => e.EventoId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Articolo)
.WithMany(a => a.DettagliPrelievo)
.HasForeignKey(e => e.ArticoloId)
.OnDelete(DeleteBehavior.Cascade);
});
// EventoDettaglioRisorsa
modelBuilder.Entity<EventoDettaglioRisorsa>(entity =>
{
entity.HasOne(e => e.Evento)
.WithMany(ev => ev.DettagliRisorse)
.HasForeignKey(e => e.EventoId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Risorsa)
.WithMany(r => r.DettagliRisorse)
.HasForeignKey(e => e.RisorsaId)
.OnDelete(DeleteBehavior.Cascade);
});
// EventoAcconto
modelBuilder.Entity<EventoAcconto>(entity =>
{
entity.HasOne(e => e.Evento)
.WithMany(ev => ev.Acconti)
.HasForeignKey(e => e.EventoId)
.OnDelete(DeleteBehavior.Cascade);
});
// EventoAltroCosto
modelBuilder.Entity<EventoAltroCosto>(entity =>
{
entity.HasOne(e => e.Evento)
.WithMany(ev => ev.AltriCosti)
.HasForeignKey(e => e.EventoId)
.OnDelete(DeleteBehavior.Cascade);
});
// EventoAllegato
modelBuilder.Entity<EventoAllegato>(entity =>
{
entity.HasOne(e => e.Evento)
.WithMany(ev => ev.Allegati)
.HasForeignKey(e => e.EventoId)
.OnDelete(DeleteBehavior.Cascade);
});
// EventoDegustazione
modelBuilder.Entity<EventoDegustazione>(entity =>
{
entity.HasOne(e => e.Evento)
.WithMany(ev => ev.Degustazioni)
.HasForeignKey(e => e.EventoId)
.OnDelete(DeleteBehavior.Cascade);
});
// Configurazione
modelBuilder.Entity<Configurazione>(entity =>
{
entity.HasIndex(e => e.Chiave).IsUnique();
});
// Utente
modelBuilder.Entity<Utente>(entity =>
{
entity.HasIndex(e => e.Username).IsUnique();
});
// UserDashboardPreference
modelBuilder.Entity<UserDashboardPreference>(entity =>
{
entity.HasIndex(e => e.UtenteId).IsUnique();
entity.HasOne(e => e.Utente)
.WithOne()
.HasForeignKey<UserDashboardPreference>(e => e.UtenteId)
.OnDelete(DeleteBehavior.Cascade);
});
// ReportTemplate
modelBuilder.Entity<ReportTemplate>(entity =>
{
entity.HasIndex(e => e.Nome);
entity.HasIndex(e => e.Categoria);
});
// ReportFont
modelBuilder.Entity<ReportFont>(entity =>
{
entity.HasIndex(e => e.FontFamily);
});
// ReportImage
modelBuilder.Entity<ReportImage>(entity =>
{
entity.HasIndex(e => e.Categoria);
});
// VirtualDataset
modelBuilder.Entity<VirtualDataset>(entity =>
{
entity.HasIndex(e => e.Nome).IsUnique();
entity.HasIndex(e => e.Categoria);
});
// App
modelBuilder.Entity<App>(entity =>
{
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.SortOrder);
entity.Property(e => e.BasePrice)
.HasPrecision(18, 2);
entity.Property(e => e.MonthlyMultiplier)
.HasPrecision(5, 2);
});
// AppSubscription
modelBuilder.Entity<AppSubscription>(entity =>
{
entity.HasIndex(e => e.AppId).IsUnique();
entity.Property(e => e.PaidPrice)
.HasPrecision(18, 2);
entity.HasOne(e => e.App)
.WithOne(m => m.Subscription)
.HasForeignKey<AppSubscription>(e => e.AppId)
.OnDelete(DeleteBehavior.Cascade);
});
// AutoCode
modelBuilder.Entity<AutoCode>(entity =>
{
entity.HasIndex(e => e.EntityCode).IsUnique();
entity.HasIndex(e => e.ModuleCode);
});
// CustomFieldDefinition
modelBuilder.Entity<CustomFieldDefinition>(entity =>
{
entity.HasIndex(e => new { e.EntityName, e.FieldName }).IsUnique();
entity.HasIndex(e => e.EntityName);
});
// ===============================================
// WAREHOUSE MODULE ENTITIES
// ===============================================
// WarehouseLocation
modelBuilder.Entity<WarehouseLocation>(entity =>
{
entity.ToTable("WarehouseLocations");
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.IsDefault);
entity.HasIndex(e => e.IsActive);
});
// WarehouseArticleCategory
modelBuilder.Entity<WarehouseArticleCategory>(entity =>
{
entity.ToTable("WarehouseArticleCategories");
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.ParentCategoryId);
entity.HasIndex(e => e.FullPath);
entity.HasOne(e => e.ParentCategory)
.WithMany(c => c.ChildCategories)
.HasForeignKey(e => e.ParentCategoryId)
.OnDelete(DeleteBehavior.Restrict);
});
// WarehouseArticle
modelBuilder.Entity<WarehouseArticle>(entity =>
{
entity.ToTable("WarehouseArticles");
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.Barcode);
entity.HasIndex(e => e.CategoryId);
entity.HasIndex(e => e.IsActive);
entity.Property(e => e.StandardCost).HasPrecision(18, 4);
entity.Property(e => e.LastPurchaseCost).HasPrecision(18, 4);
entity.Property(e => e.WeightedAverageCost).HasPrecision(18, 4);
entity.Property(e => e.BaseSellingPrice).HasPrecision(18, 4);
entity.Property(e => e.MinimumStock).HasPrecision(18, 4);
entity.Property(e => e.MaximumStock).HasPrecision(18, 4);
entity.Property(e => e.ReorderPoint).HasPrecision(18, 4);
entity.Property(e => e.ReorderQuantity).HasPrecision(18, 4);
entity.Property(e => e.UnitConversionFactor).HasPrecision(18, 6);
entity.Property(e => e.Weight).HasPrecision(18, 4);
entity.Property(e => e.Volume).HasPrecision(18, 6);
entity.HasOne(e => e.Category)
.WithMany(c => c.Articles)
.HasForeignKey(e => e.CategoryId)
.OnDelete(DeleteBehavior.SetNull);
});
// ArticleBatch
modelBuilder.Entity<ArticleBatch>(entity =>
{
entity.ToTable("ArticleBatches");
entity.HasIndex(e => new { e.ArticleId, e.BatchNumber }).IsUnique();
entity.HasIndex(e => e.ExpiryDate);
entity.HasIndex(e => e.Status);
entity.Property(e => e.UnitCost).HasPrecision(18, 4);
entity.Property(e => e.InitialQuantity).HasPrecision(18, 4);
entity.Property(e => e.CurrentQuantity).HasPrecision(18, 4);
entity.Property(e => e.ReservedQuantity).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany(a => a.Batches)
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Cascade);
});
// ArticleSerial
modelBuilder.Entity<ArticleSerial>(entity =>
{
entity.ToTable("ArticleSerials");
entity.HasIndex(e => new { e.ArticleId, e.SerialNumber }).IsUnique();
entity.HasIndex(e => e.Status);
entity.HasIndex(e => e.CurrentWarehouseId);
entity.Property(e => e.UnitCost).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany(a => a.Serials)
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Batch)
.WithMany(b => b.Serials)
.HasForeignKey(e => e.BatchId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.CurrentWarehouse)
.WithMany()
.HasForeignKey(e => e.CurrentWarehouseId)
.OnDelete(DeleteBehavior.SetNull);
});
// ArticleBarcode
modelBuilder.Entity<ArticleBarcode>(entity =>
{
entity.ToTable("ArticleBarcodes");
entity.HasIndex(e => e.Barcode).IsUnique();
entity.HasIndex(e => e.ArticleId);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany(a => a.Barcodes)
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Cascade);
});
// StockLevel
modelBuilder.Entity<StockLevel>(entity =>
{
entity.ToTable("StockLevels");
entity.HasIndex(e => new { e.ArticleId, e.WarehouseId, e.BatchId }).IsUnique();
entity.HasIndex(e => e.WarehouseId);
entity.HasIndex(e => e.LocationCode);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.Property(e => e.ReservedQuantity).HasPrecision(18, 4);
entity.Property(e => e.OnOrderQuantity).HasPrecision(18, 4);
entity.Property(e => e.StockValue).HasPrecision(18, 4);
entity.Property(e => e.UnitCost).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany(a => a.StockLevels)
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Warehouse)
.WithMany(w => w.StockLevels)
.HasForeignKey(e => e.WarehouseId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Batch)
.WithMany(b => b.StockLevels)
.HasForeignKey(e => e.BatchId)
.OnDelete(DeleteBehavior.SetNull);
});
// MovementReason
modelBuilder.Entity<MovementReason>(entity =>
{
entity.ToTable("MovementReasons");
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.MovementType);
entity.HasIndex(e => e.IsActive);
});
// StockMovement
modelBuilder.Entity<StockMovement>(entity =>
{
entity.ToTable("StockMovements");
entity.HasIndex(e => e.DocumentNumber).IsUnique();
entity.HasIndex(e => e.MovementDate);
entity.HasIndex(e => e.Type);
entity.HasIndex(e => e.Status);
entity.HasIndex(e => e.ExternalReference);
entity.Property(e => e.TotalValue).HasPrecision(18, 4);
entity.HasOne(e => e.SourceWarehouse)
.WithMany(w => w.SourceMovements)
.HasForeignKey(e => e.SourceWarehouseId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(e => e.DestinationWarehouse)
.WithMany(w => w.DestinationMovements)
.HasForeignKey(e => e.DestinationWarehouseId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(e => e.Reason)
.WithMany(r => r.Movements)
.HasForeignKey(e => e.ReasonId)
.OnDelete(DeleteBehavior.SetNull);
});
// StockMovementLine
modelBuilder.Entity<StockMovementLine>(entity =>
{
entity.ToTable("StockMovementLines");
entity.HasIndex(e => new { e.MovementId, e.LineNumber }).IsUnique();
entity.HasIndex(e => e.ArticleId);
entity.HasIndex(e => e.BatchId);
entity.HasIndex(e => e.SerialId);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.Property(e => e.UnitCost).HasPrecision(18, 4);
entity.Property(e => e.LineValue).HasPrecision(18, 4);
entity.HasOne(e => e.Movement)
.WithMany(m => m.Lines)
.HasForeignKey(e => e.MovementId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Article)
.WithMany(a => a.MovementLines)
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(e => e.Batch)
.WithMany(b => b.MovementLines)
.HasForeignKey(e => e.BatchId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.Serial)
.WithMany(s => s.MovementLines)
.HasForeignKey(e => e.SerialId)
.OnDelete(DeleteBehavior.SetNull);
});
// StockValuation
modelBuilder.Entity<StockValuation>(entity =>
{
entity.ToTable("StockValuations");
entity.HasIndex(e => new { e.Period, e.ArticleId, e.WarehouseId }).IsUnique();
entity.HasIndex(e => e.ValuationDate);
entity.HasIndex(e => e.IsClosed);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.Property(e => e.UnitCost).HasPrecision(18, 4);
entity.Property(e => e.TotalValue).HasPrecision(18, 4);
entity.Property(e => e.InboundQuantity).HasPrecision(18, 4);
entity.Property(e => e.InboundValue).HasPrecision(18, 4);
entity.Property(e => e.OutboundQuantity).HasPrecision(18, 4);
entity.Property(e => e.OutboundValue).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany()
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Warehouse)
.WithMany()
.HasForeignKey(e => e.WarehouseId)
.OnDelete(DeleteBehavior.SetNull);
});
// StockValuationLayer
modelBuilder.Entity<StockValuationLayer>(entity =>
{
entity.ToTable("StockValuationLayers");
entity.HasIndex(e => new { e.ArticleId, e.WarehouseId, e.LayerDate });
entity.HasIndex(e => e.IsExhausted);
entity.Property(e => e.OriginalQuantity).HasPrecision(18, 4);
entity.Property(e => e.RemainingQuantity).HasPrecision(18, 4);
entity.Property(e => e.UnitCost).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany()
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Warehouse)
.WithMany()
.HasForeignKey(e => e.WarehouseId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Batch)
.WithMany()
.HasForeignKey(e => e.BatchId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.SourceMovement)
.WithMany()
.HasForeignKey(e => e.SourceMovementId)
.OnDelete(DeleteBehavior.SetNull);
});
// InventoryCount
modelBuilder.Entity<InventoryCount>(entity =>
{
entity.ToTable("InventoryCounts");
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.InventoryDate);
entity.HasIndex(e => e.Status);
entity.Property(e => e.PositiveDifferenceValue).HasPrecision(18, 4);
entity.Property(e => e.NegativeDifferenceValue).HasPrecision(18, 4);
entity.HasOne(e => e.Warehouse)
.WithMany()
.HasForeignKey(e => e.WarehouseId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.Category)
.WithMany()
.HasForeignKey(e => e.CategoryId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.AdjustmentMovement)
.WithMany()
.HasForeignKey(e => e.AdjustmentMovementId)
.OnDelete(DeleteBehavior.SetNull);
});
// InventoryCountLine
modelBuilder.Entity<InventoryCountLine>(entity =>
{
entity.ToTable("InventoryCountLines");
entity.HasIndex(e => new { e.InventoryCountId, e.ArticleId, e.WarehouseId, e.BatchId }).IsUnique();
entity.HasIndex(e => e.ArticleId);
entity.Property(e => e.TheoreticalQuantity).HasPrecision(18, 4);
entity.Property(e => e.CountedQuantity).HasPrecision(18, 4);
entity.Property(e => e.SecondCountQuantity).HasPrecision(18, 4);
entity.Property(e => e.UnitCost).HasPrecision(18, 4);
entity.HasOne(e => e.InventoryCount)
.WithMany(i => i.Lines)
.HasForeignKey(e => e.InventoryCountId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Article)
.WithMany()
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(e => e.Warehouse)
.WithMany()
.HasForeignKey(e => e.WarehouseId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(e => e.Batch)
.WithMany()
.HasForeignKey(e => e.BatchId)
.OnDelete(DeleteBehavior.SetNull);
});
// ===============================================
// PURCHASES MODULE ENTITIES
// ===============================================
// Supplier
modelBuilder.Entity<Supplier>(entity =>
{
entity.ToTable("Suppliers");
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.Name);
entity.HasIndex(e => e.VatNumber);
entity.HasIndex(e => e.IsActive);
});
// PurchaseOrder
modelBuilder.Entity<PurchaseOrder>(entity =>
{
entity.ToTable("PurchaseOrders");
entity.HasIndex(e => e.OrderNumber).IsUnique();
entity.HasIndex(e => e.OrderDate);
entity.HasIndex(e => e.SupplierId);
entity.HasIndex(e => e.Status);
entity.Property(e => e.TotalNet).HasPrecision(18, 4);
entity.Property(e => e.TotalTax).HasPrecision(18, 4);
entity.Property(e => e.TotalGross).HasPrecision(18, 4);
entity.HasOne(e => e.Supplier)
.WithMany(s => s.PurchaseOrders)
.HasForeignKey(e => e.SupplierId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(e => e.DestinationWarehouse)
.WithMany()
.HasForeignKey(e => e.DestinationWarehouseId)
.OnDelete(DeleteBehavior.SetNull);
});
// PurchaseOrderLine
modelBuilder.Entity<PurchaseOrderLine>(entity =>
{
entity.ToTable("PurchaseOrderLines");
entity.HasIndex(e => e.PurchaseOrderId);
entity.HasIndex(e => e.WarehouseArticleId);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.Property(e => e.ReceivedQuantity).HasPrecision(18, 4);
entity.Property(e => e.UnitPrice).HasPrecision(18, 4);
entity.Property(e => e.TaxRate).HasPrecision(18, 2);
entity.Property(e => e.DiscountPercent).HasPrecision(18, 2);
entity.Property(e => e.LineTotal).HasPrecision(18, 4);
entity.HasOne(e => e.PurchaseOrder)
.WithMany(o => o.Lines)
.HasForeignKey(e => e.PurchaseOrderId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.WarehouseArticle)
.WithMany()
.HasForeignKey(e => e.WarehouseArticleId)
.OnDelete(DeleteBehavior.Restrict);
});
// ===============================================
// SALES MODULE ENTITIES
// ===============================================
// SalesOrder
modelBuilder.Entity<SalesOrder>(entity =>
{
entity.ToTable("SalesOrders");
entity.HasIndex(e => e.OrderNumber).IsUnique();
entity.HasIndex(e => e.OrderDate);
entity.HasIndex(e => e.CustomerId);
entity.HasIndex(e => e.Status);
entity.Property(e => e.TotalNet).HasPrecision(18, 4);
entity.Property(e => e.TotalTax).HasPrecision(18, 4);
entity.Property(e => e.TotalGross).HasPrecision(18, 4);
entity.HasOne(e => e.Customer)
.WithMany(c => c.SalesOrders)
.HasForeignKey(e => e.CustomerId)
.OnDelete(DeleteBehavior.Restrict);
});
// SalesOrderLine
modelBuilder.Entity<SalesOrderLine>(entity =>
{
entity.ToTable("SalesOrderLines");
entity.HasIndex(e => e.SalesOrderId);
entity.HasIndex(e => e.WarehouseArticleId);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.Property(e => e.ShippedQuantity).HasPrecision(18, 4);
entity.Property(e => e.UnitPrice).HasPrecision(18, 4);
entity.Property(e => e.TaxRate).HasPrecision(18, 2);
entity.Property(e => e.DiscountPercent).HasPrecision(18, 2);
entity.Property(e => e.LineTotal).HasPrecision(18, 4);
entity.HasOne(e => e.SalesOrder)
.WithMany(o => o.Lines)
.HasForeignKey(e => e.SalesOrderId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.WarehouseArticle)
.WithMany()
.HasForeignKey(e => e.WarehouseArticleId)
.OnDelete(DeleteBehavior.Restrict);
});
// ===============================================
// PRODUCTION MODULE ENTITIES
// ===============================================
// BillOfMaterials
modelBuilder.Entity<BillOfMaterials>(entity =>
{
entity.ToTable("BillOfMaterials");
entity.HasIndex(e => e.ArticleId);
entity.HasIndex(e => e.IsActive);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany()
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Restrict);
});
// BillOfMaterialsComponent
modelBuilder.Entity<BillOfMaterialsComponent>(entity =>
{
entity.ToTable("BillOfMaterialsComponents");
entity.HasIndex(e => e.BillOfMaterialsId);
entity.HasIndex(e => e.ComponentArticleId);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.Property(e => e.ScrapPercentage).HasPrecision(18, 2);
entity.HasOne(e => e.BillOfMaterials)
.WithMany(b => b.Components)
.HasForeignKey(e => e.BillOfMaterialsId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.ComponentArticle)
.WithMany()
.HasForeignKey(e => e.ComponentArticleId)
.OnDelete(DeleteBehavior.Restrict);
});
// ProductionOrder
modelBuilder.Entity<ProductionOrder>(entity =>
{
entity.ToTable("ProductionOrders");
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.ArticleId);
entity.HasIndex(e => e.Status);
entity.HasIndex(e => e.StartDate);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany()
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Restrict);
});
// ProductionOrderComponent
modelBuilder.Entity<ProductionOrderComponent>(entity =>
{
entity.ToTable("ProductionOrderComponents");
entity.HasIndex(e => e.ProductionOrderId);
entity.HasIndex(e => e.ArticleId);
entity.Property(e => e.RequiredQuantity).HasPrecision(18, 4);
entity.Property(e => e.ConsumedQuantity).HasPrecision(18, 4);
entity.HasOne(e => e.ProductionOrder)
.WithMany(o => o.Components)
.HasForeignKey(e => e.ProductionOrderId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Article)
.WithMany()
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Restrict);
});
// WorkCenter
modelBuilder.Entity<WorkCenter>(entity =>
{
entity.ToTable("WorkCenters");
entity.HasIndex(e => e.Code).IsUnique();
entity.HasIndex(e => e.IsActive);
entity.Property(e => e.CostPerHour).HasPrecision(18, 4);
});
// ProductionCycle
modelBuilder.Entity<ProductionCycle>(entity =>
{
entity.ToTable("ProductionCycles");
entity.HasIndex(e => e.ArticleId);
entity.HasIndex(e => e.IsActive);
entity.HasOne(e => e.Article)
.WithMany()
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Restrict);
});
// ProductionCyclePhase
modelBuilder.Entity<ProductionCyclePhase>(entity =>
{
entity.ToTable("ProductionCyclePhases");
entity.HasIndex(e => e.ProductionCycleId);
entity.HasIndex(e => e.WorkCenterId);
entity.HasOne(e => e.ProductionCycle)
.WithMany(c => c.Phases)
.HasForeignKey(e => e.ProductionCycleId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.WorkCenter)
.WithMany()
.HasForeignKey(e => e.WorkCenterId)
.OnDelete(DeleteBehavior.Restrict);
});
// ProductionOrderPhase
modelBuilder.Entity<ProductionOrderPhase>(entity =>
{
entity.ToTable("ProductionOrderPhases");
entity.HasIndex(e => e.ProductionOrderId);
entity.HasIndex(e => e.WorkCenterId);
entity.HasIndex(e => e.Status);
entity.Property(e => e.QuantityCompleted).HasPrecision(18, 4);
entity.Property(e => e.QuantityScrapped).HasPrecision(18, 4);
entity.HasOne(e => e.ProductionOrder)
.WithMany(o => o.Phases)
.HasForeignKey(e => e.ProductionOrderId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.WorkCenter)
.WithMany()
.HasForeignKey(e => e.WorkCenterId)
.OnDelete(DeleteBehavior.Restrict);
});
// MrpSuggestion
modelBuilder.Entity<MrpSuggestion>(entity =>
{
entity.ToTable("MrpSuggestions");
entity.HasIndex(e => e.ArticleId);
entity.HasIndex(e => e.CalculationDate);
entity.HasIndex(e => e.IsProcessed);
entity.Property(e => e.Quantity).HasPrecision(18, 4);
entity.HasOne(e => e.Article)
.WithMany()
.HasForeignKey(e => e.ArticleId)
.OnDelete(DeleteBehavior.Cascade);
});
// ===============================================
// COMMUNICATIONS MODULE ENTITIES
// ===============================================
modelBuilder.Entity<EmailLog>(entity =>
{
entity.ToTable("EmailLogs");
entity.HasIndex(e => e.SentDate);
entity.HasIndex(e => e.Status);
entity.HasIndex(e => e.Recipient);
});
}
}