From 41944638c6b273786172d71c5ce39bef28595473 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sat, 1 Aug 2026 08:45:21 -0400 Subject: [PATCH] feat: drop supplier import/export from the catalog format Co-Authored-By: Claude Sonnet 5 --- CutList.Web/DTOs/CatalogDtos.cs | 22 ---- CutList.Web/Services/CatalogService.cs | 164 +++---------------------- 2 files changed, 20 insertions(+), 166 deletions(-) diff --git a/CutList.Web/DTOs/CatalogDtos.cs b/CutList.Web/DTOs/CatalogDtos.cs index c2188dc..a04530e 100644 --- a/CutList.Web/DTOs/CatalogDtos.cs +++ b/CutList.Web/DTOs/CatalogDtos.cs @@ -3,18 +3,10 @@ namespace CutList.Web.DTOs; public class CatalogData { public DateTime ExportedAt { get; set; } - public List Suppliers { get; set; } = []; public List CuttingTools { get; set; } = []; public CatalogMaterialsDto Materials { get; set; } = new(); } -public class CatalogSupplierDto -{ - public string Name { get; set; } = ""; - public string? ContactInfo { get; set; } - public string? Notes { get; set; } -} - public class CatalogCuttingToolDto { public string Name { get; set; } = ""; @@ -113,30 +105,16 @@ public class CatalogStockItemDto public string? Name { get; set; } public int QuantityOnHand { get; set; } public string? Notes { get; set; } - public List SupplierOfferings { get; set; } = []; -} - -public class CatalogSupplierOfferingDto -{ - public string SupplierName { get; set; } = ""; - public string? PartNumber { get; set; } - public string? SupplierDescription { get; set; } - public decimal? Price { get; set; } - public string? Notes { get; set; } } public class ImportResultDto { - public int SuppliersCreated { get; set; } - public int SuppliersUpdated { get; set; } public int CuttingToolsCreated { get; set; } public int CuttingToolsUpdated { get; set; } public int MaterialsCreated { get; set; } public int MaterialsUpdated { get; set; } public int StockItemsCreated { get; set; } public int StockItemsUpdated { get; set; } - public int OfferingsCreated { get; set; } - public int OfferingsUpdated { get; set; } public List Errors { get; set; } = []; public List Warnings { get; set; } = []; } diff --git a/CutList.Web/Services/CatalogService.cs b/CutList.Web/Services/CatalogService.cs index 3a3f49b..00d8593 100644 --- a/CutList.Web/Services/CatalogService.cs +++ b/CutList.Web/Services/CatalogService.cs @@ -20,12 +20,6 @@ public class CatalogService { await using var context = _factory.CreateDbContext(); - var suppliers = await context.Suppliers - .Where(s => s.IsActive) - .OrderBy(s => s.Name) - .AsNoTracking() - .ToListAsync(); - var cuttingTools = await context.CuttingTools .Where(t => t.IsActive) .OrderBy(t => t.Name) @@ -35,7 +29,6 @@ public class CatalogService var materials = await context.Materials .Include(m => m.Dimensions) .Include(m => m.StockItems.Where(s => s.IsActive)) - .ThenInclude(s => s.SupplierOfferings.Where(o => o.IsActive)) .Where(m => m.IsActive) .OrderBy(m => m.Shape).ThenBy(m => m.SortOrder) .AsNoTracking() @@ -48,7 +41,7 @@ public class CatalogService { foreach (var m in group) { - var stockItems = MapStockItems(m, suppliers); + var stockItems = MapStockItems(m); switch (m.Shape) { @@ -139,12 +132,6 @@ public class CatalogService return new CatalogData { ExportedAt = DateTime.UtcNow, - Suppliers = suppliers.Select(s => new CatalogSupplierDto - { - Name = s.Name, - ContactInfo = s.ContactInfo, - Notes = s.Notes - }).ToList(), CuttingTools = cuttingTools.Select(t => new CatalogCuttingToolDto { Name = t.Name, @@ -164,14 +151,11 @@ public class CatalogService try { - // 1. Suppliers - upsert by name - var supplierMap = await ImportSuppliersAsync(context, data.Suppliers, result); - - // 2. Cutting tools - upsert by name + // 1. Cutting tools - upsert by name await ImportCuttingToolsAsync(context, data.CuttingTools, result); - // 3. Materials + stock items + offerings - await ImportAllMaterialsAsync(context, data.Materials, supplierMap, result); + // 2. Materials + stock items + await ImportAllMaterialsAsync(context, data.Materials, result); await transaction.CommitAsync(); } @@ -184,54 +168,6 @@ public class CatalogService return result; } - private async Task> ImportSuppliersAsync( - ApplicationDbContext context, List suppliers, ImportResultDto result) - { - var map = new Dictionary(StringComparer.OrdinalIgnoreCase); - - var existingSuppliers = await context.Suppliers.ToListAsync(); - - foreach (var dto in suppliers) - { - try - { - var existing = existingSuppliers.FirstOrDefault( - s => s.Name.Equals(dto.Name, StringComparison.OrdinalIgnoreCase)); - - if (existing != null) - { - existing.ContactInfo = dto.ContactInfo ?? existing.ContactInfo; - existing.Notes = dto.Notes ?? existing.Notes; - existing.IsActive = true; - map[dto.Name] = existing.Id; - result.SuppliersUpdated++; - } - else - { - var supplier = new Supplier - { - Name = dto.Name, - ContactInfo = dto.ContactInfo, - Notes = dto.Notes, - CreatedAt = DateTime.UtcNow - }; - context.Suppliers.Add(supplier); - await context.SaveChangesAsync(); - existingSuppliers.Add(supplier); - map[dto.Name] = supplier.Id; - result.SuppliersCreated++; - } - } - catch (Exception ex) - { - result.Errors.Add($"Supplier '{dto.Name}': {ex.Message}"); - } - } - - await context.SaveChangesAsync(); - return map; - } - private async Task ImportCuttingToolsAsync( ApplicationDbContext context, List tools, ImportResultDto result) { @@ -273,68 +209,67 @@ public class CatalogService } private async Task ImportAllMaterialsAsync( - ApplicationDbContext context, CatalogMaterialsDto materials, Dictionary supplierMap, ImportResultDto result) + ApplicationDbContext context, CatalogMaterialsDto materials, ImportResultDto result) { var existingMaterials = await context.Materials .Include(m => m.Dimensions) .Include(m => m.StockItems) - .ThenInclude(s => s.SupplierOfferings) .ToListAsync(); foreach (var dto in materials.Angles) - await ImportMaterialAsync(context, dto, MaterialShape.Angle, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.Angle, existingMaterials, result, () => new AngleDimensions { Leg1 = dto.Leg1, Leg2 = dto.Leg2, Thickness = dto.Thickness }, dim => { var d = (AngleDimensions)dim; d.Leg1 = dto.Leg1; d.Leg2 = dto.Leg2; d.Thickness = dto.Thickness; }); foreach (var dto in materials.Channels) - await ImportMaterialAsync(context, dto, MaterialShape.Channel, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.Channel, existingMaterials, result, () => new ChannelDimensions { Height = dto.Height, Flange = dto.Flange, Web = dto.Web }, dim => { var d = (ChannelDimensions)dim; d.Height = dto.Height; d.Flange = dto.Flange; d.Web = dto.Web; }); foreach (var dto in materials.FlatBars) - await ImportMaterialAsync(context, dto, MaterialShape.FlatBar, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.FlatBar, existingMaterials, result, () => new FlatBarDimensions { Width = dto.Width, Thickness = dto.Thickness }, dim => { var d = (FlatBarDimensions)dim; d.Width = dto.Width; d.Thickness = dto.Thickness; }); foreach (var dto in materials.IBeams) - await ImportMaterialAsync(context, dto, MaterialShape.IBeam, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.IBeam, existingMaterials, result, () => new IBeamDimensions { Height = dto.Height, WeightPerFoot = dto.WeightPerFoot }, dim => { var d = (IBeamDimensions)dim; d.Height = dto.Height; d.WeightPerFoot = dto.WeightPerFoot; }); foreach (var dto in materials.Pipes) - await ImportMaterialAsync(context, dto, MaterialShape.Pipe, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.Pipe, existingMaterials, result, () => new PipeDimensions { NominalSize = dto.NominalSize, Wall = dto.Wall, Schedule = dto.Schedule }, dim => { var d = (PipeDimensions)dim; d.NominalSize = dto.NominalSize; d.Wall = (decimal?)dto.Wall; d.Schedule = dto.Schedule; }); foreach (var dto in materials.RectangularTubes) - await ImportMaterialAsync(context, dto, MaterialShape.RectangularTube, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.RectangularTube, existingMaterials, result, () => new RectangularTubeDimensions { Width = dto.Width, Height = dto.Height, Wall = dto.Wall }, dim => { var d = (RectangularTubeDimensions)dim; d.Width = dto.Width; d.Height = dto.Height; d.Wall = dto.Wall; }); foreach (var dto in materials.RoundBars) - await ImportMaterialAsync(context, dto, MaterialShape.RoundBar, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.RoundBar, existingMaterials, result, () => new RoundBarDimensions { Diameter = dto.Diameter }, dim => { var d = (RoundBarDimensions)dim; d.Diameter = dto.Diameter; }); foreach (var dto in materials.RoundTubes) - await ImportMaterialAsync(context, dto, MaterialShape.RoundTube, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.RoundTube, existingMaterials, result, () => new RoundTubeDimensions { OuterDiameter = dto.OuterDiameter, Wall = dto.Wall }, dim => { var d = (RoundTubeDimensions)dim; d.OuterDiameter = dto.OuterDiameter; d.Wall = dto.Wall; }); foreach (var dto in materials.SquareBars) - await ImportMaterialAsync(context, dto, MaterialShape.SquareBar, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.SquareBar, existingMaterials, result, () => new SquareBarDimensions { Size = dto.SideLength }, dim => { var d = (SquareBarDimensions)dim; d.Size = dto.SideLength; }); foreach (var dto in materials.SquareTubes) - await ImportMaterialAsync(context, dto, MaterialShape.SquareTube, existingMaterials, supplierMap, result, + await ImportMaterialAsync(context, dto, MaterialShape.SquareTube, existingMaterials, result, () => new SquareTubeDimensions { Size = dto.SideLength, Wall = dto.Wall }, dim => { var d = (SquareTubeDimensions)dim; d.Size = dto.SideLength; d.Wall = dto.Wall; }); } private async Task ImportMaterialAsync( ApplicationDbContext context, CatalogMaterialBaseDto dto, MaterialShape shape, - List existingMaterials, Dictionary supplierMap, + List existingMaterials, ImportResultDto result, Func createDimensions, Action updateDimensions) @@ -389,7 +324,7 @@ public class CatalogService await context.SaveChangesAsync(); - await ImportStockItemsAsync(context, material, dto.StockItems, supplierMap, result); + await ImportStockItemsAsync(context, material, dto.StockItems, result); } catch (Exception ex) { @@ -399,10 +334,9 @@ public class CatalogService private async Task ImportStockItemsAsync( ApplicationDbContext context, Material material, List stockItems, - Dictionary supplierMap, ImportResultDto result) + ImportResultDto result) { var existingStockItems = await context.StockItems - .Include(s => s.SupplierOfferings) .Where(s => s.MaterialId == material.Id) .ToListAsync(); @@ -440,56 +374,6 @@ public class CatalogService existingStockItems.Add(stockItem); result.StockItemsCreated++; } - - foreach (var offeringDto in dto.SupplierOfferings) - { - try - { - if (!supplierMap.TryGetValue(offeringDto.SupplierName, out var supplierId)) - { - result.Warnings.Add( - $"Offering for stock '{material.DisplayName} @ {dto.LengthInches}\"': " + - $"Unknown supplier '{offeringDto.SupplierName}', skipped"); - continue; - } - - var existingOffering = stockItem.SupplierOfferings.FirstOrDefault( - o => o.SupplierId == supplierId); - - if (existingOffering != null) - { - existingOffering.PartNumber = offeringDto.PartNumber ?? existingOffering.PartNumber; - existingOffering.SupplierDescription = offeringDto.SupplierDescription ?? existingOffering.SupplierDescription; - existingOffering.Price = offeringDto.Price ?? existingOffering.Price; - existingOffering.Notes = offeringDto.Notes ?? existingOffering.Notes; - existingOffering.IsActive = true; - result.OfferingsUpdated++; - } - else - { - var offering = new SupplierOffering - { - StockItemId = stockItem.Id, - SupplierId = supplierId, - PartNumber = offeringDto.PartNumber, - SupplierDescription = offeringDto.SupplierDescription, - Price = offeringDto.Price, - Notes = offeringDto.Notes - }; - context.SupplierOfferings.Add(offering); - stockItem.SupplierOfferings.Add(offering); - result.OfferingsCreated++; - } - } - catch (Exception ex) - { - result.Errors.Add( - $"Offering for '{material.DisplayName} @ {dto.LengthInches}\"' " + - $"from '{offeringDto.SupplierName}': {ex.Message}"); - } - } - - await context.SaveChangesAsync(); } catch (Exception ex) { @@ -499,22 +383,14 @@ public class CatalogService } } - private static List MapStockItems(Material m, List suppliers) + private static List MapStockItems(Material m) { return m.StockItems.OrderBy(s => s.LengthInches).Select(s => new CatalogStockItemDto { LengthInches = s.LengthInches, Name = s.Name, QuantityOnHand = s.QuantityOnHand, - Notes = s.Notes, - SupplierOfferings = s.SupplierOfferings.Select(o => new CatalogSupplierOfferingDto - { - SupplierName = suppliers.FirstOrDefault(sup => sup.Id == o.SupplierId)?.Name ?? "Unknown", - PartNumber = o.PartNumber, - SupplierDescription = o.SupplierDescription, - Price = o.Price, - Notes = o.Notes - }).ToList() + Notes = s.Notes }).ToList(); } }