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,
|
InvoiceSent = 6,
|
||||||
PaymentReceived = 7,
|
PaymentReceived = 7,
|
||||||
QuoteDeclinedByCustomer = 8,
|
QuoteDeclinedByCustomer = 8,
|
||||||
|
QuoteApprovedByCustomer = 16,
|
||||||
PaymentReminder = 9,
|
PaymentReminder = 9,
|
||||||
SubscriptionExpiryReminder = 10,
|
SubscriptionExpiryReminder = 10,
|
||||||
SubscriptionExpired = 11,
|
SubscriptionExpired = 11,
|
||||||
|
|||||||
@@ -977,6 +977,28 @@ New accounts walk through an 18-step setup wizard to configure company informati
|
|||||||
CompanyId = companyId,
|
CompanyId = companyId,
|
||||||
CreatedAt = DateTime.UtcNow
|
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} APPROVED — {customerName}"
|
||||||
: $"Quote {quote.QuoteNumber} DECLINED — {customerName}";
|
: $"Quote {quote.QuoteNumber} DECLINED — {customerName}";
|
||||||
|
|
||||||
|
var notificationType = approved
|
||||||
|
? NotificationType.QuoteApprovedByCustomer
|
||||||
|
: NotificationType.QuoteDeclinedByCustomer;
|
||||||
|
|
||||||
var (subject, htmlBody) = await GetRenderedEmailAsync(
|
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 fullHtml = AppendUnsubscribeFooterHtml(htmlBody, token: null, company, await GetBaseUrlAsync());
|
||||||
var plainText = StripHtml(fullHtml);
|
var plainText = StripHtml(fullHtml);
|
||||||
@@ -913,7 +917,7 @@ public class NotificationService : INotificationService
|
|||||||
await WriteLog(new NotificationLog
|
await WriteLog(new NotificationLog
|
||||||
{
|
{
|
||||||
Channel = NotificationChannel.Email,
|
Channel = NotificationChannel.Email,
|
||||||
NotificationType = NotificationType.QuoteDeclinedByCustomer,
|
NotificationType = notificationType,
|
||||||
Status = success ? NotificationStatus.Sent : NotificationStatus.Failed,
|
Status = success ? NotificationStatus.Sent : NotificationStatus.Failed,
|
||||||
RecipientName = companyName,
|
RecipientName = companyName,
|
||||||
Recipient = companyEmail,
|
Recipient = companyEmail,
|
||||||
@@ -1133,6 +1137,10 @@ public class NotificationService : INotificationService
|
|||||||
"Payment Received — Invoice {{invoiceNumber}}",
|
"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>"
|
"<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)] = (
|
[(NotificationType.QuoteDeclinedByCustomer, NotificationChannel.Email)] = (
|
||||||
"Customer Response: Quote {{quoteNumber}} — {{companyName}}",
|
"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>"
|
"<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
|
// Quote types
|
||||||
if (type is NotificationType.QuoteSent or NotificationType.QuoteApproved
|
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)"));
|
list.Add(("{{quoteNumber}}", "Quote number (e.g. QT-2501-0001)"));
|
||||||
|
|
||||||
if (type == NotificationType.QuoteSent)
|
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"));
|
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\""));
|
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"));
|
list.Add(("{{declineReasonSection}}", "HTML block containing the decline reason — blank when the customer approved"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user