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:
2026-05-20 21:37:10 -04:00
parent 21b39161a3
commit a0bdd2b5b4
252 changed files with 1785 additions and 1633 deletions
@@ -28,7 +28,7 @@
<p>
When you make a payment to a vendor, you record it against the bill and the balance reduces.
This gives you a clear, real-time picture of your upcoming financial obligations and helps you
avoid late payments and the late fees or strained vendor relationships that come with them.
avoid late payments &mdash; and the late fees or strained vendor relationships that come with them.
</p>
<p>
Bills can be created manually or generated automatically from a received Purchase Order.
@@ -46,14 +46,14 @@
<p>
The fastest and most accurate way to create a bill is from a received Purchase Order. Open the
received PO and click <strong>Create Bill</strong>. The system generates a bill pre-filled with
all line items, quantities, and prices from the PO linked to the vendor and expense accounts
all line items, quantities, and prices from the PO &mdash; linked to the vendor and expense accounts
automatically. See the <a asp-controller="Help" asp-action="PurchaseOrders">Purchase Orders help page</a>
for step-by-step instructions.
</p>
<h3 class="h6 fw-semibold mt-3 mb-2">Manually</h3>
<p>
To create a bill that is not linked to a PO for example, a utility bill, a service invoice,
To create a bill that is not linked to a PO &mdash; for example, a utility bill, a service invoice,
or a vendor charge that arrived without a matching order:
</p>
<ol class="mb-3">
@@ -64,8 +64,8 @@
<li class="mb-2">
Add one or more <strong>line items</strong>:
<ul class="mt-1">
<li><strong>Expense Account</strong> the accounting category this cost belongs to (e.g., Cost of Goods Sold, Shop Supplies, Equipment Maintenance).</li>
<li><strong>Description</strong> a brief note about what this line covers.</li>
<li><strong>Expense Account</strong> &mdash; the accounting category this cost belongs to (e.g., Cost of Goods Sold, Shop Supplies, Equipment Maintenance).</li>
<li><strong>Description</strong> &mdash; a brief note about what this line covers.</li>
<li><strong>Quantity</strong> and <strong>Unit Price</strong>.</li>
</ul>
</li>
@@ -129,8 +129,8 @@
<i class="bi bi-check-circle text-primary me-2"></i>Marking a Bill as Open
</h2>
<p>
When you have verified that a bill is accurate it matches the goods you received and the
prices you agreed on you mark it as Open to post it to your AP ledger.
When you have verified that a bill is accurate &mdash; it matches the goods you received and the
prices you agreed on &mdash; you mark it as Open to post it to your AP ledger.
</p>
<ol class="mb-3">
<li class="mb-2">Open the Draft bill from <strong>Accounting &rsaquo; Bills</strong>.</li>
@@ -160,7 +160,7 @@
<i class="bi bi-cash-coin text-primary me-2"></i>Recording a Payment
</h2>
<p>
When you pay a vendor whether in full or as a partial payment you record the payment against
When you pay a vendor &mdash; whether in full or as a partial payment &mdash; you record the payment against
the open bill. The system supports multiple partial payments on a single bill.
</p>
<ol class="mb-3">
@@ -169,11 +169,11 @@
<li class="mb-2">
Enter the payment details:
<ul class="mt-1">
<li><strong>Amount</strong> how much you are paying now. Can be less than the full balance for partial payments.</li>
<li><strong>Payment Method</strong> Check, ACH / Bank Transfer, Credit Card, Cash, or Wire Transfer.</li>
<li><strong>Payment Date</strong> the date the payment was made or will be made.</li>
<li><strong>Reference Number</strong> check number, wire confirmation, or ACH batch ID. Always fill this in for non-cash payments to simplify reconciliation.</li>
<li><strong>Notes</strong> any additional information about this payment.</li>
<li><strong>Amount</strong> &mdash; how much you are paying now. Can be less than the full balance for partial payments.</li>
<li><strong>Payment Method</strong> &mdash; Check, ACH / Bank Transfer, Credit Card, Cash, or Wire Transfer.</li>
<li><strong>Payment Date</strong> &mdash; the date the payment was made or will be made.</li>
<li><strong>Reference Number</strong> &mdash; check number, wire confirmation, or ACH batch ID. Always fill this in for non-cash payments to simplify reconciliation.</li>
<li><strong>Notes</strong> &mdash; any additional information about this payment.</li>
</ul>
</li>
<li class="mb-2">Click <strong>Save Payment</strong>.</li>
@@ -197,7 +197,7 @@
<li class="mb-2">Go to <strong>Accounting &rsaquo; Bills</strong> and click <strong>Scan Receipt</strong>.</li>
<li class="mb-2">Upload a photo (JPG/PNG) or a PDF of the vendor's invoice.</li>
<li class="mb-2">The AI reads the document and pre-fills the vendor, bill date, line items, and amounts into a new draft bill.</li>
<li class="mb-2">Review the extracted data correct any fields that were misread and save the bill.</li>
<li class="mb-2">Review the extracted data &mdash; correct any fields that were misread &mdash; and save the bill.</li>
</ol>
<p>
The uploaded file is automatically attached to the bill so you always have the original
@@ -245,13 +245,13 @@
</p>
<ul class="mb-3">
<li class="mb-1"><strong>Vendor name</strong> and detected frequency (monthly, quarterly, biannual, annual).</li>
<li class="mb-1"><strong>Typical amount</strong> the usual charge from that vendor.</li>
<li class="mb-1"><strong>Next expected date</strong> Claude's estimate of when the next bill is likely to arrive.</li>
<li class="mb-1"><strong>Confidence badge</strong> High (4+ consistent occurrences), Medium (23 occurrences or variable timing), Low (weak pattern, worth monitoring).</li>
<li class="mb-1"><strong>Suggested action</strong> for example, "Set a monthly reminder for this bill."</li>
<li class="mb-1"><strong>Typical amount</strong> &mdash; the usual charge from that vendor.</li>
<li class="mb-1"><strong>Next expected date</strong> &mdash; Claude's estimate of when the next bill is likely to arrive.</li>
<li class="mb-1"><strong>Confidence badge</strong> &mdash; High (4+ consistent occurrences), Medium (2&ndash;3 occurrences or variable timing), Low (weak pattern, worth monitoring).</li>
<li class="mb-1"><strong>Suggested action</strong> &mdash; for example, "Set a monthly reminder for this bill."</li>
</ul>
<p>
This is useful for cash flow planning knowing that a $1,200 electricity bill arrives on the
This is useful for cash flow planning &mdash; knowing that a $1,200 electricity bill arrives on the
15th every month, or that your insurance renews every January, lets you reserve funds in advance
and avoid surprises. High-confidence patterns are reliable enough to act on; Low-confidence
patterns are worth keeping an eye on but should not be treated as certain.
@@ -261,7 +261,7 @@
<div>
Recurring bill detection requires at least 2 occurrences of a vendor bill at a similar
interval to detect a pattern. Shops with less than 2 months of history will see few or no
results. The scan covers bills only direct expenses are not included.
results. The scan covers bills only &mdash; direct expenses are not included.
</div>
</div>
</section>
@@ -271,17 +271,17 @@
<i class="bi bi-folder2-open text-primary me-2"></i>Expense Accounts
</h2>
<p>
Each line item on a bill must be assigned to an <strong>expense account</strong> an accounting
Each line item on a bill must be assigned to an <strong>expense account</strong> &mdash; an accounting
category that determines where the cost appears in your financial reports. Common expense accounts
used in a powder coating shop include:
</p>
<ul class="mb-3">
<li class="mb-1"><strong>Cost of Goods Sold (COGS)</strong> raw materials, powder coatings, and consumables that go directly into jobs.</li>
<li class="mb-1"><strong>Shop Supplies</strong> items used in the shop that are not directly tied to a specific job (masking tape, gloves, cleaning solvents).</li>
<li class="mb-1"><strong>Equipment Maintenance</strong> service, repairs, and parts for your oven, sandblaster, and coating booths.</li>
<li class="mb-1"><strong>Utilities</strong> gas, electricity, and water bills that power the shop.</li>
<li class="mb-1"><strong>Rent / Occupancy</strong> monthly rent or lease payments for your shop premises.</li>
<li class="mb-1"><strong>Operating Expenses</strong> general overhead that does not fit another specific category.</li>
<li class="mb-1"><strong>Cost of Goods Sold (COGS)</strong> &mdash; raw materials, powder coatings, and consumables that go directly into jobs.</li>
<li class="mb-1"><strong>Shop Supplies</strong> &mdash; items used in the shop that are not directly tied to a specific job (masking tape, gloves, cleaning solvents).</li>
<li class="mb-1"><strong>Equipment Maintenance</strong> &mdash; service, repairs, and parts for your oven, sandblaster, and coating booths.</li>
<li class="mb-1"><strong>Utilities</strong> &mdash; gas, electricity, and water bills that power the shop.</li>
<li class="mb-1"><strong>Rent / Occupancy</strong> &mdash; monthly rent or lease payments for your shop premises.</li>
<li class="mb-1"><strong>Operating Expenses</strong> &mdash; general overhead that does not fit another specific category.</li>
</ul>
<p>
The <strong>vendor's default expense account</strong> is set on the vendor record and pre-fills