From f34ee749be025a2052b1956ea635e00ee70870eb Mon Sep 17 00:00:00 2001 From: Scott Pouliot Date: Thu, 14 May 2026 18:54:35 -0400 Subject: [PATCH] Fix garbled encoding symbols in oven display, bill/invoice tooltips, and profile timezone dropdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace mojibake × with × in oven batch cost row across Jobs Create/Edit/EditItems and Quotes Create/Edit - Fix Qty × Unit Price tooltip in Bills/Edit and Invoices/Edit - Fix all â€" (garbled em dash) and São Paulo in Profile timezone dropdown option labels Co-Authored-By: Claude Sonnet 4.6 --- src/PowderCoating.Web/Views/Bills/Edit.cshtml | 18 +++--- .../Views/Invoices/Edit.cshtml | 6 +- .../Views/Jobs/Create.cshtml | 14 ++--- src/PowderCoating.Web/Views/Jobs/Edit.cshtml | 10 ++-- .../Views/Jobs/EditItems.cshtml | 4 +- .../Views/Profile/Index.cshtml | 56 +++++++++---------- .../Views/Quotes/Create.cshtml | 22 ++++---- .../Views/Quotes/Edit.cshtml | 26 ++++----- 8 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/PowderCoating.Web/Views/Bills/Edit.cshtml b/src/PowderCoating.Web/Views/Bills/Edit.cshtml index 69b4eff..af3317b 100644 --- a/src/PowderCoating.Web/Views/Bills/Edit.cshtml +++ b/src/PowderCoating.Web/Views/Bills/Edit.cshtml @@ -4,7 +4,7 @@ ViewData["Title"] = "Edit Bill"; ViewData["PageIcon"] = "bi-pencil-square"; ViewData["PageHelpTitle"] = "Edit Bill"; - ViewData["PageHelpContent"] = "Bills can only be edited while in Draft status. Once marked Open, they are locked — Void the bill and recreate it if corrections are needed after confirmation."; + ViewData["PageHelpContent"] = "Bills can only be edited while in Draft status. Once marked Open, they are locked — Void the bill and recreate it if corrections are needed after confirmation."; } @@ -34,8 +34,8 @@
@@ -87,7 +87,7 @@ } -
JPG, PNG, GIF, WebP, or PDF — up to 10 MB.
+
JPG, PNG, GIF, WebP, or PDF — up to 10 MB.
@@ -100,7 +100,7 @@ + data-bs-content="Each line maps to an expense account (e.g. Supplies, Materials, Subcontractors). Optionally link a line to a Job to track costs against specific work orders. Qty × Unit Price = Amount. Use multiple lines to split one bill across different expense categories."> @@ -134,7 +134,7 @@ + data-bs-content="Tax % is applied to the line-item subtotal. The resulting Total is the full amount owed to the vendor. Partial payments are allowed — each payment recorded reduces the balance due until the bill is fully paid."> @@ -171,7 +171,7 @@ - - - - - - - + + + + + + + - - - - - + + + + + - - - - + + + + - - - - - - - + + + + + + + - - + + @@ -538,7 +538,7 @@ }); }); - // Theme radio — map light/dark → paper/ink surface system + // Theme radio â€" map light/dark → paper/ink surface system document.querySelectorAll('input[name="theme"]').forEach(radio => { radio.addEventListener('change', function () { var surface = this.value === 'dark' ? 'ink' : 'paper'; diff --git a/src/PowderCoating.Web/Views/Quotes/Create.cshtml b/src/PowderCoating.Web/Views/Quotes/Create.cshtml index 95db190..011e52c 100644 --- a/src/PowderCoating.Web/Views/Quotes/Create.cshtml +++ b/src/PowderCoating.Web/Views/Quotes/Create.cshtml @@ -51,7 +51,7 @@ + data-bs-content="Choose <strong>Existing Customer</strong> if this person is already in your system. Choose <strong>New Prospect/Walk-In</strong> if they haven't committed yet — their details stay on the quote. When they approve, you can convert them to a full customer record with one click.<br><br><a href='/Help/Quotes#prospect-conversion' target='_blank'>Learn more →</a>"> @@ -146,7 +146,7 @@ + data-bs-content="Set the quote date, expiration, and any internal notes. The <strong>Expiration Date</strong> is shown to the customer — once it passes the quote is flagged Expired and can no longer be approved without editing. The <strong>Customer PO</strong> field is optional — use it if the customer provides their own purchase order number.<br><br><a href='/Help/Quotes#quote-statuses' target='_blank'>Learn more →</a>"> @@ -210,7 +210,7 @@ + data-bs-content="The oven cost is charged once per batch at the quote level, not per item. Estimate how many oven loads the full job will fill — for example, if you have 20 small parts and your oven fits 10, that's 2 batches. Cycle time is how long each batch runs. The cost is calculated from your oven's hourly rate in Settings."> @@ -253,7 +253,7 @@ + data-bs-content="<strong>Calculated</strong> — you enter surface area (sq ft) and the system prices it using your rates for materials, labour, and overhead.<br><strong>Custom Work</strong> — you enter a description and a manual price. Use this for flat-rate jobs or work that doesn't fit the formula.<br><strong>AI Photo</strong> — upload photos and let the AI estimate surface area and complexity for you.<br><br><a href='/Help/Quotes#quote-items' target='_blank'>Learn more →</a>"> @@ -314,7 +314,7 @@
@@ -329,7 +329,7 @@ + data-bs-content="The total is built up from materials, labour, equipment time, overhead, and profit margin — all based on the rates in Settings. A <strong>Tier Discount</strong> appears automatically if the customer has a pricing tier assigned. A <strong>Rush Fee</strong> is added when Rush Job is checked.<br><br><a href='/Help/Quotes#pricing-breakdown' target='_blank'>Learn more →</a>"> @@ -340,7 +340,7 @@

