using PowderCoating.Core.Entities; namespace PowderCoating.Application.Interfaces; public interface INotificationService { /// /// Notify when a quote is created/sent. Handles both registered customers and prospects. /// Optionally attaches the quote PDF to the email. /// Task NotifyQuoteSentAsync(Quote quote, byte[]? pdfAttachment = null, string? pdfFilename = null, string? overrideEmail = null); /// /// Sends the quote approval link to the customer via SMS. /// Handles both registered customers (respects NotifyBySms) and prospects (ProspectPhone). /// Returns (success, errorMessage) so the caller can surface the result to the user. /// Task<(bool Success, string? Error)> NotifyQuoteSentSmsAsync(Quote quote); /// /// Notify when a quote is approved by a customer. /// Task NotifyQuoteApprovedAsync(Quote quote); /// /// Notify customer of a job status change. Also sends SMS when status is READY_FOR_PICKUP. /// Task NotifyJobStatusChangedAsync(Job job, string newStatusCode, string newStatusDisplayName); /// /// Notify customer when a job is completed and ready for pickup. /// When is true the SMS is skipped so an admin can review /// the message via before sending manually. /// Task NotifyJobCompletedAsync(Job job, bool suppressSms = false); /// /// Renders the job-completed SMS text for admin preview without sending it. /// Returns null when SMS is not allowed for the company or the customer has not opted in. /// Task RenderJobCompletedSmsAsync(Job job); /// /// Sends a manually-composed SMS for a job (Admin/Manager compose-before-send path). /// Appends "Reply STOP to opt out." if not already present, sends, and writes a NotificationLog row. /// Returns (success, errorMessage). /// Task<(bool Success, string? Error)> SendJobSmsAsync(Job job, string message); /// /// Sends a welcome/confirmation SMS after staff records verbal SMS consent. /// This message confirms enrollment and provides opt-out instructions per CTIA guidelines. /// Task NotifySmsConsentGrantedAsync(Customer customer); /// /// Notify customer when an invoice has been sent. /// Optionally includes an online payment link in the email body. /// Task NotifyInvoiceSentAsync(Invoice invoice, byte[]? pdfAttachment = null, string? pdfFilename = null, string? paymentUrl = null, string? overrideEmail = null, bool sendSms = false, string? viewUrl = null); /// /// Notify customer (internal) when a payment has been recorded on an invoice. /// Task NotifyPaymentReceivedAsync(Invoice invoice, Payment payment); /// /// Notify the company (internal) when a customer approves or declines a quote via the self-service portal. /// Task NotifyQuoteActedByCustomerAsync(Quote quote, bool approved, string? declineReason); /// /// Send a payment reminder to the customer for an overdue invoice. /// /// The overdue invoice (must have Customer loaded or CustomerId set). /// Number of days since the invoice was due. Task NotifyPaymentReminderAsync(Invoice invoice, int daysOverdue); /// /// Send an online payment receipt to the customer after a successful Stripe payment. /// Task NotifyOnlinePaymentReceivedAsync(Invoice invoice, decimal amountPaid, decimal surchargePaid, string paymentIntentId); /// /// Notify the company (internal) when a customer pays a deposit online for a quote. /// Task NotifyDepositReceivedAsync(Quote quote, decimal amountPaid, decimal surchargePaid, string paymentIntentId); /// /// Alert company staff when a Stripe chargeback (dispute) is opened on an invoice payment. /// Task NotifyChargebackAlertAsync(Invoice invoice, string disputeId, decimal amount, string reason); }