refactor: Update Material and StockItem entities

Material entity changes:
- Shape property now uses MaterialShape enum
- Add Type (MaterialType) and Grade properties
- Add SortOrder for numeric sorting
- Add Dimensions navigation property (1:1)
- Replace ProjectParts with JobParts collection

StockItem entity changes:
- Add QuantityOnHand for inventory tracking
- Add Notes field
- Add Transactions navigation property

DbContext updates:
- Configure MaterialDimensions TPH inheritance
- Add enum-to-string conversions for MaterialShape and MaterialType
- Configure shared column names for TPH properties
- Add indexes on primary dimension columns
- Update all entity relationships for Job model

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-04 23:37:51 -05:00
parent 4f6d986dc9
commit 3b036308c8
4 changed files with 670 additions and 130 deletions

View File

@@ -11,13 +11,15 @@ public class ApplicationDbContext : DbContext
}
public DbSet<Material> Materials => Set<Material>();
public DbSet<MaterialStockLength> MaterialStockLengths => Set<MaterialStockLength>();
public DbSet<MaterialDimensions> MaterialDimensions => Set<MaterialDimensions>();
public DbSet<Supplier> Suppliers => Set<Supplier>();
public DbSet<StockItem> StockItems => Set<StockItem>();
public DbSet<SupplierOffering> SupplierOfferings => Set<SupplierOffering>();
public DbSet<StockTransaction> StockTransactions => Set<StockTransaction>();
public DbSet<CuttingTool> CuttingTools => Set<CuttingTool>();
public DbSet<Project> Projects => Set<Project>();
public DbSet<ProjectPart> ProjectParts => Set<ProjectPart>();
public DbSet<Job> Jobs => Set<Job>();
public DbSet<JobPart> JobParts => Set<JobPart>();
public DbSet<JobStock> JobStocks => Set<JobStock>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@@ -27,25 +29,119 @@ public class ApplicationDbContext : DbContext
modelBuilder.Entity<Material>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Shape).HasMaxLength(50).IsRequired();
entity.Property(e => e.Shape)
.HasMaxLength(50)
.IsRequired()
.HasConversion(
v => v.ToString(), // Enum to string (uses enum name)
v => Enum.Parse<MaterialShape>(v)); // String to enum
entity.Property(e => e.Size).HasMaxLength(100).IsRequired();
entity.Property(e => e.Type)
.HasMaxLength(20)
.HasConversion(
v => v.ToString(),
v => Enum.Parse<MaterialType>(v));
entity.Property(e => e.Grade).HasMaxLength(50);
entity.Property(e => e.Description).HasMaxLength(255);
entity.Property(e => e.CreatedAt).HasDefaultValueSql("GETUTCDATE()");
});
// MaterialStockLength
modelBuilder.Entity<MaterialStockLength>(entity =>
// MaterialDimensions - TPH inheritance
modelBuilder.Entity<MaterialDimensions>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.LengthInches).HasPrecision(10, 4);
entity.Property(e => e.Notes).HasMaxLength(255);
// 1:1 relationship with Material
entity.HasOne(e => e.Material)
.WithMany(m => m.StockLengths)
.HasForeignKey(e => e.MaterialId)
.WithOne(m => m.Dimensions)
.HasForeignKey<MaterialDimensions>(e => e.MaterialId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasIndex(e => new { e.MaterialId, e.LengthInches }).IsUnique();
// TPH discriminator
entity.HasDiscriminator<string>("DimensionType")
.HasValue<RoundBarDimensions>("RoundBar")
.HasValue<RoundTubeDimensions>("RoundTube")
.HasValue<FlatBarDimensions>("FlatBar")
.HasValue<SquareBarDimensions>("SquareBar")
.HasValue<SquareTubeDimensions>("SquareTube")
.HasValue<RectangularTubeDimensions>("RectangularTube")
.HasValue<AngleDimensions>("Angle")
.HasValue<ChannelDimensions>("Channel")
.HasValue<IBeamDimensions>("IBeam")
.HasValue<PipeDimensions>("Pipe");
});
// Configure each dimension type's properties
modelBuilder.Entity<RoundBarDimensions>(entity =>
{
entity.Property(e => e.Diameter).HasPrecision(10, 4);
entity.HasIndex(e => e.Diameter);
});
modelBuilder.Entity<RoundTubeDimensions>(entity =>
{
entity.Property(e => e.OuterDiameter).HasPrecision(10, 4);
entity.Property(e => e.Wall).HasColumnName("Wall").HasPrecision(10, 4);
entity.HasIndex(e => e.OuterDiameter);
});
modelBuilder.Entity<FlatBarDimensions>(entity =>
{
entity.Property(e => e.Width).HasColumnName("Width").HasPrecision(10, 4);
entity.Property(e => e.Thickness).HasColumnName("Thickness").HasPrecision(10, 4);
entity.HasIndex(e => e.Width);
});
modelBuilder.Entity<SquareBarDimensions>(entity =>
{
entity.Property(e => e.Size).HasColumnName("Size").HasPrecision(10, 4);
entity.HasIndex(e => e.Size);
});
modelBuilder.Entity<SquareTubeDimensions>(entity =>
{
entity.Property(e => e.Size).HasColumnName("Size").HasPrecision(10, 4);
entity.Property(e => e.Wall).HasColumnName("Wall").HasPrecision(10, 4);
entity.HasIndex(e => e.Size);
});
modelBuilder.Entity<RectangularTubeDimensions>(entity =>
{
entity.Property(e => e.Width).HasColumnName("Width").HasPrecision(10, 4);
entity.Property(e => e.Height).HasColumnName("Height").HasPrecision(10, 4);
entity.Property(e => e.Wall).HasColumnName("Wall").HasPrecision(10, 4);
entity.HasIndex(e => e.Width);
});
modelBuilder.Entity<AngleDimensions>(entity =>
{
entity.Property(e => e.Leg1).HasPrecision(10, 4);
entity.Property(e => e.Leg2).HasPrecision(10, 4);
entity.Property(e => e.Thickness).HasColumnName("Thickness").HasPrecision(10, 4);
entity.HasIndex(e => e.Leg1);
});
modelBuilder.Entity<ChannelDimensions>(entity =>
{
entity.Property(e => e.Height).HasColumnName("Height").HasPrecision(10, 4);
entity.Property(e => e.Flange).HasPrecision(10, 4);
entity.Property(e => e.Web).HasPrecision(10, 4);
entity.HasIndex(e => e.Height);
});
modelBuilder.Entity<IBeamDimensions>(entity =>
{
entity.Property(e => e.Height).HasColumnName("Height").HasPrecision(10, 4);
entity.Property(e => e.WeightPerFoot).HasPrecision(10, 4);
entity.HasIndex(e => e.Height);
});
modelBuilder.Entity<PipeDimensions>(entity =>
{
entity.Property(e => e.NominalSize).HasPrecision(10, 4);
entity.Property(e => e.Wall).HasColumnName("Wall").HasPrecision(10, 4);
entity.Property(e => e.Schedule).HasMaxLength(20);
entity.HasIndex(e => e.NominalSize);
});
// Supplier
@@ -63,6 +159,7 @@ public class ApplicationDbContext : DbContext
entity.HasKey(e => e.Id);
entity.Property(e => e.LengthInches).HasPrecision(10, 4);
entity.Property(e => e.Name).HasMaxLength(100);
entity.Property(e => e.Notes).HasMaxLength(255);
entity.Property(e => e.CreatedAt).HasDefaultValueSql("GETUTCDATE()");
entity.HasOne(e => e.Material)
@@ -73,6 +170,30 @@ public class ApplicationDbContext : DbContext
entity.HasIndex(e => new { e.MaterialId, e.LengthInches }).IsUnique();
});
// StockTransaction
modelBuilder.Entity<StockTransaction>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Notes).HasMaxLength(500);
entity.Property(e => e.UnitPrice).HasPrecision(10, 2);
entity.Property(e => e.CreatedAt).HasDefaultValueSql("GETUTCDATE()");
entity.HasOne(e => e.StockItem)
.WithMany(s => s.Transactions)
.HasForeignKey(e => e.StockItemId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Job)
.WithMany()
.HasForeignKey(e => e.JobId)
.OnDelete(DeleteBehavior.SetNull);
entity.HasOne(e => e.Supplier)
.WithMany()
.HasForeignKey(e => e.SupplierId)
.OnDelete(DeleteBehavior.SetNull);
});
// SupplierOffering
modelBuilder.Entity<SupplierOffering>(entity =>
{
@@ -103,38 +224,63 @@ public class ApplicationDbContext : DbContext
entity.Property(e => e.KerfInches).HasPrecision(6, 4);
});
// Project
modelBuilder.Entity<Project>(entity =>
// Job
modelBuilder.Entity<Job>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Name).HasMaxLength(100).IsRequired();
entity.Property(e => e.JobNumber).HasMaxLength(20).IsRequired();
entity.Property(e => e.Name).HasMaxLength(100);
entity.Property(e => e.Customer).HasMaxLength(100);
entity.Property(e => e.CreatedAt).HasDefaultValueSql("GETUTCDATE()");
entity.HasIndex(e => e.JobNumber).IsUnique();
entity.HasOne(e => e.CuttingTool)
.WithMany(t => t.Projects)
.WithMany(t => t.Jobs)
.HasForeignKey(e => e.CuttingToolId)
.OnDelete(DeleteBehavior.SetNull);
});
// ProjectPart
modelBuilder.Entity<ProjectPart>(entity =>
// JobPart
modelBuilder.Entity<JobPart>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Name).HasMaxLength(100);
entity.Property(e => e.LengthInches).HasPrecision(10, 4);
entity.HasOne(e => e.Project)
entity.HasOne(e => e.Job)
.WithMany(p => p.Parts)
.HasForeignKey(e => e.ProjectId)
.HasForeignKey(e => e.JobId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Material)
.WithMany(m => m.ProjectParts)
.WithMany(m => m.JobParts)
.HasForeignKey(e => e.MaterialId)
.OnDelete(DeleteBehavior.Restrict);
});
// JobStock
modelBuilder.Entity<JobStock>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.LengthInches).HasPrecision(10, 4);
entity.HasOne(e => e.Job)
.WithMany(j => j.Stock)
.HasForeignKey(e => e.JobId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.Material)
.WithMany()
.HasForeignKey(e => e.MaterialId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(e => e.StockItem)
.WithMany()
.HasForeignKey(e => e.StockItemId)
.OnDelete(DeleteBehavior.SetNull);
});
// Seed default cutting tools
modelBuilder.Entity<CuttingTool>().HasData(
new CuttingTool { Id = 1, Name = "Bandsaw", KerfInches = 0.0625m, IsDefault = true, IsActive = true },

View File

@@ -3,16 +3,36 @@ namespace CutList.Web.Data.Entities;
public class Material
{
public int Id { get; set; }
public string Shape { get; set; } = string.Empty;
public MaterialShape Shape { get; set; }
/// <summary>
/// Material type (Steel, Aluminum, Stainless, etc.)
/// </summary>
public MaterialType Type { get; set; }
/// <summary>
/// Grade or specification (e.g., "A36", "Hot Roll", "304", "6061-T6")
/// </summary>
public string? Grade { get; set; }
public string Size { get; set; } = string.Empty;
public string? Description { get; set; }
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public ICollection<StockItem> StockItems { get; set; } = new List<StockItem>();
public ICollection<MaterialStockLength> StockLengths { get; set; } = new List<MaterialStockLength>();
public ICollection<ProjectPart> ProjectParts { get; set; } = new List<ProjectPart>();
/// <summary>
/// Sort order based on primary dimension (stored as thousandths of an inch for numeric sorting).
/// </summary>
public int SortOrder { get; set; }
public string DisplayName => $"{Shape} - {Size}";
public ICollection<StockItem> StockItems { get; set; } = new List<StockItem>();
public ICollection<JobPart> JobParts { get; set; } = new List<JobPart>();
/// <summary>
/// Optional parsed dimensions for decimal-based searching.
/// </summary>
public MaterialDimensions? Dimensions { get; set; }
public string DisplayName => $"{Shape.GetDisplayName()} - {Size}";
}

View File

@@ -6,10 +6,13 @@ public class StockItem
public int MaterialId { get; set; }
public decimal LengthInches { get; set; }
public string? Name { get; set; }
public int QuantityOnHand { get; set; } = 0;
public string? Notes { get; set; }
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public Material Material { get; set; } = null!;
public ICollection<SupplierOffering> SupplierOfferings { get; set; } = new List<SupplierOffering>();
public ICollection<StockTransaction> Transactions { get; set; } = new List<StockTransaction>();
}

