Sweep all .cshtml files for encoding corruption; add pre-commit guard
Replace all corruption variants with HTML entities across 226 view files: - 3-char UTF-8-as-Win1252 sequences (ae-corruption) - Standalone smart/curly quotes that break C# Razor expressions - Partially re-corrupted variants where the 3rd byte was normalised to ASCII tools/Fix-Encoding.ps1: re-runnable sweep; uses [char] code points so the script itself never contains a literal non-ASCII character; supports -DryRun .githooks/pre-commit: blocks commits containing the ae-corruption byte signature (xc3xa2xe2x82xac); git core.hooksPath = .githooks so the hook is repo-committed and active for all future work on this machine. Build clean; 225 unit tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@{
|
||||
ViewData["Title"] = "Setup Complete!";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
@@ -78,7 +78,7 @@
|
||||
</div>
|
||||
<h1>You're all set!</h1>
|
||||
<p style="color:rgba(255,255,255,0.8);font-size:1.05rem;max-width:500px;margin:0 auto 1.5rem;">
|
||||
Your setup is complete. @progress.DoneSteps.Count of @WizardProgressDto.TotalSteps steps were configured — your shop is ready to roll.
|
||||
Your setup is complete. @progress.DoneSteps.Count of @WizardProgressDto.TotalSteps steps were configured — your shop is ready to roll.
|
||||
</p>
|
||||
@if (showGuidedActivationCta)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep1Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Company Profile";
|
||||
ViewData["Title"] = "Setup Wizard — Company Profile";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 1;
|
||||
}
|
||||
@@ -25,10 +25,10 @@
|
||||
<div class="small">
|
||||
<strong>Where this information is used:</strong>
|
||||
<ul class="mb-0 mt-1 ps-3">
|
||||
<li><strong>Quote & invoice PDFs</strong> — your company name, address, and phone appear in the header of every document sent to customers.</li>
|
||||
<li><strong>Customer-facing emails</strong> — the primary contact name and email are used as reply-to information in outgoing notifications.</li>
|
||||
<li><strong>Timezone</strong> — affects when scheduled reminders and alerts fire. Set it to your shop's local time.</li>
|
||||
<li><strong>Currency & units</strong> — all pricing and surface area calculations throughout the system will use these preferences.</li>
|
||||
<li><strong>Quote & invoice PDFs</strong> — your company name, address, and phone appear in the header of every document sent to customers.</li>
|
||||
<li><strong>Customer-facing emails</strong> — the primary contact name and email are used as reply-to information in outgoing notifications.</li>
|
||||
<li><strong>Timezone</strong> — affects when scheduled reminders and alerts fire. Set it to your shop's local time.</li>
|
||||
<li><strong>Currency & units</strong> — all pricing and surface area calculations throughout the system will use these preferences.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -100,12 +100,12 @@
|
||||
<div class="col-md-4">
|
||||
<label asp-for="DefaultCurrency" class="form-label fw-semibold"></label>
|
||||
<select asp-for="DefaultCurrency" class="form-select">
|
||||
<option value="USD">USD — US Dollar ($)</option>
|
||||
<option value="CAD">CAD — Canadian Dollar (C$)</option>
|
||||
<option value="EUR">EUR — Euro (€)</option>
|
||||
<option value="GBP">GBP — British Pound (£)</option>
|
||||
<option value="AUD">AUD — Australian Dollar (A$)</option>
|
||||
<option value="MXN">MXN — Mexican Peso (MX$)</option>
|
||||
<option value="USD">USD — US Dollar ($)</option>
|
||||
<option value="CAD">CAD — Canadian Dollar (C$)</option>
|
||||
<option value="EUR">EUR — Euro (€)</option>
|
||||
<option value="GBP">GBP — British Pound (£)</option>
|
||||
<option value="AUD">AUD — Australian Dollar (A$)</option>
|
||||
<option value="MXN">MXN — Mexican Peso (MX$)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-8 d-flex align-items-end pb-1">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep9Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Team Members";
|
||||
ViewData["Title"] = "Setup Wizard — Team Members";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 10;
|
||||
}
|
||||
@@ -29,7 +29,7 @@
|
||||
@foreach (var m in existingMembers)
|
||||
{
|
||||
<li class="list-group-item px-0 py-1 d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-person-circle me-2 text-secondary"></i>@m.FirstName @m.LastName — <span class="text-secondary">@m.Email</span></span>
|
||||
<span><i class="bi bi-person-circle me-2 text-secondary"></i>@m.FirstName @m.LastName — <span class="text-secondary">@m.Email</span></span>
|
||||
<span class="badge bg-secondary">@m.CompanyRole</span>
|
||||
</li>
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep6Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Chart of Accounts";
|
||||
ViewData["Title"] = "Setup Wizard — Chart of Accounts";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 11;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep10Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Vendors & Suppliers";
|
||||
ViewData["Title"] = "Setup Wizard — Vendors & Suppliers";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 12;
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
<div class="wizard-card">
|
||||
<h5 class="wizard-card-title">Vendor List</h5>
|
||||
<p class="text-secondary small mb-3">We've suggested two popular powder coating suppliers to get you started — keep, edit, or remove them as needed. You can add more vendors anytime from the Vendors section.</p>
|
||||
<p class="text-secondary small mb-3">We've suggested two popular powder coating suppliers to get you started — keep, edit, or remove them as needed. You can add more vendors anytime from the Vendors section.</p>
|
||||
|
||||
<div id="vendorsList"></div>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep8Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Inventory / Powder Colors";
|
||||
ViewData["Title"] = "Setup Wizard — Inventory / Powder Colors";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 13;
|
||||
}
|
||||
@@ -22,10 +22,10 @@
|
||||
<div class="small">
|
||||
<strong>Why add inventory during setup?</strong>
|
||||
<ul class="mb-0 mt-1 ps-3">
|
||||
<li><strong>Powder cost calculations</strong> — when unit cost is set, the system automatically calculates the exact powder cost for each coat on a quote based on surface area, coverage rate, and transfer efficiency.</li>
|
||||
<li><strong>Powder Needed display</strong> — quotes and jobs show how many pounds of each color to pull from your shelf, reducing waste and over-ordering.</li>
|
||||
<li><strong>Low-stock alerts</strong> — set reorder points so you're notified before you run out of a color in the middle of a job.</li>
|
||||
<li><strong>Quick selection in quotes</strong> — inventory colors appear in the coating dropdown when building quotes, avoiding typos and ensuring consistency.</li>
|
||||
<li><strong>Powder cost calculations</strong> — when unit cost is set, the system automatically calculates the exact powder cost for each coat on a quote based on surface area, coverage rate, and transfer efficiency.</li>
|
||||
<li><strong>Powder Needed display</strong> — quotes and jobs show how many pounds of each color to pull from your shelf, reducing waste and over-ordering.</li>
|
||||
<li><strong>Low-stock alerts</strong> — set reorder points so you're notified before you run out of a color in the middle of a job.</li>
|
||||
<li><strong>Quick selection in quotes</strong> — inventory colors appear in the coating dropdown when building quotes, avoiding typos and ensuring consistency.</li>
|
||||
</ul>
|
||||
<span class="d-block mt-1 text-secondary">Enter your most-used colors now and add the rest later. You can also import inventory from a CSV file in the Inventory module.</span>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardOvensStepDto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Equipment & Ovens";
|
||||
ViewData["Title"] = "Setup Wizard — Equipment & Ovens";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 14;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardPricingTiersStepDto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Pricing Tiers";
|
||||
ViewData["Title"] = "Setup Wizard — Pricing Tiers";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 15;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardCatalogStepDto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Service Catalog";
|
||||
ViewData["Title"] = "Setup Wizard — Service Catalog";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 16;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep7Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Notifications";
|
||||
ViewData["Title"] = "Setup Wizard — Notifications";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 17;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep9Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Team Members";
|
||||
ViewData["Title"] = "Setup Wizard — Team Members";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 18;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep2QbDto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — QuickBooks Migration";
|
||||
ViewData["Title"] = "Setup Wizard — QuickBooks Migration";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 2;
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* QB Migration Wizard launcher — shown when "Yes" is selected *@
|
||||
@* QB Migration Wizard launcher — shown when "Yes" is selected *@
|
||||
<div id="qbMigrationSection" class="wizard-card d-none">
|
||||
<div class="d-flex align-items-start gap-3">
|
||||
<div class="rounded-3 p-3 d-flex align-items-center justify-content-center flex-shrink-0"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@using PowderCoating.Core.Enums
|
||||
@model WizardStep2Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Operating Costs";
|
||||
ViewData["Title"] = "Setup Wizard — Operating Costs";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 3;
|
||||
}
|
||||
@@ -21,23 +21,23 @@
|
||||
<form asp-action="PostStep3" method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
<!-- Shop Capability Tier — quick calibration starting point -->
|
||||
<!-- Shop Capability Tier — quick calibration starting point -->
|
||||
<div class="wizard-card">
|
||||
<h5 class="wizard-card-title mb-3"><i class="bi bi-speedometer2 me-2"></i>Shop Size</h5>
|
||||
<p class="text-secondary small mb-3">
|
||||
This sets starting defaults for your quoting calibration — how fast your equipment can prep and coat parts.
|
||||
This sets starting defaults for your quoting calibration — how fast your equipment can prep and coat parts.
|
||||
You can fine-tune this later in <strong>Company Settings → Shop Equipment Profile</strong>.
|
||||
</p>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-8">
|
||||
<label asp-for="ShopCapabilityTier" class="form-label fw-semibold">What best describes your shop?</label>
|
||||
<select asp-for="ShopCapabilityTier" class="form-select">
|
||||
<option value="@((int)ShopCapabilityTier.Garage)">Garage — Home setup, small compressor, part-time</option>
|
||||
<option value="@((int)ShopCapabilityTier.Small)">Small — 1–5 person shop</option>
|
||||
<option value="@((int)ShopCapabilityTier.Medium)">Medium — Established shop, 5–10 people</option>
|
||||
<option value="@((int)ShopCapabilityTier.Large)">Large — High-volume operation, 10+ people</option>
|
||||
<option value="@((int)ShopCapabilityTier.Garage)">Garage — Home setup, small compressor, part-time</option>
|
||||
<option value="@((int)ShopCapabilityTier.Small)">Small — 1–5 person shop</option>
|
||||
<option value="@((int)ShopCapabilityTier.Medium)">Medium — Established shop, 5–10 people</option>
|
||||
<option value="@((int)ShopCapabilityTier.Large)">Large — High-volume operation, 10+ people</option>
|
||||
</select>
|
||||
<div class="form-text">This affects how the AI estimates sandblasting and prep time — a garage coater and a large shop blast the same wheel at very different speeds.</div>
|
||||
<div class="form-text">This affects how the AI estimates sandblasting and prep time — a garage coater and a large shop blast the same wheel at very different speeds.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -53,7 +53,7 @@
|
||||
<input asp-for="StandardLaborRate" class="form-control" step="0.01" type="number" min="0" />
|
||||
<span class="input-group-text">/hr</span>
|
||||
</div>
|
||||
<div class="form-text">Applied to every hour of hands-on work on a quote item — sandblasting, masking, coating, and general labor time all draw from this rate.</div>
|
||||
<div class="form-text">Applied to every hour of hands-on work on a quote item — sandblasting, masking, coating, and general labor time all draw from this rate.</div>
|
||||
<span asp-validation-for="StandardLaborRate" class="text-danger small"></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -183,7 +183,7 @@
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
MODAL 1 — Labor Rate Calculator
|
||||
MODAL 1 — Labor Rate Calculator
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div class="modal fade" id="laborCalcModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
@@ -223,7 +223,7 @@
|
||||
<div class="alert alert-warning alert-permanent d-flex gap-2 mb-0" role="alert">
|
||||
<i class="bi bi-lightbulb flex-shrink-0 mt-1"></i>
|
||||
<div class="small">
|
||||
<strong>Tip:</strong> This covers direct labor only. Facility and overhead costs are built into the equipment rates, and your markup percentage adds profit on top. Don't try to roll everything into the labor rate — keep them separate for accurate job costing.
|
||||
<strong>Tip:</strong> This covers direct labor only. Facility and overhead costs are built into the equipment rates, and your markup percentage adds profit on top. Don't try to roll everything into the labor rate — keep them separate for accurate job costing.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -238,7 +238,7 @@
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
MODAL 2 — Equipment Cost Calculator
|
||||
MODAL 2 — Equipment Cost Calculator
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div class="modal fade" id="equipCalcModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
@@ -293,7 +293,7 @@
|
||||
<div class="alert alert-warning alert-permanent d-flex gap-2 mb-0" role="alert">
|
||||
<i class="bi bi-lightbulb flex-shrink-0 mt-1"></i>
|
||||
<div class="small">
|
||||
<strong>Tip:</strong> These are estimates based on typical equipment power draw as a share of total shop electricity. Your actual numbers may vary — use these as a starting point and adjust based on your experience.
|
||||
<strong>Tip:</strong> These are estimates based on typical equipment power draw as a share of total shop electricity. Your actual numbers may vary — use these as a starting point and adjust based on your experience.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -308,7 +308,7 @@
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
MODAL 3 — Powder Cost Calculator
|
||||
MODAL 3 — Powder Cost Calculator
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div class="modal fade" id="powderCalcModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
@@ -335,12 +335,12 @@
|
||||
<div class="col-md-8">
|
||||
<label class="form-label fw-semibold">Shop mix / coverage</label>
|
||||
<select id="pc_coverage" class="form-select" onchange="powderCalc()">
|
||||
<option value="100">Simple parts, flat panels — ~100 sq ft/lb</option>
|
||||
<option value="80" selected>Average shop mix — ~80 sq ft/lb</option>
|
||||
<option value="60">Complex / detailed parts — ~60 sq ft/lb</option>
|
||||
<option value="45">Heavy rework, lots of masking — ~45 sq ft/lb</option>
|
||||
<option value="100">Simple parts, flat panels — ~100 sq ft/lb</option>
|
||||
<option value="80" selected>Average shop mix — ~80 sq ft/lb</option>
|
||||
<option value="60">Complex / detailed parts — ~60 sq ft/lb</option>
|
||||
<option value="45">Heavy rework, lots of masking — ~45 sq ft/lb</option>
|
||||
</select>
|
||||
<div class="form-text">Real-world coverage at 2–3 mil thickness, including overspray & waste.</div>
|
||||
<div class="form-text">Real-world coverage at 2–3 mil thickness, including overspray & waste.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -355,9 +355,9 @@
|
||||
<div class="col-md-6 d-flex align-items-center">
|
||||
<div class="small text-secondary">
|
||||
<div class="mb-2"><strong>Typical powder prices:</strong></div>
|
||||
<div>Standard solid colors $3–6/lb</div>
|
||||
<div>Metallic / candy $6–10/lb</div>
|
||||
<div>Specialty / texture $8–15/lb</div>
|
||||
<div>Standard solid colors $3–6/lb</div>
|
||||
<div>Metallic / candy $6–10/lb</div>
|
||||
<div>Specialty / texture $8–15/lb</div>
|
||||
<div class="mt-2 text-secondary" style="font-size:0.75rem;">Use your blended average if you stock multiple types.</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -366,7 +366,7 @@
|
||||
<div class="alert alert-warning alert-permanent d-flex gap-2 mb-0" role="alert">
|
||||
<i class="bi bi-lightbulb flex-shrink-0 mt-1"></i>
|
||||
<div class="small">
|
||||
<strong>Tip:</strong> This is your material cost only — labor and equipment are priced separately. Your markup percentage (set below) adds profit on top of all costs combined.
|
||||
<strong>Tip:</strong> This is your material cost only — labor and equipment are priced separately. Your markup percentage (set below) adds profit on top of all costs combined.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardOvensStepDto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Shop Equipment";
|
||||
ViewData["Title"] = "Setup Wizard — Shop Equipment";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 4;
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="wizard-step-header">
|
||||
<span class="wizard-step-badge">Step @step of @WizardProgressDto.TotalSteps</span>
|
||||
<h2><i class="bi bi-tools me-2"></i>Shop Equipment</h2>
|
||||
<p class="text-secondary">Register your ovens and blast setups. Ovens power the Oven Scheduler and quoting engine — at least one is required. Blast setups define each rig's throughput rate so the AI quote engine can estimate sandblasting time accurately.</p>
|
||||
<p class="text-secondary">Register your ovens and blast setups. Ovens power the Oven Scheduler and quoting engine — at least one is required. Blast setups define each rig's throughput rate so the AI quote engine can estimate sandblasting time accurately.</p>
|
||||
</div>
|
||||
|
||||
<form asp-action="PostStep4" method="post" onsubmit="return validateStep4()">
|
||||
@@ -49,7 +49,7 @@
|
||||
<h5 class="wizard-card-title"><i class="bi bi-fan me-2"></i>Blast Setups</h5>
|
||||
<p class="text-secondary small mb-3">
|
||||
Add each blast rig in your shop (cabinets, pressure pots, blast rooms). The AI quoting engine uses CFM,
|
||||
nozzle size, and substrate to derive a sqft/hr throughput rate. Mark one as the default — it will be
|
||||
nozzle size, and substrate to derive a sqft/hr throughput rate. Mark one as the default — it will be
|
||||
pre-selected when quoting. You can also enter a measured rate override if you prefer to use real shop data.
|
||||
Blast setups are optional; skip this section if you don't do in-house blasting.
|
||||
</p>
|
||||
@@ -132,7 +132,7 @@
|
||||
<div class="col-12 mb-1">
|
||||
<span class="small fw-semibold text-secondary">
|
||||
<i class="bi bi-rulers me-1"></i>Dimension Calculator
|
||||
<span class="fw-normal">(optional — enter interior oven dimensions)</span>
|
||||
<span class="fw-normal">(optional — enter interior oven dimensions)</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep3Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Document Numbering";
|
||||
ViewData["Title"] = "Setup Wizard — Document Numbering";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 5;
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="wizard-card">
|
||||
<h5 class="wizard-card-title">Document Prefixes</h5>
|
||||
<p class="text-secondary small mb-3">
|
||||
Numbers are generated automatically in the format <strong>PREFIX-YYMM-####</strong> — for example, <code>QT-2604-0001</code> or <code>JOB-2604-0001</code>.
|
||||
Numbers are generated automatically in the format <strong>PREFIX-YYMM-####</strong> — for example, <code>QT-2604-0001</code> or <code>JOB-2604-0001</code>.
|
||||
You can use any short prefix (up to 10 characters) that makes sense for your business.
|
||||
</p>
|
||||
<div class="row g-3">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep5Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Job Settings";
|
||||
ViewData["Title"] = "Setup Wizard — Job Settings";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 6;
|
||||
}
|
||||
@@ -20,8 +20,8 @@
|
||||
<div class="alert alert-info alert-permanent d-flex align-items-start gap-2 mb-3" role="alert">
|
||||
<i class="bi bi-info-circle-fill flex-shrink-0 mt-1"></i>
|
||||
<div class="small">
|
||||
<strong>Customer PO Number</strong> — if enabled, a Purchase Order number becomes required before a job can move to active status. This is most useful for commercial/B2B customers who need to tie your invoice to their internal purchasing system. For walk-in retail shops, leave this off.<br />
|
||||
<strong class="d-block mt-1">Customer Approval via Link</strong> — when enabled, customers receive a secure email link with their quote so they can approve or reject it online without calling you. Approved quotes automatically convert to jobs. This dramatically reduces back-and-forth for remote or commercial clients.
|
||||
<strong>Customer PO Number</strong> — if enabled, a Purchase Order number becomes required before a job can move to active status. This is most useful for commercial/B2B customers who need to tie your invoice to their internal purchasing system. For walk-in retail shops, leave this off.<br />
|
||||
<strong class="d-block mt-1">Customer Approval via Link</strong> — when enabled, customers receive a secure email link with their quote so they can approve or reject it online without calling you. Approved quotes automatically convert to jobs. This dramatically reduces back-and-forth for remote or commercial clients.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep4Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Payment Terms";
|
||||
ViewData["Title"] = "Setup Wizard — Payment Terms";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 7;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardPricingTiersStepDto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Pricing Tiers";
|
||||
ViewData["Title"] = "Setup Wizard — Pricing Tiers";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 8;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using PowderCoating.Application.DTOs.Wizard
|
||||
@model WizardStep7Dto
|
||||
@{
|
||||
ViewData["Title"] = "Setup Wizard — Notifications";
|
||||
ViewData["Title"] = "Setup Wizard — Notifications";
|
||||
var progress = ViewBag.Progress as WizardProgressDto ?? new WizardProgressDto();
|
||||
int step = ViewBag.Step as int? ?? 5;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@* QuickBooks Migration Wizard — embedded modal partial included in Step2.cshtml *@
|
||||
@* QuickBooks Migration Wizard — embedded modal partial included in Step2.cshtml *@
|
||||
|
||||
<div class="modal fade" id="qbMigrationWizard" tabindex="-1"
|
||||
aria-labelledby="qbMigrationWizardLabel" aria-hidden="true"
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="modal-body pt-4" id="qbwStepContent">
|
||||
<div class="text-center py-5">
|
||||
<div class="spinner-border text-primary" role="status"></div>
|
||||
<p class="mt-2 text-secondary">Loading…</p>
|
||||
<p class="mt-2 text-secondary">Loading…</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
Next Step <i class="bi bi-arrow-right ms-1"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-success d-none" id="qbwBtnFinish" onclick="qbwFinish()" data-bs-dismiss="modal">
|
||||
<i class="bi bi-check-lg me-1"></i>Done — Close Wizard
|
||||
<i class="bi bi-check-lg me-1"></i>Done — Close Wizard
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user