Fix passkey login tracking, add email opt-out UI guards, and add Quick/Full quote mode toggle

- PasskeyController: set LastLoginDate on passkey sign-in so Company Health
  and audit pages show accurate last-login times (was always showing 'Never')
- Jobs/Index status modal: disable 'Notify customer' email toggle and show
  warning when customer has notifications turned off; CustomerNotifyByEmail
  added to JobListDto + JobProfile mapping + data-customer-notify attribute
- Quotes/Create: disable 'Send quote via email' checkbox with 'Notifications
  off' badge when selected customer has email opt-out; ViewBag.CustomerEmailOptOutIds
  added alongside existing CustomerTaxExemptIds pattern
- Quotes/Create: Quick Quote / Full Quote segmented toggle at top of form;
  hides non-essential fields (dates, notes, tags, oven, discount, photos) in
  Quick mode; selection persisted in localStorage
- InvoicesController Send action: improved error logging and user-facing
  warning when PDF generation or email dispatch fails after status is saved
- item-wizard.js: guard item restoration with try/catch; ensure writeHiddenFields
  always runs on form submit via capture-phase listener
- Help docs and AI knowledge base updated for all new features

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-27 13:32:34 -04:00
parent 0ea192d55b
commit cad728ba66
11 changed files with 194 additions and 18 deletions
@@ -77,6 +77,11 @@
(waiting for customer approval, missing materials, etc.) and Cancelled to formally close a job that
will not be completed.
</p>
<p>
On the Jobs list, click any status badge to open a quick-change modal. The modal includes a
<strong>Notify customer via email</strong> toggle. If the customer has email notifications turned off,
that toggle is automatically disabled and a warning note is shown — no email will be sent regardless.
</p>
<div class="table-responsive">
<table class="table table-sm table-bordered mb-0">
@@ -40,6 +40,28 @@
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
<i class="bi bi-plus-circle text-primary me-2"></i>Creating a Quote
</h2>
<h3 class="h6 fw-semibold mt-0 mb-2"><i class="bi bi-lightning me-1 text-primary"></i>Quick Quote vs Full Quote</h3>
<p>
The quote form offers two modes, selectable via the <strong>Quick Quote / Full Quote</strong> toggle at the
top of the page. Your selection is remembered automatically for next time.
</p>
<ul class="mb-3">
<li class="mb-1"><strong>Quick Quote</strong> — shows only the essentials: customer picker (or walk-in info) and
the item wizard. Dates, notes, tags, oven settings, discounts, and photos are hidden. Use this for
fast phone or counter estimates where you just need a price.</li>
<li class="mb-1"><strong>Full Quote</strong> — shows the complete form with all fields. Use this for formal
quotes where you want to capture notes, set an expiry date, apply a discount, or add photos.</li>
</ul>
<div class="alert alert-permanent alert-info d-flex gap-2 mb-3" role="alert">
<i class="bi bi-lightbulb-fill flex-shrink-0 mt-1"></i>
<div>
Switching to Quick Quote does not change how the quote saves — all pricing calculations and the item
wizard work exactly the same. Hidden fields use their default values (no rush fee, no discount, company
default tax rate).
</div>
</div>
<p>To create a new quote:</p>
<ol class="mb-3">
<li class="mb-2">Go to <strong>Operations &rsaquo; Quotes</strong> and click <strong>New Quote</strong>.</li>
@@ -251,6 +273,16 @@
<li class="mb-2">Click <strong>Send Quote</strong>. The status changes from Draft to Sent.</li>
<li class="mb-2">If email notifications are configured for your company, the customer will automatically receive an email with the quote details.</li>
</ol>
<div class="alert alert-permanent alert-warning d-flex gap-2 mb-3" role="alert">
<i class="bi bi-bell-slash flex-shrink-0 mt-1"></i>
<div>
<strong>Customer notifications off:</strong> If a customer has email notifications turned off, the
<strong>Send quote via email</strong> checkbox on the Create page is automatically disabled and marked
with a <em>Notifications off</em> badge. The Send button on the Details page is also disabled.
To re-enable emails for this customer, open their record and turn on <strong>Notify by Email</strong>
under their contact settings.
</div>
</div>
<p>
You can also manually mark a quote as <strong>Approved</strong> or <strong>Rejected</strong> when
you hear back from the customer verbally or by phone, without going through a formal email send.