@model PowderCoating.Application.DTOs.Powder.PowderInsightsDashboardDto @{ ViewData["Title"] = "Powder Insights"; ViewData["PageIcon"] = "bi-graph-up"; var readiness = Model.Readiness; }
@* ── KPI cards ── *@No active jobs require powder, or all stock levels are sufficient.
| Powder | On Hand | Pipeline Demand | Shortfall | Jobs | Status |
|---|---|---|---|---|---|
|
@item.Name
@if (!string.IsNullOrEmpty(item.ColorName))
{
@item.ColorName @(item.ColorCode != null ? $"({item.ColorCode})" : "") @item.Manufacturer } |
@item.CurrentStockLbs.ToString("0.##") lbs | @item.ScheduledDemandLbs.ToString("0.##") lbs | @Html.Raw(item.ShortfallLbs > 0 ? $"{item.ShortfallLbs:0.##} lbs" : "—") | @item.ActiveJobCount | @if (item.IsAtRisk) { Order Now } else if (item.IsBelowReorderPoint) { Below Reorder } else { OK } |
Coverage efficiency trends become meaningful after @readiness.Layer2MinJobs jobs with actual usage recorded.
You have @readiness.JobsWithActualData so far. Keep recording actuals on completed jobs!
No efficiency data yet — record actual powder usage on completed jobs to see this chart.
| Powder | Catalog Rate | Actual Avg Rate | Variance | Est. lbs | Actual lbs | Samples |
|---|---|---|---|---|---|---|
|
@eff.Name
@if (!string.IsNullOrEmpty(eff.ColorName))
{
@eff.ColorName · @eff.Manufacturer } @if (!eff.HasEnoughData) { Low confidence — need 5+ samples } |
@eff.CatalogCoverageSqFtPerLb.ToString("0.#") sq ft/lb | @eff.ActualAvgCoverageSqFtPerLb.ToString("0.#") sq ft/lb | @(eff.VariancePct > 0 ? "+" : "")@eff.VariancePct.ToString("0.#")% | @eff.TotalEstimatedLbs.ToString("0.#") | @eff.TotalActualLbs.ToString("0.#") | @eff.SampleCount |
Once @readiness.Layer3MinJobs jobs have actual powder usage recorded, this tab will show AI-powered reorder suggestions and waste pattern analysis.
@readiness.JobsWithActualData of @readiness.Layer3MinJobs jobs recorded (@readiness.Layer3ProgressPercent%)
| Powder | On Hand | 30-Day Pipeline | Avg Monthly Usage | Suggested Order | Confidence |
|---|---|---|---|---|---|
|
@s.Name
@if (!string.IsNullOrEmpty(s.ColorName))
{
@s.ColorName · @s.Manufacturer } |
@s.CurrentStockLbs.ToString("0.#") lbs | @s.PipelineDemand30DaysLbs.ToString("0.#") lbs | @s.HistoricalAvgMonthlyUsageLbs.ToString("0.#") lbs | @s.SuggestedOrderQtyLbs.ToString("0.#") lbs |
@s.SampleJobCount jobs
|
| Job | Item / Coat | Powder | Complexity | Estimated | Actual | Overage |
|---|---|---|---|---|---|---|
| @w.JobNumber |
@w.ItemDescription
@w.CoatName |
@(w.InventoryItemName ?? "Custom") | @Html.Raw(w.Complexity ?? "—") | @w.EstimatedLbs.ToString("0.##") lbs | @w.ActualLbs.ToString("0.##") lbs | +@w.OveragePct.ToString("0.#")% |