View File

@@ -84,78 +84,7 @@ namespace CutList.Web.Migrations
});
});
modelBuilder.Entity("CutList.Web.Data.Entities.Material", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<string>("Description")
.HasMaxLength(255)
.HasColumnType("nvarchar(255)");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<string>("Shape")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("Size")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("datetime2");
b.HasKey("Id");
b.ToTable("Materials");
});
modelBuilder.Entity("CutList.Web.Data.Entities.MaterialStockLength", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<decimal>("LengthInches")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.Property<int>("MaterialId")
.HasColumnType("int");
b.Property<string>("Notes")
.HasMaxLength(255)
.HasColumnType("nvarchar(255)");
b.Property<int>("Quantity")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("MaterialId", "LengthInches")
.IsUnique();
b.ToTable("MaterialStockLengths");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Project", b =>
modelBuilder.Entity("CutList.Web.Data.Entities.Job", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
@@ -175,8 +104,12 @@ namespace CutList.Web.Migrations
b.Property<int?>("CuttingToolId")
.HasColumnType("int");
b.Property<string>("Name")
b.Property<string>("JobNumber")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b.Property<string>("Name")
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
@@ -190,10 +123,13 @@ namespace CutList.Web.Migrations
b.HasIndex("CuttingToolId");
b.ToTable("Projects");
b.HasIndex("JobNumber")
.IsUnique();
b.ToTable("Jobs");
});
modelBuilder.Entity("CutList.Web.Data.Entities.ProjectPart", b =>
modelBuilder.Entity("CutList.Web.Data.Entities.JobPart", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
@@ -201,6 +137,9 @@ namespace CutList.Web.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("JobId")
.HasColumnType("int");
b.Property<decimal>("LengthInches")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
@@ -213,9 +152,6 @@ namespace CutList.Web.Migrations
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("ProjectId")
.HasColumnType("int");
b.Property<int>("Quantity")
.HasColumnType("int");
@@ -224,11 +160,133 @@ namespace CutList.Web.Migrations
b.HasKey("Id");
b.HasIndex("JobId");
b.HasIndex("MaterialId");
b.HasIndex("ProjectId");
b.ToTable("JobParts");
});
b.ToTable("ProjectParts");
modelBuilder.Entity("CutList.Web.Data.Entities.JobStock", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<bool>("IsCustomLength")
.HasColumnType("bit");
b.Property<int>("JobId")
.HasColumnType("int");
b.Property<decimal>("LengthInches")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.Property<int>("MaterialId")
.HasColumnType("int");
b.Property<int>("Priority")
.HasColumnType("int");
b.Property<int>("Quantity")
.HasColumnType("int");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<int?>("StockItemId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("JobId");
b.HasIndex("MaterialId");
b.HasIndex("StockItemId");
b.ToTable("JobStocks");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Material", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<string>("Description")
.HasMaxLength(255)
.HasColumnType("nvarchar(255)");
b.Property<string>("Grade")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<string>("Shape")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("Size")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("datetime2");
b.HasKey("Id");
b.ToTable("Materials");
});
modelBuilder.Entity("CutList.Web.Data.Entities.MaterialDimensions", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("DimensionType")
.IsRequired()
.HasMaxLength(21)
.HasColumnType("nvarchar(21)");
b.Property<int>("MaterialId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("MaterialId")
.IsUnique();
b.ToTable("MaterialDimensions");
b.HasDiscriminator<string>("DimensionType").HasValue("MaterialDimensions");
b.UseTphMappingStrategy();
});
modelBuilder.Entity("CutList.Web.Data.Entities.StockItem", b =>
@@ -258,6 +316,13 @@ namespace CutList.Web.Migrations
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("Notes")
.HasMaxLength(255)
.HasColumnType("nvarchar(255)");
b.Property<int>("QuantityOnHand")
.HasColumnType("int");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("datetime2");
@@ -269,6 +334,53 @@ namespace CutList.Web.Migrations
b.ToTable("StockItems");
});
modelBuilder.Entity("CutList.Web.Data.Entities.StockTransaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<int?>("JobId")
.HasColumnType("int");
b.Property<string>("Notes")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<int>("Quantity")
.HasColumnType("int");
b.Property<int>("StockItemId")
.HasColumnType("int");
b.Property<int?>("SupplierId")
.HasColumnType("int");
b.Property<int>("Type")
.HasColumnType("int");
b.Property<decimal?>("UnitPrice")
.HasPrecision(10, 2)
.HasColumnType("decimal(10,2)");
b.HasKey("Id");
b.HasIndex("JobId");
b.HasIndex("StockItemId");
b.HasIndex("SupplierId");
b.ToTable("StockTransactions");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Supplier", b =>
{
b.Property<int>("Id")
@@ -345,44 +457,274 @@ namespace CutList.Web.Migrations
b.ToTable("SupplierOfferings");
});
modelBuilder.Entity("CutList.Web.Data.Entities.MaterialStockLength", b =>
modelBuilder.Entity("CutList.Web.Data.Entities.AngleDimensions", b =>
{
b.HasOne("CutList.Web.Data.Entities.Material", "Material")
.WithMany("StockLengths")
.HasForeignKey("MaterialId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Navigation("Material");
b.Property<decimal>("Leg1")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.Property<decimal>("Leg2")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.Property<decimal>("Thickness")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Thickness");
b.HasIndex("Leg1");
b.HasDiscriminator().HasValue("Angle");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Project", b =>
modelBuilder.Entity("CutList.Web.Data.Entities.ChannelDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("Flange")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.Property<decimal>("Height")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Height");
b.Property<decimal>("Web")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.HasIndex("Height");
b.HasDiscriminator().HasValue("Channel");
});
modelBuilder.Entity("CutList.Web.Data.Entities.FlatBarDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("Thickness")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Thickness");
b.Property<decimal>("Width")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Width");
b.HasIndex("Width");
b.HasDiscriminator().HasValue("FlatBar");
});
modelBuilder.Entity("CutList.Web.Data.Entities.IBeamDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("Height")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Height");
b.Property<decimal>("WeightPerFoot")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.HasIndex("Height");
b.HasDiscriminator().HasValue("IBeam");
});
modelBuilder.Entity("CutList.Web.Data.Entities.PipeDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("NominalSize")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.Property<string>("Schedule")
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b.Property<decimal?>("Wall")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Wall");
b.HasIndex("NominalSize");
b.HasDiscriminator().HasValue("Pipe");
});
modelBuilder.Entity("CutList.Web.Data.Entities.RectangularTubeDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("Height")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Height");
b.Property<decimal>("Wall")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Wall");
b.Property<decimal>("Width")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Width");
b.HasIndex("Width");
b.HasDiscriminator().HasValue("RectangularTube");
});
modelBuilder.Entity("CutList.Web.Data.Entities.RoundBarDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("Diameter")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.HasIndex("Diameter");
b.HasDiscriminator().HasValue("RoundBar");
});
modelBuilder.Entity("CutList.Web.Data.Entities.RoundTubeDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("OuterDiameter")
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)");
b.Property<decimal>("Wall")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Wall");
b.HasIndex("OuterDiameter");
b.HasDiscriminator().HasValue("RoundTube");
});
modelBuilder.Entity("CutList.Web.Data.Entities.SquareBarDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("Size")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Size");
b.HasIndex("Size");
b.HasDiscriminator().HasValue("SquareBar");
});
modelBuilder.Entity("CutList.Web.Data.Entities.SquareTubeDimensions", b =>
{
b.HasBaseType("CutList.Web.Data.Entities.MaterialDimensions");
b.Property<decimal>("Size")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Size");
b.Property<decimal>("Wall")
.ValueGeneratedOnUpdateSometimes()
.HasPrecision(10, 4)
.HasColumnType("decimal(10,4)")
.HasColumnName("Wall");
b.HasIndex("Size");
b.HasDiscriminator().HasValue("SquareTube");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Job", b =>
{
b.HasOne("CutList.Web.Data.Entities.CuttingTool", "CuttingTool")
.WithMany("Projects")
.WithMany("Jobs")
.HasForeignKey("CuttingToolId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("CuttingTool");
});
modelBuilder.Entity("CutList.Web.Data.Entities.ProjectPart", b =>
modelBuilder.Entity("CutList.Web.Data.Entities.JobPart", b =>
{
b.HasOne("CutList.Web.Data.Entities.Job", "Job")
.WithMany("Parts")
.HasForeignKey("JobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("CutList.Web.Data.Entities.Material", "Material")
.WithMany("ProjectParts")
.WithMany("JobParts")
.HasForeignKey("MaterialId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("CutList.Web.Data.Entities.Project", "Project")
.WithMany("Parts")
.HasForeignKey("ProjectId")
b.Navigation("Job");
b.Navigation("Material");
});
modelBuilder.Entity("CutList.Web.Data.Entities.JobStock", b =>
{
b.HasOne("CutList.Web.Data.Entities.Job", "Job")
.WithMany("Stock")
.HasForeignKey("JobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("CutList.Web.Data.Entities.Material", "Material")
.WithMany()
.HasForeignKey("MaterialId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("CutList.Web.Data.Entities.StockItem", "StockItem")
.WithMany()
.HasForeignKey("StockItemId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("Job");
b.Navigation("Material");
b.Navigation("StockItem");
});
modelBuilder.Entity("CutList.Web.Data.Entities.MaterialDimensions", b =>
{
b.HasOne("CutList.Web.Data.Entities.Material", "Material")
.WithOne("Dimensions")
.HasForeignKey("CutList.Web.Data.Entities.MaterialDimensions", "MaterialId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Material");
b.Navigation("Project");
});
modelBuilder.Entity("CutList.Web.Data.Entities.StockItem", b =>
@@ -396,6 +738,31 @@ namespace CutList.Web.Migrations
b.Navigation("Material");
});
modelBuilder.Entity("CutList.Web.Data.Entities.StockTransaction", b =>
{
b.HasOne("CutList.Web.Data.Entities.Job", "Job")
.WithMany()
.HasForeignKey("JobId")
.OnDelete(DeleteBehavior.SetNull);
b.HasOne("CutList.Web.Data.Entities.StockItem", "StockItem")
.WithMany("Transactions")
.HasForeignKey("StockItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("CutList.Web.Data.Entities.Supplier", "Supplier")
.WithMany()
.HasForeignKey("SupplierId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("Job");
b.Navigation("StockItem");
b.Navigation("Supplier");
});
modelBuilder.Entity("CutList.Web.Data.Entities.SupplierOffering", b =>
{
b.HasOne("CutList.Web.Data.Entities.StockItem", "StockItem")
@@ -417,26 +784,30 @@ namespace CutList.Web.Migrations
modelBuilder.Entity("CutList.Web.Data.Entities.CuttingTool", b =>
{
b.Navigation("Projects");
b.Navigation("Jobs");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Job", b =>
{
b.Navigation("Parts");
b.Navigation("Stock");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Material", b =>
{
b.Navigation("ProjectParts");
b.Navigation("Dimensions");
b.Navigation("JobParts");
b.Navigation("StockItems");
b.Navigation("StockLengths");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Project", b =>
{
b.Navigation("Parts");
});
modelBuilder.Entity("CutList.Web.Data.Entities.StockItem", b =>
{
b.Navigation("SupplierOfferings");
b.Navigation("Transactions");
});
modelBuilder.Entity("CutList.Web.Data.Entities.Supplier", b =>