Lazily enrich catalog specs from TDS on first use
Specific gravity, coverage, and ~55% of cure specs aren't in the Columbia feed. Rather than read 2,400 TDS PDFs up front, enrich a catalog item the first time it's actually used: - FetchTdsCureSpecsAsync now also extracts specific gravity from the TDS. - New EnsureCatalogTdsSpecsAsync fills a catalog item's specific gravity (and any missing cure temp/time) from its TDS, then derives theoretical coverage (192.3 / (SG x mils)). No-op once specific gravity is known or when there's no TDS; persists to the catalog so the work is done once and benefits everyone. - Hooked into the catalog->inventory paths (CreateIncomingFromCatalog, the custom-powder receive enrichment, and ReceivePowderFromCatalog) so a powder's full specs land on both the catalog and the new inventory record. DashboardController gains the AI lookup service for this. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,7 @@ public class DashboardController : Controller
|
||||
private readonly ICompanyConfigHealthService _configHealth;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly ISubscriptionService _subscriptionService;
|
||||
private readonly IInventoryAiLookupService _aiLookupService;
|
||||
|
||||
public DashboardController(
|
||||
IUnitOfWork unitOfWork,
|
||||
@@ -33,7 +34,8 @@ public class DashboardController : Controller
|
||||
ITenantContext tenantContext,
|
||||
ICompanyConfigHealthService configHealth,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ISubscriptionService subscriptionService)
|
||||
ISubscriptionService subscriptionService,
|
||||
IInventoryAiLookupService aiLookupService)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_logger = logger;
|
||||
@@ -42,6 +44,7 @@ public class DashboardController : Controller
|
||||
_configHealth = configHealth;
|
||||
_userManager = userManager;
|
||||
_subscriptionService = subscriptionService;
|
||||
_aiLookupService = aiLookupService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -868,8 +871,12 @@ public class DashboardController : Controller
|
||||
InventoryItem item, string? colorCode, string? colorName, string? manufacturer)
|
||||
{
|
||||
var catalog = await FindCatalogByIdentityAsync(colorCode, colorName, manufacturer);
|
||||
if (catalog != null)
|
||||
ApplyCatalogToInventory(item, catalog);
|
||||
if (catalog == null)
|
||||
return;
|
||||
|
||||
// First use — lazily fill specific gravity / cure from the TDS before copying onto the item.
|
||||
await _aiLookupService.EnsureCatalogTdsSpecsAsync(catalog);
|
||||
ApplyCatalogToInventory(item, catalog);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -987,6 +994,9 @@ public class DashboardController : Controller
|
||||
if (catalog == null)
|
||||
return Json(new { success = false, needsDetails = true });
|
||||
|
||||
// First use — lazily fill specific gravity / cure from the TDS so the new record is complete.
|
||||
await _aiLookupService.EnsureCatalogTdsSpecsAsync(catalog);
|
||||
|
||||
// Resolve the company's POWDER (coating) inventory category.
|
||||
var categories = await _unitOfWork.InventoryCategoryLookups.FindAsync(c => c.CompanyId == companyId);
|
||||
var coatingCategory = categories.FirstOrDefault(c => c.IsActive && c.IsCoating
|
||||
|
||||
@@ -1263,6 +1263,10 @@ public class InventoryController : Controller
|
||||
if (catalogItem == null)
|
||||
return Json(new { success = false, error = "Catalog item not found." });
|
||||
|
||||
// First use of this powder — lazily fill specific gravity / cure from its TDS so the new
|
||||
// inventory record (and the catalog) carry complete specs. No-op once already enriched.
|
||||
await _aiLookupService.EnsureCatalogTdsSpecsAsync(catalogItem);
|
||||
|
||||
var companyId = _tenantContext.GetCurrentCompanyId() ?? 0;
|
||||
|
||||
// Find the default coating category to assign.
|
||||
|
||||
Reference in New Issue
Block a user