Add QuoteApprovedByCustomer notification type; fix wrong type logged on approval
QuoteDeclinedByCustomer was used for both approve and decline responses, so approval notifications showed the wrong type in the log. Added a distinct QuoteApprovedByCustomer = 16 enum value, wired up the correct type in NotificationService, added default templates in both the service fallback dictionary and SeedData, and updated placeholder hints in CompanySettings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ public enum NotificationType
|
||||
InvoiceSent = 6,
|
||||
PaymentReceived = 7,
|
||||
QuoteDeclinedByCustomer = 8,
|
||||
QuoteApprovedByCustomer = 16,
|
||||
PaymentReminder = 9,
|
||||
SubscriptionExpiryReminder = 10,
|
||||
SubscriptionExpired = 11,
|
||||
|
||||
@@ -977,6 +977,28 @@ New accounts walk through an 18-step setup wizard to configure company informati
|
||||
CompanyId = companyId,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
},
|
||||
new NotificationTemplate
|
||||
{
|
||||
NotificationType = NotificationType.QuoteApprovedByCustomer,
|
||||
Channel = NotificationChannel.Email,
|
||||
DisplayName = "Quote Approved by Customer (Internal)",
|
||||
Subject = "Customer Response: Quote {{quoteNumber}} — {{companyName}}",
|
||||
Body = "<p>Hello,</p><p>A customer has responded to quote <strong>{{quoteNumber}}</strong>.</p><p><strong>Customer:</strong> {{customerName}}<br/><strong>Response:</strong> {{response}}</p><p>Log in to the portal to review and follow up.</p>",
|
||||
IsActive = true,
|
||||
CompanyId = companyId,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
},
|
||||
new NotificationTemplate
|
||||
{
|
||||
NotificationType = NotificationType.QuoteDeclinedByCustomer,
|
||||
Channel = NotificationChannel.Email,
|
||||
DisplayName = "Quote Declined by Customer (Internal)",
|
||||
Subject = "Customer Response: Quote {{quoteNumber}} — {{companyName}}",
|
||||
Body = "<p>Hello,</p><p>A customer has responded to quote <strong>{{quoteNumber}}</strong>.</p><p><strong>Customer:</strong> {{customerName}}<br/><strong>Response:</strong> {{response}}</p>{{declineReasonSection}}<p>Log in to the portal to review and follow up.</p>",
|
||||
IsActive = true,
|
||||
CompanyId = companyId,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -900,8 +900,12 @@ public class NotificationService : INotificationService
|
||||
? $"Quote {quote.QuoteNumber} APPROVED — {customerName}"
|
||||
: $"Quote {quote.QuoteNumber} DECLINED — {customerName}";
|
||||
|
||||
var notificationType = approved
|
||||
? NotificationType.QuoteApprovedByCustomer
|
||||
: NotificationType.QuoteDeclinedByCustomer;
|
||||
|
||||
var (subject, htmlBody) = await GetRenderedEmailAsync(
|
||||
quote.CompanyId, NotificationType.QuoteDeclinedByCustomer, values, defaultSubject);
|
||||
quote.CompanyId, notificationType, values, defaultSubject);
|
||||
|
||||
var fullHtml = AppendUnsubscribeFooterHtml(htmlBody, token: null, company, await GetBaseUrlAsync());
|
||||
var plainText = StripHtml(fullHtml);
|
||||
@@ -913,7 +917,7 @@ public class NotificationService : INotificationService
|
||||
await WriteLog(new NotificationLog
|
||||
{
|
||||
Channel = NotificationChannel.Email,
|
||||
NotificationType = NotificationType.QuoteDeclinedByCustomer,
|
||||
NotificationType = notificationType,
|
||||
Status = success ? NotificationStatus.Sent : NotificationStatus.Failed,
|
||||
RecipientName = companyName,
|
||||
Recipient = companyEmail,
|
||||
@@ -1133,6 +1137,10 @@ public class NotificationService : INotificationService
|
||||
"Payment Received — Invoice {{invoiceNumber}}",
|
||||
"<p>Dear {{customerName}},</p><p>We have received your payment of <strong>{{paymentAmount}}</strong> on {{paymentDate}} for invoice <strong>{{invoiceNumber}}</strong>.{{balanceDue}}</p><p>Thank you for your business with {{companyName}}.</p>"
|
||||
),
|
||||
[(NotificationType.QuoteApprovedByCustomer, NotificationChannel.Email)] = (
|
||||
"Customer Response: Quote {{quoteNumber}} — {{companyName}}",
|
||||
"<p>Hello,</p><p>A customer has responded to quote <strong>{{quoteNumber}}</strong>.</p><p><strong>Customer:</strong> {{customerName}}<br/><strong>Response:</strong> {{response}}</p><p>Log in to the portal to review and follow up.</p>"
|
||||
),
|
||||
[(NotificationType.QuoteDeclinedByCustomer, NotificationChannel.Email)] = (
|
||||
"Customer Response: Quote {{quoteNumber}} — {{companyName}}",
|
||||
"<p>Hello,</p><p>A customer has responded to quote <strong>{{quoteNumber}}</strong>.</p><p><strong>Customer:</strong> {{customerName}}<br/><strong>Response:</strong> {{response}}</p>{{declineReasonSection}}<p>Log in to the portal to review and follow up.</p>"
|
||||
|
||||
@@ -2610,7 +2610,7 @@ public class CompanySettingsController : Controller
|
||||
|
||||
// Quote types
|
||||
if (type is NotificationType.QuoteSent or NotificationType.QuoteApproved
|
||||
or NotificationType.QuoteDeclinedByCustomer)
|
||||
or NotificationType.QuoteApprovedByCustomer or NotificationType.QuoteDeclinedByCustomer)
|
||||
list.Add(("{{quoteNumber}}", "Quote number (e.g. QT-2501-0001)"));
|
||||
|
||||
if (type == NotificationType.QuoteSent)
|
||||
@@ -2620,9 +2620,13 @@ public class CompanySettingsController : Controller
|
||||
list.Add(("{{approvalUrl}}", "Unique URL for the customer to view and approve the quote online"));
|
||||
}
|
||||
|
||||
if (type == NotificationType.QuoteDeclinedByCustomer)
|
||||
if (type is NotificationType.QuoteApprovedByCustomer or NotificationType.QuoteDeclinedByCustomer)
|
||||
{
|
||||
list.Add(("{{response}}", "Customer's response — either \"APPROVED\" or \"DECLINED\""));
|
||||
}
|
||||
|
||||
if (type == NotificationType.QuoteDeclinedByCustomer)
|
||||
{
|
||||
list.Add(("{{declineReasonSection}}", "HTML block containing the decline reason — blank when the customer approved"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user