Pricing will update automatically as you add items.

Items Subtotal: $0.00

- Oven (1 batch × 45 min): + Oven (1 batch × 45 min): $0.00

@@ -379,7 +379,7 @@

- Uploading… + Uploading…
@@ -560,7 +560,7 @@ function applyMode(mode) { if (mode === 'simple') { form.classList.add('quote-simple-mode'); - hint.textContent = 'Advanced fields are hidden — switch to Full Quote to see them.'; + hint.textContent = 'Advanced fields are hidden — switch to Full Quote to see them.'; } else { form.classList.remove('quote-simple-mode'); hint.textContent = ''; @@ -628,8 +628,8 @@ smsNote.style.display = 'inline'; smsNote.className = hasSms ? 'badge bg-info text-white' : 'badge bg-warning text-dark'; smsNote.innerHTML = hasSms - ? 'No email — send via SMS from quote details' - : 'No email — SMS consent required'; + ? 'No email — send via SMS from quote details' + : 'No email — SMS consent required'; } else { smsNote.style.display = 'none'; } diff --git a/src/PowderCoating.Web/Views/Quotes/Edit.cshtml b/src/PowderCoating.Web/Views/Quotes/Edit.cshtml index 56b211e..4e49336 100644 --- a/src/PowderCoating.Web/Views/Quotes/Edit.cshtml +++ b/src/PowderCoating.Web/Views/Quotes/Edit.cshtml @@ -109,7 +109,7 @@ + data-bs-content="Set the quote date, expiration, and any internal notes. The <strong>Expiration Date</strong> is shown to the customer — once it passes the quote is flagged Expired and can no longer be approved without editing. The <strong>Customer PO</strong> field is optional — use it if the customer provides their own purchase order number.<br><br><a href='/Help/Quotes#quote-statuses' target='_blank'>Learn more →</a>"> @@ -173,7 +173,7 @@ + data-bs-content="The oven cost is charged once per batch at the quote level, not per item. Estimate how many oven loads the full job will fill — for example, if you have 20 small parts and your oven fits 10, that's 2 batches. Cycle time is how long each batch runs. The cost is calculated from your oven's hourly rate in Settings."> @@ -216,7 +216,7 @@ + data-bs-content="<strong>Calculated</strong> — you enter surface area (sq ft) and the system prices it using your rates for materials, labour, and overhead.<br><strong>Custom Work</strong> — you enter a description and a manual price. Use this for flat-rate jobs or work that doesn't fit the formula.<br><strong>AI Photo</strong> — upload photos and let the AI estimate surface area and complexity for you.<br><br><a href='/Help/Quotes#quote-items' target='_blank'>Learn more →</a>"> @@ -277,7 +277,7 @@
@@ -292,7 +292,7 @@ + data-bs-content="The total is built up from materials, labour, equipment time, overhead, and profit margin — all based on the rates in Settings. A <strong>Tier Discount</strong> appears automatically if the customer has a pricing tier assigned. A <strong>Rush Fee</strong> is added when Rush Job is checked.<br><br><a href='/Help/Quotes#pricing-breakdown' target='_blank'>Learn more →</a>"> @@ -303,7 +303,7 @@

Pricing will update automatically as you add items.

Items Subtotal: $0.00

- Oven (1 batch × 45 min): + Oven (1 batch × 45 min): $0.00

@@ -407,7 +407,7 @@

- Uploading… + Uploading…
@@ -435,11 +435,11 @@ @if (editHasSms) { - No email — send via SMS from quote details + No email — send via SMS from quote details } else { - No email — SMS consent required + No email — SMS consent required } } @@ -488,7 +488,7 @@ @Html.Raw(Json.Serialize(ViewBag.BlastSetups ?? new List())) - +