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:
@@ -26,7 +26,7 @@
|
||||
</p>
|
||||
<p>
|
||||
Keeping inventory accurate matters for two reasons. First, your job and quote pricing is only
|
||||
as accurate as the unit costs stored in inventory — outdated costs lead to under-pricing.
|
||||
as accurate as the unit costs stored in inventory — outdated costs lead to under-pricing.
|
||||
Second, knowing how much powder you have on hand before a job starts prevents the frustrating
|
||||
situation of running out of material mid-job.
|
||||
</p>
|
||||
@@ -45,19 +45,19 @@
|
||||
<li class="mb-2">
|
||||
Fill in the item details:
|
||||
<ul class="mt-1">
|
||||
<li><strong>Item Name</strong> — a clear, descriptive name (e.g., "Gloss Black Powder — Tiger Drylac 49/90005").</li>
|
||||
<li><strong>SKU / Part Number</strong> — the manufacturer's part number or your internal SKU.</li>
|
||||
<li><strong>Category</strong> — Powder, Primer, Consumable, Shop Supply, or other category as appropriate.</li>
|
||||
<li><strong>Unit of Measure</strong> — lbs, kg, each, litre, etc.</li>
|
||||
<li><strong>Unit Cost</strong> — your purchase cost per unit. Used in quote and job pricing calculations.</li>
|
||||
<li><strong>Current Quantity on Hand</strong> — the number of units you have right now. This becomes the opening stock level.</li>
|
||||
<li><strong>Reorder Point</strong> — the quantity at which you want to be alerted to reorder. See the Reorder Points section below.</li>
|
||||
<li><strong>Vendor / Supplier</strong> — the vendor you purchase this item from. Linking a vendor lets you quickly see who to call when stock runs low.</li>
|
||||
<li><strong>Item Name</strong> — a clear, descriptive name (e.g., "Gloss Black Powder — Tiger Drylac 49/90005").</li>
|
||||
<li><strong>SKU / Part Number</strong> — the manufacturer's part number or your internal SKU.</li>
|
||||
<li><strong>Category</strong> — Powder, Primer, Consumable, Shop Supply, or other category as appropriate.</li>
|
||||
<li><strong>Unit of Measure</strong> — lbs, kg, each, litre, etc.</li>
|
||||
<li><strong>Unit Cost</strong> — your purchase cost per unit. Used in quote and job pricing calculations.</li>
|
||||
<li><strong>Current Quantity on Hand</strong> — the number of units you have right now. This becomes the opening stock level.</li>
|
||||
<li><strong>Reorder Point</strong> — the quantity at which you want to be alerted to reorder. See the Reorder Points section below.</li>
|
||||
<li><strong>Vendor / Supplier</strong> — the vendor you purchase this item from. Linking a vendor lets you quickly see who to call when stock runs low.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
For powder coatings, the <strong>Coverage Rate</strong> (sq ft per lb) and <strong>Transfer Efficiency %</strong>
|
||||
default to <strong>30 sq ft/lb</strong> and <strong>65%</strong> respectively — typical starting values for most powder
|
||||
default to <strong>30 sq ft/lb</strong> and <strong>65%</strong> respectively — typical starting values for most powder
|
||||
and application setups. Adjust these to match your specific powder and equipment. Both values are used when
|
||||
calculating powder needed on quotes and jobs.
|
||||
</li>
|
||||
@@ -86,12 +86,12 @@
|
||||
<p>
|
||||
Click the <strong>Lookup</strong> button next to the SKU/Part Number field. Type a color name,
|
||||
SKU, or part number and the system searches a built-in catalog of thousands of Prismatic Powders
|
||||
and other manufacturer SKUs. Select a match and the form fills in automatically — item name,
|
||||
and other manufacturer SKUs. Select a match and the form fills in automatically — item name,
|
||||
manufacturer, color code, finish, coverage rate, SDS/TDS links, and cure specifications.
|
||||
</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-1">The catalog only shows products <strong>not already in your inventory</strong>, preventing duplicates. When editing an existing item, its own catalog entry is always shown.</li>
|
||||
<li class="mb-1">If no catalog match is found, the lookup falls back to <strong>AI Lookup</strong> — Claude searches the web for product specs and fills in whatever it can find.</li>
|
||||
<li class="mb-1">If no catalog match is found, the lookup falls back to <strong>AI Lookup</strong> — Claude searches the web for product specs and fills in whatever it can find.</li>
|
||||
<li class="mb-1">If a vendor name is selected in the Vendor field before searching, results are scoped to that vendor first, then broadened automatically if nothing matches.</li>
|
||||
</ul>
|
||||
|
||||
@@ -102,11 +102,11 @@
|
||||
The scanner reads the code and attempts to identify the product:
|
||||
</p>
|
||||
<ol class="mb-3">
|
||||
<li class="mb-1">If the QR code matches a product in the platform catalog, the form fills in automatically — same as a manual catalog lookup.</li>
|
||||
<li class="mb-1">If the QR code matches a product in the platform catalog, the form fills in automatically — same as a manual catalog lookup.</li>
|
||||
<li class="mb-1">If no catalog match is found, the AI analyzes the label image and fills in whatever details it can extract (color name, SKU, manufacturer, finish).</li>
|
||||
<li class="mb-1">
|
||||
If the scanned product is <strong>already in your inventory</strong>, a prompt appears to
|
||||
<strong>Add Stock</strong> to the existing item instead — enter the quantity received and an
|
||||
<strong>Add Stock</strong> to the existing item instead — enter the quantity received and an
|
||||
optional updated unit cost, then save. No duplicate item is created.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -127,7 +127,7 @@
|
||||
</h2>
|
||||
<p>
|
||||
The <strong>quantity on hand</strong> for each item is updated automatically whenever a transaction
|
||||
is recorded — a purchase receipt increases stock, a job consumption decreases it, and a manual
|
||||
is recorded — a purchase receipt increases stock, a job consumption decreases it, and a manual
|
||||
adjustment sets it to the corrected count.
|
||||
</p>
|
||||
<p>
|
||||
@@ -142,8 +142,8 @@
|
||||
A good reorder point accounts for two factors:
|
||||
</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-1"><strong>Lead time</strong> — how many days it typically takes for your vendor to deliver after you place an order. If lead time is 5 days, your reorder point should cover at least 5 days of usage.</li>
|
||||
<li class="mb-1"><strong>Daily usage rate</strong> — how much of the item you typically consume per day based on your job volume.</li>
|
||||
<li class="mb-1"><strong>Lead time</strong> — how many days it typically takes for your vendor to deliver after you place an order. If lead time is 5 days, your reorder point should cover at least 5 days of usage.</li>
|
||||
<li class="mb-1"><strong>Daily usage rate</strong> — how much of the item you typically consume per day based on your job volume.</li>
|
||||
</ul>
|
||||
<p>
|
||||
For example, if you use 3 lbs of a powder per day and your vendor takes 5 days to deliver, a
|
||||
@@ -163,9 +163,9 @@
|
||||
</p>
|
||||
<p>Click <strong>Stock Adjustment</strong> in the Actions panel and choose one of three modes:</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-2"><strong>Add Stock</strong> — increases the current quantity by the amount you enter. Use for received goods, returns, or found stock.</li>
|
||||
<li class="mb-2"><strong>Remove Stock</strong> — decreases the current quantity by the amount you enter. Use for waste, spillage, or damage write-offs.</li>
|
||||
<li class="mb-2"><strong>Set Exact</strong> — sets the quantity on hand to the exact number you enter, regardless of the current value. Use after a physical inventory count to correct the balance.</li>
|
||||
<li class="mb-2"><strong>Add Stock</strong> — increases the current quantity by the amount you enter. Use for received goods, returns, or found stock.</li>
|
||||
<li class="mb-2"><strong>Remove Stock</strong> — decreases the current quantity by the amount you enter. Use for waste, spillage, or damage write-offs.</li>
|
||||
<li class="mb-2"><strong>Set Exact</strong> — sets the quantity on hand to the exact number you enter, regardless of the current value. Use after a physical inventory count to correct the balance.</li>
|
||||
</ul>
|
||||
<p>
|
||||
A <strong>reason</strong> is required for every adjustment. Common reasons are listed in the dropdown
|
||||
@@ -230,7 +230,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Job Usage</strong></td>
|
||||
<td>Powder consumed during a job — recorded automatically when actual usage is entered on a job coat.</td>
|
||||
<td>Powder consumed during a job — recorded automatically when actual usage is entered on a job coat.</td>
|
||||
<td class="text-danger fw-semibold">− Decreases</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -268,12 +268,12 @@
|
||||
<p>It has two tabs:</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-2">
|
||||
<strong>Stock Transactions</strong> — every transaction recorded against your inventory items,
|
||||
<strong>Stock Transactions</strong> — every transaction recorded against your inventory items,
|
||||
showing date, type, quantity (green for additions, red for deductions), unit cost, total cost,
|
||||
running balance after the transaction, and a link to the source Purchase Order if applicable.
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<strong>Powder Usage by Job</strong> — every instance of powder being consumed on a job coat,
|
||||
<strong>Powder Usage by Job</strong> — every instance of powder being consumed on a job coat,
|
||||
showing the job number (linked to the job), customer, color applied, estimated vs actual pounds
|
||||
used, and the variance. A totals row at the bottom summarises the full filtered selection.
|
||||
</li>
|
||||
@@ -287,7 +287,7 @@
|
||||
<i class="bi bi-lightbulb-fill flex-shrink-0 mt-1"></i>
|
||||
<div>
|
||||
To see the history for a single powder, open its Details page and click
|
||||
<strong>View Activity History</strong> — the Inventory Activity page will open pre-filtered
|
||||
<strong>View Activity History</strong> — the Inventory Activity page will open pre-filtered
|
||||
to that item.
|
||||
</div>
|
||||
</div>
|
||||
@@ -299,14 +299,14 @@
|
||||
</h2>
|
||||
<p>
|
||||
Every inventory item has a printable <strong>QR code label</strong>. Stick it on the bag, bin,
|
||||
or shelf and shop floor workers can scan it with their phone to log how much they used —
|
||||
or shelf and shop floor workers can scan it with their phone to log how much they used —
|
||||
without ever touching a desktop.
|
||||
</p>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-4 mb-2">Printing a label</h3>
|
||||
<ol class="mb-3">
|
||||
<li class="mb-1">Open the inventory item's Details page.</li>
|
||||
<li class="mb-1">Click <strong>Print QR Label</strong> in the Actions panel — the label opens in a new tab.</li>
|
||||
<li class="mb-1">Click <strong>Print QR Label</strong> in the Actions panel — the label opens in a new tab.</li>
|
||||
<li class="mb-1">Click <strong>Print Label</strong> and send it to your printer. The label is sized for a standard 3.5″ label and includes the item name, SKU, colour, finish, and manufacturer.</li>
|
||||
</ol>
|
||||
|
||||
@@ -316,9 +316,9 @@
|
||||
<li class="mb-1">
|
||||
<strong>Select a job</strong> (optional but recommended):
|
||||
<ul class="mt-1">
|
||||
<li><em>My Jobs</em> — active jobs assigned to your account appear first.</li>
|
||||
<li><em>Other Jobs</em> — any other open job in the system.</li>
|
||||
<li><em>No Job</em> — log usage without a job reference (e.g. a waste event).</li>
|
||||
<li><em>My Jobs</em> — active jobs assigned to your account appear first.</li>
|
||||
<li><em>Other Jobs</em> — any other open job in the system.</li>
|
||||
<li><em>No Job</em> — log usage without a job reference (e.g. a waste event).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="mb-1">Enter the <strong>quantity</strong> used. A live preview shows what the new stock balance will be.</li>
|
||||
@@ -331,8 +331,8 @@
|
||||
The success screen gives you two options:
|
||||
</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-1"><strong>Log Another Item for This Job</strong> — returns to the scan page with the same job pre-selected, so you can quickly log the next powder without re-picking the job.</li>
|
||||
<li class="mb-1"><strong>Back to Inventory</strong> or <strong>View Item Details</strong> — returns to a neutral state.</li>
|
||||
<li class="mb-1"><strong>Log Another Item for This Job</strong> — returns to the scan page with the same job pre-selected, so you can quickly log the next powder without re-picking the job.</li>
|
||||
<li class="mb-1"><strong>Back to Inventory</strong> or <strong>View Item Details</strong> — returns to a neutral state.</li>
|
||||
</ul>
|
||||
|
||||
<div class="alert alert-permanent alert-info d-flex gap-2 mb-0" role="alert">
|
||||
@@ -341,7 +341,7 @@
|
||||
Every scan-based usage log is recorded as a <strong>JobUsage</strong> or <strong>Adjustment</strong>
|
||||
transaction and immediately reduces the item's quantity on hand. You can review it on the
|
||||
<a href="/Inventory/Ledger" class="alert-link">Inventory Activity</a> page.
|
||||
The first time a worker scans on a new device they will be asked to log in — after that the
|
||||
The first time a worker scans on a new device they will be asked to log in — after that the
|
||||
browser keeps them signed in.
|
||||
</div>
|
||||
</div>
|
||||
@@ -374,7 +374,7 @@
|
||||
<div>
|
||||
An item continues to show as Low Stock or Out of Stock even after you have placed a Purchase
|
||||
Order, until the goods are physically received and the PO is marked as Received in the system.
|
||||
This is intentional — it reminds you that stock has not yet arrived.
|
||||
This is intentional — it reminds you that stock has not yet arrived.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -428,12 +428,12 @@
|
||||
<li class="mb-2">Go to <strong><a asp-controller="CompanySettings" asp-action="Index">Company Settings</a> › Data Lookups › Inventory Categories</strong>.</li>
|
||||
<li class="mb-2">Find the category that contains your powder coating colors (e.g. "Powder Coatings").</li>
|
||||
<li class="mb-2">Click the edit icon and check the <strong>Is Coating</strong> checkbox.</li>
|
||||
<li class="mb-2">Save. Items in that category will immediately appear in the powder color dropdown on all quotes and jobs — no restart required.</li>
|
||||
<li class="mb-2">Save. Items in that category will immediately appear in the powder color dropdown on all quotes and jobs — no restart required.</li>
|
||||
</ol>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-3 mb-2">Which categories should have "Is Coating" enabled?</h3>
|
||||
<p>
|
||||
Only categories that contain actual powder coating colors — the materials that go into the oven
|
||||
Only categories that contain actual powder coating colors — the materials that go into the oven
|
||||
and bond to the part. Do <strong>not</strong> enable this on categories for primers, masking
|
||||
supplies, consumables, or equipment. Enabling it on non-coating categories will pollute the
|
||||
color dropdown with irrelevant items and make it harder to find the right powder.
|
||||
@@ -443,7 +443,7 @@
|
||||
<i class="bi bi-lightbulb-fill flex-shrink-0 mt-1"></i>
|
||||
<div>
|
||||
The "Is Coating" flag also controls where the <strong>sample panel toggle</strong> appears
|
||||
on an item's Details page. The toggle — "I have a swatch/sample of this color" — only
|
||||
on an item's Details page. The toggle — "I have a swatch/sample of this color" — only
|
||||
shows up for items in a coating category, and those items are the ones tracked on the
|
||||
<strong>Sample Panels</strong> page.
|
||||
</div>
|
||||
@@ -459,9 +459,9 @@
|
||||
will be needed before the job begins. This estimate is based on three values:
|
||||
</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-1"><strong>Surface area</strong> — the total square footage to be coated (entered per item in the job or quote wizard).</li>
|
||||
<li class="mb-1"><strong>Coverage rate</strong> — how many square feet one pound of the selected powder covers (set on the inventory item).</li>
|
||||
<li class="mb-1"><strong>Number of coats</strong> — selected when you add the coating to the item.</li>
|
||||
<li class="mb-1"><strong>Surface area</strong> — the total square footage to be coated (entered per item in the job or quote wizard).</li>
|
||||
<li class="mb-1"><strong>Coverage rate</strong> — how many square feet one pound of the selected powder covers (set on the inventory item).</li>
|
||||
<li class="mb-1"><strong>Number of coats</strong> — selected when you add the coating to the item.</li>
|
||||
</ul>
|
||||
<p>
|
||||
The <strong>Powder Needed</strong> figure appears in the item wizard as you build the quote or job,
|
||||
@@ -486,30 +486,30 @@
|
||||
The AI Price Check reviews every active, priced item in your
|
||||
<a asp-controller="CatalogItems" asp-action="Index">Catalog Items</a> list against your
|
||||
shop's actual operating costs. It estimates a realistic surface area and processing time
|
||||
for each item, calculates a cost floor, and compares that to your current price — flagging
|
||||
for each item, calculates a cost floor, and compares that to your current price — flagging
|
||||
anything that may be losing money, leaving margin on the table, or priced above market rates.
|
||||
</p>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-3 mb-2">Verdicts</h3>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-2"><strong>Below Cost</strong> — price is at or below the estimated cost floor. The shop loses money on every sale of this item.</li>
|
||||
<li class="mb-2"><strong>Thin Margin</strong> — price covers costs but falls below your target margin percentage.</li>
|
||||
<li class="mb-2"><strong>High</strong> — price appears significantly above typical market rates, which may cost you work.</li>
|
||||
<li class="mb-2"><strong>OK</strong> — price is within a reasonable range given your costs and market context.</li>
|
||||
<li class="mb-2"><strong>Below Cost</strong> — price is at or below the estimated cost floor. The shop loses money on every sale of this item.</li>
|
||||
<li class="mb-2"><strong>Thin Margin</strong> — price covers costs but falls below your target margin percentage.</li>
|
||||
<li class="mb-2"><strong>High</strong> — price appears significantly above typical market rates, which may cost you work.</li>
|
||||
<li class="mb-2"><strong>OK</strong> — price is within a reasonable range given your costs and market context.</li>
|
||||
</ul>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-3 mb-2">How to run it</h3>
|
||||
<ol class="mb-3">
|
||||
<li class="mb-2">Make sure your <a asp-controller="CompanySettings" asp-action="Index">operating costs</a> are up to date — stale rates produce inaccurate verdicts.</li>
|
||||
<li class="mb-2">Make sure your <a asp-controller="CompanySettings" asp-action="Index">operating costs</a> are up to date — stale rates produce inaccurate verdicts.</li>
|
||||
<li class="mb-2">Go to <a asp-controller="CatalogItems" asp-action="Index">Catalog Items</a> and click <strong>AI Price Check</strong> in the top-right.</li>
|
||||
<li class="mb-2">Click <strong>Analyze Catalog with AI</strong>. A progress overlay appears while the analysis runs (allow 7–10 minutes for large catalogs).</li>
|
||||
<li class="mb-2">Review results sorted by severity — Below Cost items appear first. Click <strong>Edit Price</strong> on any item to update it directly from the results page.</li>
|
||||
<li class="mb-2">Click <strong>Analyze Catalog with AI</strong>. A progress overlay appears while the analysis runs (allow 7–10 minutes for large catalogs).</li>
|
||||
<li class="mb-2">Review results sorted by severity — Below Cost items appear first. Click <strong>Edit Price</strong> on any item to update it directly from the results page.</li>
|
||||
</ol>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-3 mb-2">Things to know</h3>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-2"><strong>Run limit:</strong> Analysis can be run once per quarter (90 days). The button shows the next available date when a recent run exists.</li>
|
||||
<li class="mb-2"><strong>Confidence levels:</strong> Each result shows High, Medium, or Low confidence. Vague item names like "Custom Part" will be Low — verify those manually.</li>
|
||||
<li class="mb-2"><strong>Confidence levels:</strong> Each result shows High, Medium, or Low confidence. Vague item names like "Custom Part" will be Low — verify those manually.</li>
|
||||
<li class="mb-2"><strong>Category paths matter:</strong> The AI uses the full category path (e.g. "Cerakote › Firearms") to determine the coating type. Make sure specialty items are in the correct category.</li>
|
||||
<li class="mb-2"><strong>$0 items skipped:</strong> Placeholder items and category headers with no price are automatically excluded from analysis.</li>
|
||||
</ul>
|
||||
@@ -518,7 +518,7 @@
|
||||
<i class="bi bi-exclamation-triangle-fill flex-shrink-0 mt-1"></i>
|
||||
<div>
|
||||
Results are estimates based on industry knowledge and your shop's rates. Always apply
|
||||
your own judgment before changing prices — especially for items flagged as Low confidence.
|
||||
your own judgment before changing prices — especially for items flagged as Low confidence.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user