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:
@@ -893,14 +893,19 @@ public class InvoicesController : Controller
|
||||
if (!string.IsNullOrEmpty(invoice.PaymentLinkToken))
|
||||
paymentUrl = $"{Request.Scheme}://{Request.Host}/pay/{invoice.PaymentLinkToken}";
|
||||
|
||||
bool pdfAndNotifSucceeded = false;
|
||||
try
|
||||
{
|
||||
var pdfBytes = await BuildInvoicePdfAsync(invoice, currentUser!.CompanyId);
|
||||
await _notificationService.NotifyInvoiceSentAsync(invoice, pdfBytes, $"Invoice-{invoice.InvoiceNumber}.pdf", paymentUrl);
|
||||
pdfAndNotifSucceeded = true;
|
||||
}
|
||||
catch (Exception notifyEx)
|
||||
{
|
||||
_logger.LogWarning(notifyEx, "Invoice sent but notification failed for invoice {Id}", id);
|
||||
_logger.LogError(notifyEx,
|
||||
"Invoice {InvoiceId} ({InvoiceNumber}): PDF generation or email dispatch failed. " +
|
||||
"Inner: {InnerMessage}. Invoice status was already saved as Sent.",
|
||||
id, invoice.InvoiceNumber, notifyEx.InnerException?.Message ?? "none");
|
||||
}
|
||||
|
||||
var notifLog = await _context.NotificationLogs
|
||||
@@ -911,6 +916,8 @@ public class InvoicesController : Controller
|
||||
this.SetNotificationResultToast(notifLog);
|
||||
|
||||
TempData["Success"] = $"Invoice {invoice.InvoiceNumber} marked as sent.";
|
||||
if (!pdfAndNotifSucceeded)
|
||||
TempData["Warning"] = "The invoice is marked as sent, but PDF generation or the customer email failed. Check the notification logs or your email configuration.";
|
||||
return RedirectToAction(nameof(Details), new { id });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user