Initial commit

This commit is contained in:
2026-04-23 21:38:24 -04:00
commit 63e12a9636
1762 changed files with 1672620 additions and 0 deletions
@@ -0,0 +1,262 @@
@model (int ItemIndex, List<PowderCoating.Application.DTOs.Quote.CreateQuoteItemCoatDto> Coats)
@{
var itemIndex = Model.ItemIndex;
var coats = Model.Coats ?? new List<PowderCoating.Application.DTOs.Quote.CreateQuoteItemCoatDto>();
// Debug: Log coat count
var coatCountForDebug = coats.Count;
// If no coats exist, initialize with one default Single Stage coat
if (!coats.Any())
{
coats.Add(new PowderCoating.Application.DTOs.Quote.CreateQuoteItemCoatDto
{
CoatName = "Single Stage",
Sequence = 1,
CoverageSqFtPerLb = 30,
TransferEfficiency = 65
});
}
}
<!-- DEBUG: Item @itemIndex has @coats.Count coat(s) (original count: @coatCountForDebug) -->
<div class="row g-3 mb-3">
<div class="col-12">
<label class="form-label fw-semibold d-block mb-2">
<i class="bi bi-paint-bucket me-1"></i>Coating Layers
</label>
<div class="accordion" id="coatsAccordion_@itemIndex">
@for (int coatIndex = 0; coatIndex < coats.Count; coatIndex++)
{
var coat = coats[coatIndex];
var isExpanded = coatIndex == 0; // First coat expanded by default
<div class="accordion-item coat-accordion-item" data-coat-index="@coatIndex">
<h2 class="accordion-header" id="coatHeading_@(itemIndex)_@(coatIndex)">
<div class="d-flex align-items-center">
<button class="accordion-button @(isExpanded ? "" : "collapsed") flex-grow-1" type="button"
data-bs-toggle="collapse" data-bs-target="#coat_@(itemIndex)_@(coatIndex)"
aria-expanded="@(isExpanded ? "true" : "false")" aria-controls="coat_@(itemIndex)_@(coatIndex)">
<span class="coat-header-text">@(coat.CoatName ?? $"Coating Layer {coatIndex + 1}")</span>
</button>
@if (coats.Count > 1)
{
<button type="button" class="btn btn-sm btn-outline-danger ms-2 me-2"
onclick="removeCoat(@itemIndex, @coatIndex); event.stopPropagation();"
title="Remove this coating layer">
<i class="bi bi-trash"></i>
</button>
}
</div>
</h2>
<div id="coat_@(itemIndex)_@(coatIndex)" class="accordion-collapse collapse @(isExpanded ? "show" : "")"
aria-labelledby="coatHeading_@(itemIndex)_@(coatIndex)"
data-bs-parent="#coatsAccordion_@itemIndex">
<div class="accordion-body">
<input type="hidden" name="QuoteItems[@itemIndex].Coats[@coatIndex].Sequence" value="@coat.Sequence" />
<div class="row g-3 mb-3">
<div class="col-md-12">
<label class="form-label fw-semibold">Coat Type <span class="text-danger">*</span></label>
<select name="QuoteItems[@itemIndex].Coats[@coatIndex].CoatName"
class="form-select coat-name-input"
onchange="updateCoatHeader(@itemIndex, @coatIndex)"
required>
<option value="Primer" selected="@(coat.CoatName == "Primer")">Primer</option>
<option value="Single Stage" selected="@(coat.CoatName == "Single Stage")">Single Stage</option>
<option value="Base Coat" selected="@(coat.CoatName == "Base Coat")">Base Coat</option>
<option value="Top Coat" selected="@(coat.CoatName == "Top Coat")">Top Coat</option>
<option value="Additional Stage" selected="@(coat.CoatName == "Additional Stage")">Additional Stage</option>
</select>
</div>
</div>
<!-- Radio: Stock vs Custom -->
@{
var hasInventoryItem = coat.InventoryItemId.HasValue && coat.InventoryItemId.Value > 0;
var isCustom = !string.IsNullOrEmpty(coat.ColorName) || coat.PowderCostPerLb.HasValue;
var coatType = hasInventoryItem ? "stock" : (isCustom ? "custom" : "stock");
}
<div class="btn-group mb-3 w-100" role="group">
<input type="radio" class="btn-check"
name="coatPowderType_@(itemIndex)_@(coatIndex)"
id="coatStock_@(itemIndex)_@(coatIndex)" value="stock"
@(coatType == "stock" ? "checked" : "")
onchange="toggleCoatPowderSelection(@itemIndex, @coatIndex, 'stock')">
<label class="btn btn-outline-primary" for="coatStock_@(itemIndex)_@(coatIndex)">
<i class="bi bi-box-seam me-1"></i>In-Stock Powder
</label>
<input type="radio" class="btn-check"
name="coatPowderType_@(itemIndex)_@(coatIndex)"
id="coatCustom_@(itemIndex)_@(coatIndex)" value="custom"
@(coatType == "custom" ? "checked" : "")
onchange="toggleCoatPowderSelection(@itemIndex, @coatIndex, 'custom')">
<label class="btn btn-outline-primary" for="coatCustom_@(itemIndex)_@(coatIndex)">
<i class="bi bi-bag-plus me-1"></i>Custom Powder
</label>
</div>
<!-- Stock Powder Section -->
<div id="coatStockSection_@(itemIndex)_@(coatIndex)" style="display: @(coatType == "stock" ? "block" : "none")">
<div class="row g-3 mb-3">
<div class="col-md-12">
<label class="form-label">Select Powder from Inventory</label>
<select name="QuoteItems[@itemIndex].Coats[@coatIndex].InventoryItemId"
id="coatInventorySelect_@(itemIndex)_@(coatIndex)"
class="form-select inventory-coat-select"
data-selected-value="@(coat.InventoryItemId ?? 0)"
onchange="onCoatInventorySelected(@itemIndex, @coatIndex)">
<option value="">-- Select Powder --</option>
</select>
</div>
</div>
<div class="row g-3 mb-3">
<div class="col-md-6">
<label class="form-label">Coverage Rate</label>
<div class="input-group input-group-sm">
<input type="number"
name="QuoteItems[@itemIndex].Coats[@coatIndex].CoverageSqFtPerLb"
id="coatCoverage_@(itemIndex)_@(coatIndex)"
class="form-control" value="@coat.CoverageSqFtPerLb"
min="1" max="500" step="0.1"
onchange="calculateCoatPowderNeeded(@itemIndex, @coatIndex)">
<span class="input-group-text">sq ft/lb</span>
</div>
</div>
<div class="col-md-6">
<label class="form-label">Transfer Efficiency</label>
<div class="input-group input-group-sm">
<input type="number"
name="QuoteItems[@itemIndex].Coats[@coatIndex].TransferEfficiency"
id="coatEfficiency_@(itemIndex)_@(coatIndex)"
class="form-control" value="@coat.TransferEfficiency"
min="1" max="100" step="1"
onchange="calculateCoatPowderNeeded(@itemIndex, @coatIndex)">
<span class="input-group-text">%</span>
</div>
</div>
</div>
</div>
<!-- Custom Powder Section -->
<div id="coatCustomSection_@(itemIndex)_@(coatIndex)" style="display: @(coatType == "custom" ? "block" : "none")">
<div class="row g-3 mb-3">
<div class="col-md-6">
<label class="form-label">Color Name</label>
<input type="text"
name="QuoteItems[@itemIndex].Coats[@coatIndex].ColorName"
id="coatColorName_@(itemIndex)_@(coatIndex)"
value="@coat.ColorName"
class="form-control"
placeholder="e.g., Gloss Black RAL 9005"
onchange="updateCoatHeader(@itemIndex, @coatIndex)" />
</div>
<div class="col-md-6">
<label class="form-label">Vendor</label>
<select name="QuoteItems[@itemIndex].Coats[@coatIndex].VendorId"
id="coatVendorSelect_@(itemIndex)_@(coatIndex)"
class="form-select coat-vendor-select"
data-selected-value="@(coat.VendorId ?? 0)">
<option value="">-- Select Vendor --</option>
</select>
</div>
</div>
<div class="row g-3 mb-3">
<div class="col-md-6">
<label class="form-label">Powder to Order</label>
<div class="input-group input-group-sm">
<input type="number"
name="QuoteItems[@itemIndex].Coats[@coatIndex].PowderToOrder"
id="coatPowderToOrder_@(itemIndex)_@(coatIndex)"
value="@coat.PowderToOrder"
class="form-control" min="0" step="1"
placeholder="Auto-calculated" />
<span class="input-group-text">lbs</span>
</div>
<small class="text-muted">Auto-filled from powder needed (rounded up)</small>
</div>
<div class="col-md-6">
<label class="form-label">Powder Cost</label>
<div class="input-group input-group-sm">
<span class="input-group-text">$</span>
<input type="number"
name="QuoteItems[@itemIndex].Coats[@coatIndex].PowderCostPerLb"
value="@coat.PowderCostPerLb"
class="form-control" min="0" step="0.01"
placeholder="0.00" />
<span class="input-group-text">per lb</span>
</div>
</div>
</div>
<div class="row g-3 mb-3">
<div class="col-md-4">
<label class="form-label">Coverage Rate</label>
<div class="input-group input-group-sm">
<input type="number"
name="QuoteItems[@itemIndex].Coats[@coatIndex].CoverageSqFtPerLb"
id="coatCustomCoverage_@(itemIndex)_@(coatIndex)"
class="form-control" value="@coat.CoverageSqFtPerLb"
min="1" max="500" step="0.1"
onchange="calculateCoatPowderNeeded(@itemIndex, @coatIndex)">
<span class="input-group-text">sq ft/lb</span>
</div>
</div>
<div class="col-md-4">
<label class="form-label">Transfer Efficiency</label>
<div class="input-group input-group-sm">
<input type="number"
name="QuoteItems[@itemIndex].Coats[@coatIndex].TransferEfficiency"
id="coatCustomEfficiency_@(itemIndex)_@(coatIndex)"
class="form-control" value="@coat.TransferEfficiency"
min="1" max="100" step="1"
onchange="calculateCoatPowderNeeded(@itemIndex, @coatIndex)">
<span class="input-group-text">%</span>
</div>
</div>
</div>
</div>
<!-- Powder Needed Display (shown for calculated items only) -->
<div class="row g-3 mb-3">
<div class="col-md-12 coat-powder-needed-display" id="coatPowderNeededContainer_@(itemIndex)_@(coatIndex)">
<label class="form-label fw-semibold">Powder Needed for This Coat (Total Batch)</label>
<div class="bg-success bg-opacity-10 border border-success rounded p-3 text-center">
<strong id="coatPowderNeeded_@(itemIndex)_@(coatIndex)" class="fs-5 text-success">0.00 lbs</strong>
</div>
<small class="text-muted">
<i class="bi bi-info-circle"></i> This calculation is for the entire batch (all items × surface area)
</small>
</div>
</div>
<!-- Coat Notes -->
<div class="row g-3">
<div class="col-md-12">
<label class="form-label">Notes (Optional)</label>
<textarea name="QuoteItems[@itemIndex].Coats[@coatIndex].Notes"
class="form-control" rows="2"
placeholder="Special instructions for this coating layer...">@coat.Notes</textarea>
</div>
</div>
</div>
</div>
</div>
}
</div>
<!-- Add Coating Layer Button -->
<div class="mt-3">
<button type="button" class="btn btn-sm btn-outline-success"
onclick="addCoat(@itemIndex)">
<i class="bi bi-plus-circle me-1"></i> Add Coating Layer
</button>
<small class="text-muted ms-2">
<i class="bi bi-info-circle"></i>
First coat = 100% labor, each additional = +30% labor
</small>
</div>
</div>
</div>