diff --git a/src/PowderCoating.Web/Controllers/DashboardController.cs b/src/PowderCoating.Web/Controllers/DashboardController.cs index 123b9f9..c594152 100644 --- a/src/PowderCoating.Web/Controllers/DashboardController.cs +++ b/src/PowderCoating.Web/Controllers/DashboardController.cs @@ -765,6 +765,12 @@ public class DashboardController : Controller UpdatedAt = DateTime.UtcNow, }; + // Enrich from the platform powder catalog so the new inventory record carries the full + // spec/doc set (cure schedule, SDS/TDS, sample image, color families) rather than just + // the color code/name carried on the quote. Match by the catalog SKU (stored as the + // coat's colorCode), preferring the same manufacturer; fall back to color name. + await EnrichInventoryFromCatalogAsync(inventoryItem, colorCode, colorName, manufacturer); + await _unitOfWork.InventoryItems.AddAsync(inventoryItem); await _unitOfWork.CompleteAsync(); // flush to get inventoryItem.Id @@ -828,6 +834,69 @@ public class DashboardController : Controller } } + /// + /// Fills blank spec/document fields on a newly received custom-powder inventory item from the + /// matching platform powder catalog row — cure schedule, coverage, specific gravity, transfer + /// efficiency, SDS/TDS links, sample image, color families, product page — so the tenant gets a + /// complete record instead of just the color code/name carried on the quote. Matches by catalog + /// SKU (stored as the coat's color code), preferring the same manufacturer, then by color name. + /// Only fills gaps (never overwrites form-entered values) and links the item to the catalog row. + /// + private async Task EnrichInventoryFromCatalogAsync( + InventoryItem item, string? colorCode, string? colorName, string? manufacturer) + { + PowderCatalogItem? catalog = null; + + var code = colorCode?.Trim(); + if (!string.IsNullOrWhiteSpace(code)) + { + var codeLower = code.ToLower(); + var hits = (await _unitOfWork.PowderCatalog.FindAsync(p => p.Sku.ToLower() == codeLower)).ToList(); + var mfr = manufacturer?.Trim().ToLower(); + catalog = (!string.IsNullOrWhiteSpace(mfr) + ? hits.FirstOrDefault(p => p.VendorName.ToLower().Contains(mfr)) + : null) + ?? hits.FirstOrDefault(); + } + + if (catalog == null && !string.IsNullOrWhiteSpace(colorName)) + { + var nameLower = colorName.Trim().ToLower(); + catalog = (await _unitOfWork.PowderCatalog.FindAsync(p => p.ColorName.ToLower() == nameLower)) + .FirstOrDefault(); + } + + if (catalog == null) + return; + + item.PowderCatalogItemId = catalog.Id; + + if (string.IsNullOrWhiteSpace(item.ManufacturerPartNumber)) item.ManufacturerPartNumber = catalog.Sku; + if (string.IsNullOrWhiteSpace(item.Manufacturer)) item.Manufacturer = catalog.VendorName; + if (string.IsNullOrWhiteSpace(item.ColorName)) item.ColorName = catalog.ColorName; + if (string.IsNullOrWhiteSpace(item.Finish)) item.Finish = catalog.Finish; + if (string.IsNullOrWhiteSpace(item.ColorFamilies)) item.ColorFamilies = catalog.ColorFamilies; + if (string.IsNullOrWhiteSpace(item.ImageUrl)) item.ImageUrl = catalog.ImageUrl; + if (string.IsNullOrWhiteSpace(item.SdsUrl)) item.SdsUrl = catalog.SdsUrl; + if (string.IsNullOrWhiteSpace(item.TdsUrl)) item.TdsUrl = catalog.TdsUrl; + if (string.IsNullOrWhiteSpace(item.SpecPageUrl)) item.SpecPageUrl = catalog.ProductUrl; + + item.CureTemperatureF ??= catalog.CureTemperatureF; + item.CureTimeMinutes ??= catalog.CureTimeMinutes; + item.SpecificGravity ??= catalog.SpecificGravity; + item.CoverageSqFtPerLb ??= catalog.CoverageSqFtPerLb ?? 30m; + item.TransferEfficiency ??= catalog.TransferEfficiency ?? 65m; + + if (!item.RequiresClearCoat && catalog.RequiresClearCoat == true) + item.RequiresClearCoat = true; + + if (item.UnitCost <= 0 && catalog.UnitPrice > 0) + { + item.UnitCost = catalog.UnitPrice; + item.LastPurchasePrice = catalog.UnitPrice; + } + } + /// /// Platform-level dashboard visible only to SuperAdmins who are not impersonating a tenant. /// Displays a cross-company overview: total/active/inactive company counts, user count,