# Email catalog Discovery date: 2026-11-02. Source: the local simple-api-postgresql working tree, including existing uncommitted changes. This is a static source audit. A referenced sender is evidence of intended use, not proof that email reaches recipients in production. Laravel was not booted; no database, environment file, mail transport, live token, or recipient dataset was accessed. Literal email addresses are omitted from this catalog. Work is isolated in built-email-redesign, the location explicitly requested for this draft. No production template or sender was changed. The user confirmed invoice and new sign-in alert, Built navy/yellow, and Built-led styling on 2026-11-02. Merchant invoice_color is reserved for a later secondary treatment. ## How to read this catalog - **Referenced** means an executable-looking project call constructs the exact imported Mailable or directly names the view. It does not establish route reachability, enabled configuration, queue workers, provider acceptance or delivery. - **Apparently unused** means no executable construction/reference was found in the inspected project PHP. Dynamic invocation outside the repository remains possible. - **Unresolved** means a missing view, incomplete binding, external sender, or untraced job dispatch prevents a stronger conclusion. - Queueable is a trait, not proof of queueing. Each entry records queue() calls, send() calls, and ShouldQueue separately. The configured bank_api transport can add an asynchronous outbox below either Laravel call style. - Data expressions below are source variable names, not real recipient values. Links are source expressions, not links to execute. ## Delivery architecture and boundaries Laravel 12 Mailables use markdown(), view(), and Content definitions. config/mail.php selects MAIL_MAILER or MAIL_DRIVER with a mailgun fallback, and registers SMTP, Mailgun, SES, Postmark, Resend, sendmail, logging/array and custom bank_api options. Runtime transport configuration was not inspected. config/beautymail.php retains older styling configuration, but no active BeautyMail sending call was found. app/Http/Repository/MailChimp.php manages marketing contacts; this does not establish a project-owned campaign email template. app/Providers/BankMailServiceProvider.php registers bank_api. app/Mail/BankApi/BankApiOutboxTransport.php stores messages and attachment objects, then dispatches recipients through BankMailOutboxDispatcher and queued DeliverBankMailRecipient jobs. DispatchPendingBankMail recovers pending recipients. BankApiMessageMapper prefers HTML and falls back to text, and the transport explicitly drops CC, BCC and Reply-To. This matters because many Mailables request these headers. No configured runtime schedule for this recovery command was found in bootstrap/app.php or routes/console.php. app/EmailHelper.php posts rendered HTML to the configured external scheduler /api/send-bulk-emails. ImportEmployeesBulkJob uses this for employee welcomes. External scheduler templates and delivery are outside this repository's evidence. Invoice-created/paid/deleted/reminder-deactivated events notify the scheduler through listeners; InvoiceWasCreated and QuoteWasCreated create action links, rather than sending email themselves. URLVisted is an actual invoice-open notification sender. No project class extending Laravel Notification or implementing toMail() was found under app. App\Notification, AppliedNotification, ItemNotification and WalletNotification are models used for in-app/database state; their existence does not make them emails. SMS/push/WebSocket calls are excluded. TwoFactorAuthentication chooses an email code for non-phone identifiers and a separate phone/SMS path otherwise. Framework email verification is registered through Registered -> SendEmailVerificationNotification (app/Providers/EventServiceProvider.php), and verification routes/controllers are present. User does not declare MustVerifyEmail, so automatic registration delivery is unresolved. The verification-notification controller directly calls the framework method. PasswordResetLinkController calls Password::sendResetLink, but the corresponding reset-request routes are commented in routes/auth.php; distinguish this framework path from the referenced custom API passwordReset Mailable. Neither framework path owns an individual project email view. config/backup.php selects mail for five package backup/cleanup/health notifications; package bodies are excluded from the project-owned catalog. ## Shared rendering and plain text config/mail.php points Markdown rendering at resources/views/vendor/mail. Despite the vendor directory name, these checked-in overrides are relevant project rendering dependencies. html/message.blade.php adds the Built logo, product tagline and mobile app promotion. html/layout, header, footer, panel, button, promotion, subcopy and table plus html/themes/default.css form the shared HTML layer. The corresponding text/* components form the Markdown text layer. These are components, not separate notification types. Full HTML embedded in Markdown views needs separate text-output review; do not assume every generated text part is useful. No selected Mailable has a dedicated ->text() alternative. Legacy mails/* views extend mailtemplate::emails.default/blitz/campaign. That namespace is not established by a dependency in composer.json or a project registration found in this scan; rendering of these legacy paths is unresolved. Project-owned welcomeWallet and welcomeWallet_plain_text under resources/views/vendor/maileclipse/templates are retained below; stock public/vendor/maileclipse example assets and vendor package examples are excluded. ## Mailable index | Implementation | Purpose | Static status | Queue evidence | | --- | --- | --- | --- | | [AccountantInvite](#accountantinvite) | Invite an accountant to collaborate with a business. | referenced | queued | | [AffiliateAccountCreated](#affiliateaccountcreated) | Confirm affiliate creation and provide a shareable referral link. | referenced | send | | [AffiliateInvite](#affiliateinvite) | Invite a referral to sign up using an affiliate code. | referenced | queued | | [BankTopupCode](#banktopupcode) | Send bank top-up details and an authorization code to internal finance. | referenced | send | | [CancelSubscription](#cancelsubscription) | Confirm cancellation and downgrade to the basic plan. | referenced | queued | | [CardCreatedNotification](#cardcreatednotification) | Confirm virtual card creation and prompt expense classification. | referenced | send | | [ChangeInvite](#changeinvite) | Notify a collaborator that their business roles changed. | referenced | queued | | [CrmAccountCreatedMail](#crmaccountcreatedmail) | Notify internal staff of a CRM signup. | referenced | send | | [CrmAccountUpdatedMail](#crmaccountupdatedmail) | Notify internal staff of a CRM sender-ID change. | referenced | send | | [CustomerInvite](#customerinvite) | Invite a customer to sign up through a referral. | apparently unused | none found | | [DepositTransaction](#deposittransaction) | Send a deposit transaction receipt with PDF. | referenced | queued | | [DeveloperAccountCreatedMail](#developeraccountcreatedmail) | Notify internal staff of a developer signup. | referenced | ShouldQueue; send | | [FailedSubscription](#failedsubscription) | Notify internal staff of an undefined automatic subscription type during successful collection handling. | referenced | send | | [FloatingMail](#floatingmail) | Send stock audit report attachments. | apparently unused | none found | | [FundsRequestConfirmation](#fundsrequestconfirmation) | Confirm loan application submission to the applicant. | referenced | queued | | [GetStarted](#getstarted) | Introduce Built after signup and link to the dashboard. | referenced | send | | [GrantPayroll](#grantpayroll) | Notify a collaborator that payroll access was granted. | referenced | queued | | [ImportCompleted](#importcompleted) | Confirm CRM contact import completion. | referenced | ShouldQueue; queued | | [ImportFailed](#importfailed) | Report CRM contact import failure and its reason. | referenced | ShouldQueue; queued | | [InfoMail](#infomail) | Carry product-import success and failure messages in a shared body template. | referenced | ShouldQueue; send | | [InsuranceClaimStatusChanged](#insuranceclaimstatuschanged) | Notify a claimant of a status transition, including cancellation reason. | referenced | queued | | [InsuranceClaimSubmitted](#insuranceclaimsubmitted) | Acknowledge an insurance claim to the customer and internal staff. | referenced | queued | | [InsuranceOrderConfirmed](#insuranceorderconfirmed) | Send purchase details to the insurance provider. | referenced | queued | | [InsuranceOrderCreated](#insuranceordercreated) | Acknowledge insurance order creation to the customer and internal staff. | referenced | queued | | [InsuranceOrderStatusChanged](#insuranceorderstatuschanged) | Notify a customer of order cancellation, completion, or another status change. | referenced | queued | | [InsurancePolicyClosed](#insurancepolicyclosed) | Explain insurance policy closure. | referenced | queued | | [InviteConfirmation](#inviteconfirmation) | Tell business administrators that an invitation was accepted. | referenced | queued | | [InvoiceDiscountRequestMail](#invoicediscountrequestmail) | Send an invoice-discounting request to internal staff. | referenced | send | | [LinkVisitedNotification](#linkvisitednotification) | Notify a business user that an invoice link was visited. | referenced | send | | [ManagementReportMail](#managementreportmail) | Share a management report and its PDF with chosen recipients. | referenced | queued | | [MultipleInvoicesCreatedMail](#multipleinvoicescreatedmail) | Report bulk invoice creation success or partial failure. | referenced | queued | | [NsanoStatus](#nsanostatus) | Provide a payment-provider status message. | apparently unused | none found | | [OverdraftRequestMail](#overdraftrequestmail) | Send an overdraft request to internal finance. | referenced | send | | [PaymentError](#paymenterror) | Report transfer failure with an optional retry action. | referenced | queued | | [PaymentLimit](#paymentlimit) | Report a transfer limit/provider failure after successful collection. | apparently unused | none found | | [PaymentLinkReciept](#paymentlinkreciept) | Send a payment-link transaction receipt to the payer. | referenced | send | | [Receipt](#receipt) | Send an invoice payment receipt and PDF. | referenced | queued | | [ReportGenerated](#reportgenerated) | Tell the requesting user that a management report is ready. | referenced | ShouldQueue; queued | | [ReportGenerationFailed](#reportgenerationfailed) | Tell the requesting user that management report generation failed. | referenced | ShouldQueue; queued | | [RequestFunds](#requestfunds) | Send loan application details to the service provider. | referenced | queued | | [ResetPassword](#resetpassword) | Scaffold password-reset template with no established sending call. | apparently unused | none found | | [SendLinkEmail](#sendlinkemail) | Request a payment using the business wallet payment link. | referenced | send | | [SendManualInvoiceReminder](#sendmanualinvoicereminder) | Send a user-composed invoice reminder with a caller-supplied subject. | referenced | queued | | [SendNewLoginNotification](#sendnewloginnotification) | Warn the user of a sign-in from a new device and offer password reset. | referenced | send | | [SubscriptionWillExpire](#subscriptionwillexpire) | Legacy scheduled-delivery experiment for subscription expiry. | apparently unused | none found | | [SupplierInvite](#supplierinvite) | Invite a supplier to sign up using a referral code. | apparently unused | none found | | [TestEmail](#testemail) | Unused test scaffold referencing a placeholder view. | unresolved | none found | | [TestMail](#testmail) | Test message wrapper. | apparently unused | none found | | [TokenRecievedMail](#tokenrecievedmail) | Deliver an electricity/network token after wallet purchase. | referenced | send | | [TwoFAAlert](#twofaalert) | Deliver a two-factor verification code by email. | referenced | queued | | [UngrantPayroll](#ungrantpayroll) | Notify a collaborator that payroll access was revoked. | referenced | queued | | [UserAccountantSubscriptionEmail](#useraccountantsubscriptionemail) | Welcome a virtual support subscriber and provide onboarding steps. | referenced | queued | | [UserInvite](#userinvite) | Invite a collaborator to join a business. | referenced | queued | | [WalletCreatedMail](#walletcreatedmail) | Notify internal staff of a wallet signup. | referenced | send | | [WaybillMail](#waybillmail) | Send an invoice waybill with PDF. | referenced | queued | | [WelcomeCFOAIAccount](#welcomecfoaiaccount) | Welcome a user to Built CFO AI. | referenced | send | | [WelcomeCrmAccount](#welcomecrmaccount) | Welcome a user to CRM while account approval is pending. | referenced | send | | [WelcomeWallet](#welcomewallet) | Welcome a user to Built Wallet while approval is pending. | referenced | send | | [accounttantRequest](#accounttantrequest) | Tell a subscriber that their plan includes accountant pairing. | referenced | queued | | [cardTransactionNotification](#cardtransactionnotification) | Notify the account holder of a virtual-card debit. | referenced | queued | | [confirm](#confirm) | Ask a newly registered user to verify their account. | referenced | queued | | [customerTransactions](#customertransactions) | Send a customer transaction statement and PDF. | referenced | queued | | [disableTwoFA](#disabletwofa) | Authorize disabling two-step authentication. | referenced | queued | | [insuranceActivity](#insuranceactivity) | Notify a customer of an insurance policy creation through Curasel. | referenced | send | | [internalAccountNotification](#internalaccountnotification) | Request internal accountant pairing for a subscribed business. | referenced | queued | | [invoice](#invoice) | Send an invoice to a customer with a view or payment-enabled action and PDF. | referenced | queued | | [invoiceMail](#invoicemail) | Legacy invoice test Mailable. | apparently unused | none found | | [passwordReset](#passwordreset) | Send the custom API password reset instructions and one-use link. | referenced | queued | | [paymentRecieved](#paymentrecieved) | Notify the business user of an invoice payment and charges. | referenced | queued | | [payslip](#payslip) | Send an employee payslip and attached PDF. | referenced | queued | | [quote](#quote) | Send a quote to a customer and attach its PDF. | referenced | queued | | [salesReciept](#salesreciept) | Send a sales receipt with PDF. | referenced | queued | | [ssnit2report](#ssnit2report) | Send tier-two social security contributions and attachment. | referenced | queued | | [ssnitreport](#ssnitreport) | Send social security contributions and attachment. | referenced | queued | | [subscriptionFailed](#subscriptionfailed) | Explain a failed subscription or upgrade attempt. | referenced | queued | | [subscriptionNotification](#subscriptionnotification) | Confirm subscription and show billing cycle and amount/tax details. | referenced | queued | | [supplierTransactions](#suppliertransactions) | Send a supplier transaction statement and PDF. | referenced | queued | | [taxreport](#taxreport) | Send a country-specific payroll income-tax report PDF. | referenced | queued | | [tier3](#tier3) | Send tier-three social security contributions and PDF. | referenced | queued | | [welcome](#welcome) | Legacy personal onboarding welcome email. | apparently unused | none found | | [welcomeEmployee](#welcomeemployee) | Give a newly registered employee access details for their payroll portal. | referenced | queued, rendered for external bulk sender | ## Mailable details ### AccountantInvite Invite an accountant to collaborate with a business. - Status: **referenced**. Implementation: `app/Mail/AccountantInvite.php:1`. - Subject: `->subject($this->business->name.' invites you to collaborate');` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/invitationsController.php:1317`, function `inviteaccountant`, queued: `$business = Business::findOrFail($invite->business_id); Mail::to($request->email) ->queue(new AccountantInvite($business, $invite)); } public function sendaccountantinvite() {` - `app/Http/Controllers/Settings/invitationsController.php:1841`, function `sendaccountantinvite`, queued: `$this->invite = $invite; Mail::to($this->invite->user_email) ->queue(new AccountantInvite($business, $invite)); return redirect()->back()->with('success', 'Invite sent'); }` - Data bindings and derived links: `$data['business'] = $this->business;`; `$data['invite'] = $this->invite;`; `$data['link'] = config('app.url').'/confirminvitation/'.encrypt($this->invite->id);` Template: `resources/views/emails/users/accountantInvite.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$business->name`; `$link`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### AffiliateAccountCreated Confirm affiliate creation and provide a shareable referral link. - Status: **referenced**. Implementation: `app/Mail/AffiliateAccountCreated.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Account/AffiliateAccountController.php:104`, function `store`, send: `$userToUpdate->update(['is_affiliate' => 1]); } Mail::to($request->email)->send(new AffiliateAccountCreated($account));` - Data bindings and derived links: `return $this->markdown('emails.affiliateAccount', ['account' => $this->account]);` Template: `resources/views/emails/affiliateAccount.blade.php:1` - Shared components/layouts: `mail::message`, `mail::promotion`, `mail::subcopy` - Dynamic content expressions: `$account->name`; `$account->code`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: The body prints https://affiliate.builtaccounting.com/{account.code} as a copy/share URL. It is not a mail::button action; the source explicitly says not to sign up yourself through it. This manual trace corrects the earlier button-only scanner omission. ### AffiliateInvite Invite a referral to sign up using an affiliate code. - Status: **referenced**. Implementation: `app/Mail/AffiliateInvite.php:1`. - Subject: `return $this->markdown('emails.AffiliateInvite', ['account' => $this->account])->subject($this->account->name.' invites you to use Built for free');` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Account/AffiliateAccountController.php:205`, function `sendinvite`, queued: `public function sendinvite(Request $request) { Mail::to($request->email)->queue(new AffiliateInvite(AffiliateAccountController::getAccount())); \App\AffiliateInvite::create([ 'account_id' => AffiliateAccountController::getAccount()->id, 'email' => $request->email, ]);` - Data bindings and derived links: `return $this->markdown('emails.AffiliateInvite', ['account' => $this->account])->subject($this->account->name.' invites you to use Built for free');` Template: `resources/views/emails/AffiliateInvite.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button`, `mail::subcopy`, `mail::panel` - Dynamic content expressions: `$account->name`; `config('app.url').'/img/built.jpeg'`; `config('app.url')`; `$account->code`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://builtaccounting.com/features/`; `@component('mail::button', ['url' => "https://affiliate.builtaccounting.com/".$account->code,'color'=>'success'])`; `@component('mail::button',['color'=>'success','url' => "https://affiliate.builtaccounting.com/".$account->code,])` ### BankTopupCode Send bank top-up details and an authorization code to internal finance. - Status: **referenced**. Implementation: `app/Mail/BankTopupCode.php:1`. - Subject: `return $this->subject('Built:No-reply')->markdown('emails.BankTopupCode', `` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - [app/Http/Controllers/Wallet/WalletController.php:184`, function `bankTopTup`, send: `$bankTopupTransaction->save(); Mail::to('[address omitted]')->send(new BankTopupCode($bankTopupTransaction, $wallet, $bank)); $smsMessage = WalletRepository::makeBankTopupCodeSMS($bankTopupTransaction, $wallet, $bank); $sms = new SMSHelper; $sms->sendSMS(PHONE_NUMBER, $smsMessage, false);` - Content and workflow notes: BankTopupTransaction hides secrete from serialization; the caller sends before clearing its in-memory value and returning JSON. Read the model property explicitly in the Mailable adapter. No source expiry, single-use rule, approval URL or verified receipt/credit claim exists. - Data bindings and derived links: `'transaction' => $this->transaction,`; `'wallet' => $this->wallet,`; `'bank' => $this->bank,` Template: `resources/views/emails/BankTopupCode.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$wallet->business_name`; `$wallet->number`; `$transaction->reference`; `$wallet->currency`; `number_format($transaction->amount,2)`; `$transaction->secrete`; `$bank->bank_name`; `$bank->account_name`; `$bank->account_number`; `$bank->branch`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### CancelSubscription Confirm cancellation and downgrade to the basic plan. - Status: **referenced**. Implementation: `app/Mail/CancelSubscription.php:1`. - Subject: `->subject('Built subscription canceled');` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Billing/AppSubscriptionsController.php:459`, function `cancel`, queued: `$bill->update(['end_date' => $end_date]); Mail::to($request->user('api')->email) ->queue(new CancelSubscription($bill)); $fw = new FlutterWave; $fw->deleteCard();` - Data bindings and derived links: `return $this->markdown('emails.users.CancelSubscription', ['bill' => $this->bill])` Template: `resources/views/emails/users/CancelSubscription.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$bill->planname`; `$bill->start_date`; `$bill->end_date`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### CardCreatedNotification Confirm virtual card creation and prompt expense classification. - Status: **referenced**. Implementation: `app/Mail/CardCreatedNotification.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Wallet/MapleradController.php:142`, function `handleWebhook`, send: `}); $realCard = VirtualCard::find($dummyCard->id); Mail::to($user->email)->send(new CardCreatedNotification($realCard)); } }` - Data bindings and derived links: `return $this->markdown('emails.CardCreated', ['card' => $this->card]);` Template: `resources/views/emails/CardCreated.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$card->name`; `$card->card_pan_masked`; `$card->card_type`; `$card->amount` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://app.built.africa` ### ChangeInvite Notify a collaborator that their business roles changed. - Status: **referenced**. Implementation: `app/Mail/ChangeInvite.php:1`. - Subject: `->subject('Your roles have been changed')` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/invitationsController.php:712`, function `update`, queued: `$user = User::find($user_id); Mail::to($user->email) ->queue(new ChangeInvite($business, $user)); return response(['success' => true, 'message' => 'Permissions were changed for '.$user->name.' on this business']); }` - Data bindings and derived links: `$data['business'] = $this->business;`; `$data['user'] = $this->user;` Template: `resources/views/emails/users/ChangeInvite.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name`; `$business->name` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### CrmAccountCreatedMail Notify internal staff of a CRM signup. - Status: **referenced**. Implementation: `app/Mail/CrmAccountCreatedMail.php:1`. - Subject: `return $this->subject('New CRM Account signup')->markdown('emails.crm.CreatedMail', $data);` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/CrmSettingController.php:65`, function `store`, send: `Mail::to($request->user()->email)->send(new WelcomeCrmAccount); Mail::to('[address omitted]')->send(new CrmAccountCreatedMail($crmSetting, $business->name)); return response()->json($crmSetting); } public function show(): Response\\|JsonResponse` - Data bindings and derived links: `public function __construct(public CrmSetting $crmSetting, public string $businessName) {}`; `'business_name' => $this->businessName,`; `'id' => $this->crmSetting->id,`; `'sender_id' => $this->crmSetting->sender_id,` Template: `resources/views/emails/crm/CreatedMail.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$business_name`; `$sender_id`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => 'https://xxxyydd234.builtaccounting.com/crm-accounts/'.$id])` ### CrmAccountUpdatedMail Notify internal staff of a CRM sender-ID change. - Status: **referenced**. Implementation: `app/Mail/CrmAccountUpdatedMail.php:1`. - Subject: `return $this->subject('New CRM Account signup')->markdown('emails.crm.UpdatedMail', $data);` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/CrmSettingController.php:149`, function `update`, send: `'channel_transaction_sms' => $validated['channel_transactions'], ]); Mail::to('[address omitted]')->send(new CrmAccountUpdatedMail($crmSetting, $business->name, $oldSenderId)); return response()->json($crmSetting); }` - Data bindings and derived links: `public function __construct(public CrmSetting $crmSetting, public string $businessName, public string $oldSenderId) {}`; `'business_name' => $this->businessName,`; `'id' => $this->crmSetting->id,`; `'old_sender_id' => $this->oldSenderId,`; `'sender_id' => $this->crmSetting->sender_id,` Template: `resources/views/emails/crm/UpdatedMail.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$business_name`; `$old_sender_id`; `$sender_id`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => 'https://xxxyydd234.builtaccounting.com/crm-accounts/'.$id])` ### CustomerInvite Invite a customer to sign up through a referral. - Status: **apparently unused**. Implementation: `app/Mail/CustomerInvite.php:1`. - Subject: `return $this->markdown('emails.customers.invite')->subject($this->user->first_name.' '.$this->user->last_name.' invites you to use built for free');` - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `public $user;`; `public $code;` Template: `resources/views/emails/customers/invite.blade.php:1` - Shared components/layouts: `mail::message`, `mail::panel`, `mail::button`, `mail::subcopy` - Dynamic content expressions: `$user->first_name . ' ' . $user->last_name`; `config('app.url').'/img/built.jpeg'`; `config('app.url')`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://builtaccounting.com/features/`; `@component('mail::button', ['url' => "https://affiliate.builtaccounting.com/customer-invite/".$code,'color'=>'success'])`; `@component('mail::button',['color'=>'success','url' => "https://affiliate.builtaccounting.com/customer-invite/".$code,])`; `@component("mail::button",["color"=>"success","url"=> "https://affiliate.builtaccounting.com/customer-invite/".$code])` ### DepositTransaction Send a deposit transaction receipt with PDF. - Status: **referenced**. Implementation: `app/Mail/DepositTransaction.php:1`. - Subject: `->subject('Deposit Transaction #'.$transactionID);` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Accounting/DepositTransactionsController.php:562`, function `sendEmail`, queued: `$emails = array_filter(array_unique(array_unique($emails))); if ($emails) { Mail::to($emails)->queue(new \App\Mail\DepositTransaction($transaction)); } return response('Messages sent successfully'); } catch (Exception $e) { report($e);` - Data bindings and derived links: `$pdf = SnappyPdf::loadView('deposit-transactions.receipt', ['transaction' => $this->transaction]);`; `return $this->markdown('emails.deposit-transaction-receipt', ['transaction' => $this->transaction])` - Attachments/PDF views: `$pdf = SnappyPdf::loadView('deposit-transactions.receipt', ['transaction' => $this->transaction]);`; `->attachData($pdf->output(), 'deposit_transaction_#'.$transactionID.'.pdf')` Template: `resources/views/emails/deposit-transaction-receipt.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$transaction->business->name`; `str_pad($transaction->id,12,"0",STR_PAD_LEFT)`; `\Carbon\Carbon::parse($transaction->created_at)->toDateTimeString()`; `$transaction->description ?? "N/A"`; `$transaction->type`; `$transaction->business->currency->code.number_format($transaction->amount,2)`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### DeveloperAccountCreatedMail Notify internal staff of a developer signup. - Status: **referenced**. Implementation: `app/Mail/DeveloperAccountCreatedMail.php:1`. - Subject: `return $this->subject('New Developer Account Signup')` - Queue: implements ShouldQueue. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Developer/DeveloperAccountController.php:96`, function `store`, send: `Mail::to('[address omitted]') ->bcc(['[address omitted]', '[address omitted]']) ->send(new DeveloperAccountCreatedMail($account)); } return response()->json($account); } }` - Data bindings and derived links: `public function __construct(public DeveloperAccount $developerAccount) {}`; `'developerAccount' => $this->developerAccount,` Template: `resources/views/emails/developer-account/CreatedMail.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$developerAccount->user->first_name`; `$developerAccount->user->last_name`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => 'https://xxxyydd234.builtaccounting.com/developers'])` ### FailedSubscription Notify internal staff of an undefined automatic subscription type during successful collection handling. Tracing correction (3 November 2026): PaymentRepository::resolveMobileMoneyCollection nests the subscription-undefined branch inside code === 00 handling. The source subject/class says failure, but the recipient list is internal and this trigger does not establish a failed customer debit. Retain the distinction. - Status: **referenced**. Implementation: `app/Mail/FailedSubscription.php:1`. - Subject: `subject: 'Failed Automatic Subscription',` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Repository/PaymentRepository.php:1027`, function `resolveMobileMoneyCollection`, send: `foreach ($mails as $mail) { Mail::to($mail) ->send(new FailedSubscription($business, $collection)); } } if (in_array($collection->transaction_type, $indicies)) {` - Data bindings and derived links: `public Business $business,`; `public MobileMoneyCollections $collection` Template: `resources/views/emails/users/automatic-subscription-failed.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$business->id`; `$business->name`; `$collection->amount`; `$collection->network`; `$collection->transaction_id`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### FloatingMail Send stock audit report attachments. - Status: **apparently unused**. Implementation: `app/Mail/FloatingMail.php:1`. - Subject: `subject: 'Stock Audit Reports',` - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `public function __construct(public $files)` - Attachments/PDF views: `return Arr::map($this->files, fn ($file) => Attachment::fromStorageDisk('do', $file));` Template: `resources/views/emails/stock-audit.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: No interpolated values found. - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### FundsRequestConfirmation Confirm loan application submission to the applicant. - Status: **referenced**. Implementation: `app/Mail/FundsRequestConfirmation.php:1`. - Subject: `->subject('Your Application for cash advance');` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Service ID 7 selects the Fido template, which requires downloading the external Fido app to finish the application. Other services use the generic confirmation with provider contact details. Neither state is approval. - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/OffersController.php:181`, function `register`, queued: `Mail::to($request_funds->personal_info['email']) ->bcc(['[address omitted]', '[address omitted]']) ->queue(new FundsRequestConfirmation($data)); if ($request_funds->service_id == 7) { try { (new SMSHelper)->sendSMS( recipient_numbers: $request_funds->personal_info['phone_number'],` - Data bindings and derived links: `public $data;`; `$template = $this->data['service']->id == 7`; `return $this->markdown($template)`; `->with($this->data)` Template: `resources/views/emails/loan-offers/fido-template.blade.php:1` - Shared components/layouts: `mail::layout`, `mail::button`, `mail::panel` - Dynamic content expressions: `$request['personal_info']['first_name']`; `$request['business_details']['business_name']`; `$service->name`; `$service->tel_number`; `$service->business_email`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://play.google.com/store/apps/details?id=com.builtaccounting.app&hl=en`; `https://apps.apple.com/gh/app/built-accounting/id1547855525`; `@component('mail::button', ['url' => 'https://fido.smart.link/3c5c7t03v'])` Template: `resources/views/emails/loan-offers/FundsRequestConfirmation.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$request['personal_info']['first_name']`; `$request['business_details']['business_name']`; `$service->name`; `$service->tel_number`; `$service->business_email`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### GetStarted Introduce Built after signup and link to the dashboard. - Status: **referenced**. Implementation: `app/Mail/GetStarted.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Auth/AuthController.php:174`, function `googleCallback`, send: `]); $newUser->save(); Mail::to($newUser->email)->send(new GetStarted($newUser)); $tokenResult = $newUser->createToken('google_oauth_'.$user['id']); }` - `app/Http/Controllers/Auth/AuthController.php:285`, function `signup`, send: `}); if (! $this->checkIfEmailContainsPhoneNumber($user->email)) { Mail::to($user->email)->send(new GetStarted($user)); Mail::to($user->email)->queue(new confirm($user));` - `app/Http/Controllers/Auth/AuthController.php:429`, function `signupV2`, send: `}); if (! $this->checkIfEmailContainsPhoneNumber($user->email)) { Mail::to($user->email)->send(new GetStarted($user)); Mail::to($user->email)->queue(new confirm($user));` - Data bindings and derived links: `return $this->markdown('emails.getstarted', ['user' => $this->user]);` Template: `resources/views/emails/getstarted.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: No interpolated values found. - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://app.built.africa`; `https://play.google.com/store/search?q=built+accounting&c=apps`; `https://apps.apple.com/gh/app/built-accounting/id1547855525`; `https://built.africa` ### GrantPayroll Notify a collaborator that payroll access was granted. - Status: **referenced**. Implementation: `app/Mail/GrantPayroll.php:1`. - Subject: `->subject('Payroll access')` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/invitationsController.php:1918`, function `grantpayroll`, queued: `$business = Business::findOrFail($invite->business_id); Mail::to($invite->user_email) ->queue(new GrantPayroll($business)); return response()->json($invite); }` - Data bindings and derived links: `$data['business'] = $this->business;` Template: `resources/views/emails/users/GrantPayroll.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$business->name` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### ImportCompleted Confirm CRM contact import completion. - Status: **referenced**. Implementation: `app/Mail/ImportCompleted.php:1`. - Subject: `->subject('CRM Contacts Import Completed!');` - Queue: implements ShouldQueue. queued - Recipient, trigger and usage evidence: - `app/Jobs/Crm/ContactsImportCompleted.php:46`, function `handle`, queued: `); Mail::to($this->user) ->queue(new ImportCompleted( $this->user->first_name, $this->business->name, 'https://app.built.africa/crm' )); }` - Data bindings and derived links: `public string $firstName,`; `public string $businessName,`; `public string $url,`; `->with(``; `'firstName' => $this->firstName,`; `'businessName' => $this->businessName,`; `'url' => $this->url,` Template: [resources/views/emails/crm/import-successful.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$firstName`; `$businessName`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => $url])` ### ImportFailed Report CRM contact import failure and its reason. - Status: **referenced**. Implementation: `app/Mail/ImportFailed.php:1`. - Subject: `->subject('CRM Contacts Import Failed!');` - Queue: implements ShouldQueue. queued - Recipient, trigger and usage evidence: - `app/Jobs/Crm/ContactsImportFailed.php:48`, function `handle`, queued: `); Mail::to($this->user) ->queue(new ImportFailed( $this->user->first_name, $this->business->name, $this->error )); }` - Data bindings and derived links: `public string $firstName,`; `public string $businessName,`; `public string $reason,`; `->with(``; `'firstName' => $this->firstName,`; `'businessName' => $this->businessName,`; `'reason' => $this->reason,` Template: [resources/views/emails/crm/import-failed.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$firstName`; `$businessName`; `$reason`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### InfoMail Carry product-import success and failure messages in a shared body template. - Status: **referenced**. Implementation: `app/Mail/InfoMail.php:1`. - Subject: `->subject($this->title)` - Queue: implements ShouldQueue. send - Content and workflow notes: Two distinct notification types share emails.info: Product Import Completed and Product Import Failed. The caller supplies title and body; the template renders body as raw HTML. Count these as two types if selected for redesign. - Recipient, trigger and usage evidence: - `app/Http/Repository/ItemRepository.php:1053`, function `processItemImport`, send: `); Mail::to($user) ->send(new InfoMail('Product Import Completed', $mailMessage)); Cache::forget($cacheKey); })->catch(function (Batch $batch, Throwable $e) use ($business, $user, $total, $chunkSize) { $cacheKey = 'product_import_'.$business->id.'_'.$batch->id; $data = Cache::get($cacheKey);` - `app/Http/Repository/ItemRepository.php:1085`, function `processItemImport`, send: `); Mail::to($user) ->send(new InfoMail('Product Import Failed', $mailMessage)); Cache::forget($cacheKey); }) ->name('Importing products for '.$business->name) ->dispatch();` - Data bindings and derived links: `public function __construct(public string $title, public string $message)`; `->with(``; `'body' => $this->message,` Template: [resources/views/emails/info.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$body`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### InsuranceClaimStatusChanged Notify a claimant of a status transition, including cancellation reason. - Status: **referenced**. Implementation: `app/Mail/InsuranceClaimStatusChanged.php:1`. - Subject: `return $this->subject('Your insurance claim status changed!')` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Cancelled state adds the cancellation reason; other states show previous and current status. - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/Insurance/InsuranceClaimController.php:294`, function `changeStatus`, queued: `} Mail::to($claim->user->email)->bcc('[address omitted]') ->queue(new InsuranceClaimStatusChanged($claim, $previousState)); try { $sms_helper = new SMSHelper; $message = "Hello, Your insurance claim status changed from {$previousState} {$validated['status']}.";` - Data bindings and derived links: `public function __construct(public InsuranceClaim $claim, public string $previousStatus)`; `'claim' => $this->claim,`; `'user' => $this->claim->user,`; `'previousStatus' => $this->previousStatus,` Template: `resources/views/emails/insurance/claim_status_changed.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name ?? ''`; `$previousStatus`; `$claim->status`; `$claim->reason`; `config('app.name')` - Conditional/loop source: `@if($claim->status == 'cancelled')` - Action destinations: No explicit action URL found. ### InsuranceClaimSubmitted Acknowledge an insurance claim to the customer and internal staff. - Status: **referenced**. Implementation: `app/Mail/InsuranceClaimSubmitted.php:1`. - Subject: `return $this->subject('Insurance Claim Submitted')` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: The same acknowledgement goes to the claimant and internal staff. The template reads $user; inspect policy/user binding before integration. - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/Insurance/InsuranceClaimController.php:118`, function `store`, queued: `} Mail::to($user->email)->bcc('[address omitted]') ->queue(new InsuranceClaimSubmitted($policy)); Mail::to('[address omitted]')->bcc('[address omitted]') ->queue(new InsuranceClaimSubmitted($policy)); try {` - `app/Http/Controllers/FinancialServices/Insurance/InsuranceClaimController.php:121`, function `store`, queued: `->queue(new InsuranceClaimSubmitted($policy)); Mail::to('[address omitted]')->bcc('[address omitted]') ->queue(new InsuranceClaimSubmitted($policy)); try { $sms_helper = new SMSHelper; $message = "Hello, We have received your claim request for the policy {$policy->policy_id}.";` - Data bindings and derived links: `public function __construct(public NewInsurancePolicy $policy) {}`; `'policy' => $this->policy,` Template: `resources/views/emails/insurance/claim_submitted.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name ?? ''`; `$policy->policy_id`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### InsuranceOrderConfirmed Send purchase details to the insurance provider. - Status: **referenced**. Implementation: `app/Mail/InsuranceOrderConfirmed.php:1`. - Subject: `return $this->subject('New Insurance Purchase From Built!')` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Motor vehicle insurance iterates order.data; life insurance shows personal and beneficiary fields. Preserve these separate states and do not populate a preview with actual customer information. - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/Insurance/InsuranceOrderController.php:238`, function `changeState`, queued: `if ($order->serviceProvider->business_email && filter_var($order->serviceProvider->business_email, FILTER_VALIDATE_EMAIL)) { Mail::to($order->serviceProvider->business_email) ->bcc('[address omitted]') ->queue(new InsuranceOrderConfirmed($order)); } } elseif ($data['status'] == 'completed') { $period = $order->product->period; $startAt = Carbon::parse($data['start_at']);` - Data bindings and derived links: `public function __construct(public InsuranceOrder $order) {}`; `'provider' => $this->order->serviceProvider,`; `'order' => $this->order,`; `'user' => $this->order->user,` Template: `resources/views/emails/insurance/purchase.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$provider->name ?? ''`; `$order->product->name`; `$order->name`; `$order->currency`; `$order->amount`; `$order->user?->first_name ?? 'N/A'`; `$order->product->type->name()`; `$order->phone_number`; `\Illuminate\Support\Str::headline($key)`; `$value`; `$order->birth_date`; `$order->age`; `$order->gender`; `$order->address`; `$order->nationality?->name`; `$order->marital_status`; `$order->occupation`; `$order->beneficiary_name`; `$order->beneficiary_phone_number`; `$order->beneficiary_birth_date`; `$order->beneficiary_age`; `$order->beneficiary_relationship`; `$order->beneficiary_gender`; `config('app.name')` - Conditional/loop source: `@if($order->product->type === \App\Enums\InsuranceTypes::MotorVehicleInsurance)`; `@foreach($order->data as $key => $value)`; `@elseif($order->product->type === \App\Enums\InsuranceTypes::LifeInsurance)` - Action destinations: No explicit action URL found. ### InsuranceOrderCreated Acknowledge insurance order creation to the customer and internal staff. - Status: **referenced**. Implementation: `app/Mail/InsuranceOrderCreated.php:1`. - Subject: `return $this->subject($subject)` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: The same customer-facing template is sent both to the user and internal staff. Subject concatenates provider, product and user name. The template reads $user but build() passes only order; runtime binding is unresolved. - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/Insurance/InsuranceOrderController.php:123`, function `store`, queued: `} Mail::to($user->email)->bcc('[address omitted]') ->queue(new InsuranceOrderCreated($order)); Mail::to('[address omitted]')->bcc('[address omitted]') ->queue(new InsuranceOrderCreated($order)); try {` - `app/Http/Controllers/FinancialServices/Insurance/InsuranceOrderController.php:126`, function `store`, queued: `->queue(new InsuranceOrderCreated($order)); Mail::to('[address omitted]')->bcc('[address omitted]') ->queue(new InsuranceOrderCreated($order)); try { $sms_helper = new SMSHelper;` - `app/Http/Controllers/FinancialServices/Insurance/InsuranceOrderController.php:354`, function `motorInsurance`, queued: `} Mail::to($user->email)->bcc('[address omitted]') ->queue(new InsuranceOrderCreated($order)); Mail::to('[address omitted]')->bcc('[address omitted]') ->queue(new InsuranceOrderCreated($order)); try {` - `app/Http/Controllers/FinancialServices/Insurance/InsuranceOrderController.php:357`, function `motorInsurance`, queued: `->queue(new InsuranceOrderCreated($order)); Mail::to('[address omitted]')->bcc('[address omitted]') ->queue(new InsuranceOrderCreated($order)); try { $sms_helper = new SMSHelper;` - Data bindings and derived links: `public function __construct(public InsuranceOrder $order) {}`; `'order' => $this->order,` Template: `resources/views/emails/insurance/order_created.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name ?? ''`; `$order->serviceProvider->name`; `$order->product->name`; `$order->currency.number_format($order->amount,2)`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### InsuranceOrderStatusChanged Notify a customer of order cancellation, completion, or another status change. - Status: **referenced**. Implementation: `app/Mail/InsuranceOrderStatusChanged.php:1`. - Subject: `return $this->subject('Your insurance order status changed!')` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Cancelled state includes reason; completed state includes policy ID or N/A; other states show the previous and current status. - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/Insurance/InsuranceOrderController.php:277`, function `changeState`, queued: `} Mail::to($order->user->email)->bcc('[address omitted]') ->queue(new InsuranceOrderStatusChanged($order, $previousState)); try { $sms_helper = new SMSHelper; $message = "Hello, Your insurance order status changed from {$previousState} {$data['status']}.";` - Data bindings and derived links: `public function __construct(public InsuranceOrder $order, public string $previousStatus) {}`; `'order' => $this->order,`; `'user' => $this->order->user,`; `'previousStatus' => $this->previousStatus,` Template: `resources/views/emails/insurance/order_status_changed.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name ?? ''`; `$previousStatus`; `$order->status`; `$order->reason`; `$order->policy?->policy_id ?? 'N/A'`; `config('app.name')` - Conditional/loop source: `@if($order->status == 'cancelled')`; `@elseif($order->status == 'completed')` - Action destinations: No explicit action URL found. ### InsurancePolicyClosed Explain insurance policy closure. - Status: **referenced**. Implementation: `app/Mail/InsurancePolicyClosed.php:1`. - Subject: `return $this->subject('Your insurance policy has been closed!')` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/Insurance/InsurancePolicyController.php:97`, function `close`, queued: `} Mail::to($policy->user->email)->bcc('[address omitted]') ->queue(new InsurancePolicyClosed($policy)); try { $sms_helper = new SMSHelper; $message = "Hello, Your insurance policy ({$policy->policy_id}) has been closed.";` - Data bindings and derived links: `public function __construct(public NewInsurancePolicy $policy)`; `'policy' => $this->policy,`; `'user' => $this->policy->user,` Template: `resources/views/emails/insurance/policy_closed.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name ?? ''`; `$policy->policy_id`; `$policy->closure_reason`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### InviteConfirmation Tell business administrators that an invitation was accepted. - Status: **referenced**. Implementation: `app/Mail/InviteConfirmation.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/invitationsController.php:756`, function `confirm`, queued: `$active_business->save(); } Mail::to($admin->email)->queue(new InviteConfirmation($user, $business)); return view('invite_accepted'); } elseif ($invite) { $components = Component::where('invitation_id', $invite_id)->get();` - Data bindings and derived links: `$data['user'] = $this->user;`; `$data['business'] = $this->business;` Template: `resources/views/emails/users/InvitConfirmation.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `config('app.url')`; `$user->first_name." ".$user->last_name`; `$business->name`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### InvoiceDiscountRequestMail Send an invoice-discounting request to internal staff. - Status: **referenced**. Implementation: `app/Mail/InvoiceDiscountRequestMail.php:1`. - Subject: `return $this->subject('Invoice discounting request from '.$this->data['business']->name.' for invoice '.$this->data['invoice']->invoice_number)` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Repository/InvoiceRepository.php:297`, function `requestDiscount`, send: `]; Mail::to('[address omitted]') ->send(new InvoiceDiscountRequestMail($info)); return $invoiceDiscount; }` - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/emails/InvoiceDiscountRequest.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$business->name`; `$business->address ?? "Not available"`; `$business->phone_number ?? "Not available"`; `$request->customer_name`; `$request->customer_phone_number`; `$request->customer_email`; `$invoice->fx_currency.number_format($request->amount,2)`; `$invoice->fx_currency.number_format($invoice->amount_due,2)`; `$invoice->invoice_number`; `$request->note`; `config("app.url").$request->attachment_url`; `$invoice->link`; `$wallet->number`; `$wallet->currency`; `number_format($wallet->balance,2)`; `config('app.name')` - Conditional/loop source: `@if($request->attachment_url)`; `@if($invoice->link)`; `@if($wallet)` - Action destinations: No explicit action URL found. - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### LinkVisitedNotification Notify a business user that an invoice link was visited. - Status: **referenced**. Implementation: `app/Mail/LinkVisitedNotification.php:1`. - Subject: `->subject('Invoice notification-'.$this->data['invoice']->invoice_number)->markdown('emails.invoice.URLVisitedNotification', $this->data);` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Listeners/URLVisted.php:77`, function `handle`, send: `$data['business'] = $business; $data['user'] = $user; Mail::to($email)->send(new LinkVisitedNotification($data)); } if ($settings->notify_on_invoice_view && $settings->notify_sms) {` - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/emails/invoice/URLVisitedNotification.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$user->first_name`; `\Carbon\Carbon::now()->toDateTimeString()`; `$customer->business_name`; `$invoice->paid_status`; `$invoice->invoice_number`; `$invoice->start_date`; `$invoice->end_date`; `$invoice->fx_currency.number_format($invoice->amount_due,2)`; `$invoice->fx_currency.number_format($invoice->amount_paid,2)`; `$invoice->fx_currency.number_format($invoice->amount_due-$invoice->amount_paid,2)`; `$business->name`; `$business->phone_name`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => config("app.url")."/viewinvoice/".$invoice->uuid])` ### ManagementReportMail Share a management report and its PDF with chosen recipients. - Status: **referenced**. Implementation: `app/Mail/ManagementReportMail.php:1`. - Subject: `->subject($this->report->name);` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Optional body is distinct from report and businessName. PDF attachment and user-derived From/Reply-To remain integration responsibilities. - Recipient, trigger and usage evidence: - `app/Http/Controllers/AI/ManagementReportController.php:425`, function `sendEmail`, queued: `try { Mail::to($validated['emails']) ->cc($validated['cc']) ->queue(new ManagementReportMail($report, $report->business_name, $validated['body'] ?? '')); return response('Messages sent successfully'); } catch (Exception $e) { report($e);` - Data bindings and derived links: `public ManagementReport $report,`; `public $businessName,`; `public string $body = ''`; `->with(``; `'businessName' => $this->businessName,`; `'report' => $this->report,`; `'body' => $this->body,` - Attachments/PDF views: `->attachData($pdf, Str::slug($report->business_name, '_').'_'.Str::slug($report->name, '_').'.pdf')` Template: [resources/views/emails/management-reports/email.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$body`; `$report->business_name`; `$report->name`; `$report->from->format('d-m-Y')`; `$report->to->format('d-m-Y')`; `$report->user->fullname` - Conditional/loop source: `@if(!empty($body))`; `@else` - Action destinations: No explicit action URL found. - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### MultipleInvoicesCreatedMail Report bulk invoice creation success or partial failure. - Status: **referenced**. Implementation: `app/Mail/MultipleInvoicesCreatedMail.php:1`. - Subject: `->subject('Multiple Invoices Created!');` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: When failedInvoices > 0, show created/total/failed counts and each failedMessages entry; otherwise use the complete-success text. The caller can supply zero successes as well as partial success. - Recipient, trigger and usage evidence: - `app/Jobs/CreateMutipleInvoicesJob.php:98`, function `handle`, queued: `if ($this->user->email && filter_var($this->user->email, FILTER_VALIDATE_EMAIL)) { Mail::to($this->user) ->queue(new MultipleInvoicesCreatedMail( $this->user->first_name, $this->business->name, $totalInvoices, $createdInvoices, $failedInvoices,` - Data bindings and derived links: `public string $firstName,`; `public string $businessName,`; `public int $totalInvoices,`; `public int $createdInvoices,`; `public int $failedInvoices,`; `public array $failedMessages`; `->with(``; `'firstName' => $this->firstName,`; `'businessName' => $this->businessName,`; `'totalInvoices' => $this->totalInvoices,`; `'createdInvoices' => $this->createdInvoices,`; `'failedInvoices' => $this->failedInvoices,`; `'failedMessages' => $this->failedMessages,` Template: [resources/views/emails/invoice/multiple.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$firstName`; `$createdInvoices`; `$totalInvoices`; `$failedInvoices`; `$loop->iteration`; `$failedMessage`; `config('app.name')` - Conditional/loop source: `@if($failedInvoices > 0)`; `@foreach($failedMessages as $failedMessage)`; `@else` - Action destinations: `@component('mail::button', ['url' => $url])` ### NsanoStatus Provide a payment-provider status message. - Status: **apparently unused**. Implementation: `app/Mail/NsanoStatus.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `$data['title'] = $this->title;`; `$data['message'] = $this->message;` Template: `resources/views/emails/nsano/status.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$title`; `$message`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### OverdraftRequestMail Send an overdraft request to internal finance. - Status: **referenced**. Implementation: `app/Mail/OverdraftRequestMail.php:1`. - Subject: Explicit native pattern `Overdraft request from {business.name} for bill {bill.bill_id}`. Manual source inspection confirms the chained subject() call in app/Mail/OverdraftRequestMail.php; the earlier scanner missed its line break. - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Repository/FinanceRepository.php:87`, function `SendOverDraft`, send: `'link' => $link, ]; Mail::to('[address omitted]')->send(new OverdraftRequestMail($data)); return $overdraft; } }` - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/emails/overdraftRequest.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$business->name`; `$business->address ?? "Not available"`; `$business->phone_number ?? "Not available"`; `$request->account_name`; `$request->account_number`; `$request->bank`; `$bill->fx_currency.number_format($request->amount,2)`; `$bill->fx_currency.number_format($request->interest,2)`; `$bill->fx_currency.number_format($request->total_amount,2)`; `$request->repayment_period`; `$request->repayment_due_date`; `$bill->fx_currency.number_format($bill->amount_left,2)`; `$bill->bill_id`; `$link`; `$wallet->number`; `$wallet->currency`; `number_format($wallet->balance,2)`; `config('app.name')` - Conditional/loop source: `@if($wallet)` - Action destinations: No explicit action URL found. ### PaymentError Report transfer failure with an optional retry action. - Status: **referenced**. Implementation: `app/Mail/PaymentError.php:1`. - Subject: `->subject('Transfer failed');` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: business can be null; link is conditional. Some callers pass #, so a truthy link does not guarantee a useful retry destination. Do not invent a working retry URL. - Recipient, trigger and usage evidence: - `app/Http/Controllers/Income/paymentsController.php:450`, function `completeMomopayment`, queued: `$link = '#'; Mail::to('[address omitted]') ->queue(new PaymentError(null, 0, $link, $e->getMessage().' line '.$e->getLine())); return 'Error: could not verify this transaction '; }` - `app/Http/Controllers/Income/paymentsController.php:468`, function `sendFailedNotification`, queued: `Mail::to('[address omitted]') ->queue(new PaymentError($business, $amount, $link, $reason)); } public static function completeCardPayment($ref) {` - `app/Http/Controllers/Income/paymentsController.php:800`, function `completeCardPayment`, queued: `$reason = 'something went wrong, please refresh the page to try again or contact support'; $link = '#'; Mail::to('[address omitted]') ->queue(new PaymentError(null, 0, $link, $reason)); return false; }` - `app/Http/Controllers/Income/paymentsController.php:1291`, function `completepayment`, queued: `$reason = 'something went wrong, please refresh the page to try again or contact support .'.$e->getMessage().'line:'.$e->getLine(); $link = '#'; Mail::to('[address omitted]') ->queue(new PaymentError(null, 0, $link, $reason)); $data['error_message'] = 'Error: could not verify this transaction '; return view('invoice_notfound', $data);` - Additional manual trace: sendFailedNotification is also referenced by invoice bank/mobile-money failure paths, WalletKEController::withdraw (:300), NSANOController::confirmdebit (:451), non-production ATCallbackEvent/FlutterWaveWebhook diagnostics and NSANOCrediCallBack::broadcastOn (:49). The latter event dispatch remains unresolved; its helper call is not status-filtered. AT diagnostic var_export lacks return=true and may supply null reason. These are data/usage states of PaymentError, not additional notification types. Preserve exact helper URL tuple and distinguish PHP link truthiness from a validated retry destination. See the internal payment-operations contracts. - Data bindings and derived links: `$this->link = $link;`; `$data['business'] = $this->business;`; `$data['amount'] = $this->amount;`; `$data['reason'] = $this->reason;`; `$data['link'] = $this->link;` Template: `resources/views/emails/invoice/paymentError.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$business ? $business->name : ''`; `$business ? $business->currency->symbol : ""`; `number_format($amount,2)`; `$reason`; `config('app.name')` - Conditional/loop source: `@if($link)` - Action destinations: `@component('mail::button', ['url' => $link])` ### PaymentLimit Report a transfer limit/provider failure after successful collection. - Status: **apparently unused**. Implementation: `app/Mail/PaymentLimit.php:1`. - Subject: `return $this->markdown('emails.invoice.paymentLimit', $data)->subject('Transfer Failed');` - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Content and workflow notes: The current Mailable has no discovered construction. A separate direct Mail::send path uses mails.payment_limit for bill transfer failures; it is cataloged separately. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `$data['invoice'] = $this->invoice;`; `$data['description'] = $this->descritpion;`; `$data['amount'] = $this->amount;`; `$data['business'] = $this->business;` Template: `resources/views/emails/invoice/paymentLimit.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$description`; `$business->currency->symbol.number_format($amount,2)`; `$business->name`; `isset($invoice) ? $invoice->invoice_number : "bill"`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://dashboard.paystack.com/#/dashboard` ### PaymentLinkReciept Send a payment-link transaction receipt to the payer. - Status: **referenced**. Implementation: `app/Mail/PaymentLinkReciept.php:1`. - Subject: `->subject('Payment receipt from '.$wallet->business_name)` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Repository/PaymentRepository.php:1215`, function `resolveMobileMoneyCollection`, send: `if ($tranx->customer_email) { Mail::to($tranx->customer_email)->send(new PaymentLinkReciept($wallet, $tranx)); } $WpLog = WBLog::where('wallet_id', $wallet->id)->where('transaction_id', $link->id)->first();` - `app/Http/Repository/PaymentRepository.php:1308`, function `resolveMobileMoneyCollection`, send: `$payment_link_transaction->update(['status' => 'processed']); if ($payment_link_transaction->customer_email) { Mail::to($payment_link_transaction->customer_email)->send(new PaymentLinkReciept($wallet, $payment_link_transaction)); } }` - Data bindings and derived links: `'wallet' => $this->wallet,`; `'transaction' => $this->transaction,` Template: `resources/views/emails/paynentLinkReciept.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$transaction->id`; `$wallet->business_name`; `$transaction->created_at->format("d-M-Y")`; `$wallet->currency`; `number_format($transaction->amount,2)` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### Receipt Send an invoice payment receipt and PDF. - Status: **referenced**. Implementation: `app/Mail/Receipt.php:1`. - Subject: `->subject('Receipt_#'.$this->invoice->invoice_number.'.pdf')` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Template shows cumulative invoice.amount_paid, while the constructor also receives amount and payment. Preserve these distinct values until product semantics are confirmed. Optional business phone/address/email rows. Action uses link built as /invoicereciept/{uuid}. - Recipient, trigger and usage evidence: - `app/Http/Controllers/Accounting/DepositTransactionsController.php:457`, function `PayInvoice`, queued: `if (! empty($invoice->customer->business_email)) { $payment = Payment::where('invoice_id', $invoice->id)->get()->last(); Mail::to($invoice->customer->business_email) ->queue(new Receipt($invoice, $business, $payment->amount, $payment)); } }` - `app/Http/Controllers/Income/invoicesController.php:908`, function `savepayment`, queued: `if ($request->send_receipt == 'true' && ! empty($invoice->customer->business_email)) { Mail::to($invoice->customer->business_email) ->queue(new Receipt($invoice, $current_business, $payment->amount, $payment)); } if (config('app.env') === 'production') { event(new InvoicePaid($invoice->id)); }` - `app/Http/Repository/InvoiceRepository.php:1549`, function `addPayment`, queued: `if ((string) $send_receipt == 'true' && ! empty($invoice->customer->business_email)) { Mail::to($invoice->customer->business_email) ->queue(new Receipt($invoice, $business, $payment->amount, $payment)); } if (config('app.env') === 'production') { event(new InvoicePaid($invoice->id)); }` - `app/Http/Repository/InvoiceRepository.php:1757`, function `payFromDeposit`, queued: `if (! empty($invoice->customer->business_email)) { $payment = Payment::where('invoice_id', $invoice->id)->get()->last(); Mail::to($invoice->customer->business_email) ->queue(new Receipt($invoice, $business, $payment->amount, $payment)); } }` - Data bindings and derived links: `$data['invoice'] = $this->invoice;`; `$data['business'] = $this->business;`; `$data['payment'] = $this->payment;`; `$data['method'] = $this->payment->method;`; `$data['amount'] = $this->amount;`; `$data['link'] = config('app.url').'/invoicereciept/'.$this->invoice->uuid;`; `$data['payments'] = $this->invoice->payment_history;` - Attachments/PDF views: `$pdf = SnappyPdf::loadView('receipt', $data);`; `->attachData($pdf->output(), 'Receipt_#'.$this->invoice->invoice_number.'.pdf');` Template: `resources/views/emails/invoice/Receipt.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$invoice->invoice_number`; `$business->name`; `$invoice->invoice_color`; `$invoice->fx_currency`; `number_format($invoice->amount_paid,2)`; `$payment->method`; `\Illuminate\Support\Carbon::parse($payment->date_paid)->format("l d F, Y")`; `$business->phone_number`; `$business->address`; `$business->email`; `$link` - Conditional/loop source: `@if($business->phone_number)`; `@if($business->address)`; `@if($business->email)` - Action destinations: `{{$link}}` ### ReportGenerated Tell the requesting user that a management report is ready. - Status: **referenced**. Implementation: `app/Mail/ReportGenerated.php:1`. - Subject: `->subject('Report Generation Completed');` - Queue: implements ShouldQueue. queued - Recipient, trigger and usage evidence: - `app/Jobs/CFOAIReport/NotifyUserReportCompleted.php:57`, function `handle`, queued: `); Mail::to($this->report->user) ->queue(new ReportGenerated($this->report)); } }` - Data bindings and derived links: `public function __construct(public ManagementReport $report)`; `->with(``; `'report' => $this->report,` - Attachments/PDF views: `->attachData($pdf, Str::slug($report->business_name, '_').'_'.Str::slug($report->name, '_').'.pdf')` Template: [resources/views/emails/management-reports/generation-completed.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$report->user->first_name`; `$report->business_name`; `$report->name`; `$report->from->format('d-m-Y')`; `$report->to->format('d-m-Y')`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => $url])` ### ReportGenerationFailed Tell the requesting user that management report generation failed. - Status: **referenced**. Implementation: `app/Mail/ReportGenerationFailed.php:1`. - Subject: `->subject('Report Generation Failed');` - Queue: implements ShouldQueue. queued - Recipient, trigger and usage evidence: - `app/Jobs/CFOAIReport/ReportGenerationFailedJob.php:52`, function `handle`, queued: `); Mail::to($this->report->user) ->queue(new ReportGenerationFailed($this->report)); } }` - Data bindings and derived links: `public function __construct(public ManagementReport $report)`; `->with(['report' => $this->report])` Template: `resources/views/emails/management-reports/generation-failed.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$report->user->first_name`; `$report->business_name`; `$report->name`; `$report->from->format('d-m-Y')`; `$report->to->format('d-m-Y')`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### RequestFunds Send loan application details to the service provider. - Status: **referenced**. Implementation: `app/Mail/RequestFunds.php:1`. - Subject: `->subject('Request For Cash Advance')` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/OffersController.php:177`, function `register`, queued: `Mail::to($service_provider->business_email) ->cc($service_provider->email) ->bcc('[address omitted]') ->queue(new RequestFunds($data)); Mail::to($request_funds->personal_info['email']) ->bcc(['[address omitted]', '[address omitted]']) ->queue(new FundsRequestConfirmation($data));` - Data bindings and derived links: `public $data;` Template: `resources/views/emails/requestfunds.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$service['name']`; `$request['business_details']['business_name']`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => "https://partner.built.africa/requests/{$request['id']}"])` ### ResetPassword Scaffold password-reset template with no established sending call. - Status: **apparently unused**. Implementation: `app/Mail/ResetPassword.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `$this->link = $link;`; `return $this->markdown('emails.users.resetpassword', ['link' => $this->link]);` Template: `resources/views/emails/users/resetpassword.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => ''])` ### SendLinkEmail Request a payment using the business wallet payment link. - Status: **referenced**. Implementation: `app/Mail/SendLinkEmail.php:1`. - Subject: `->subject('Payment request from '.$this->wallet->business_name)` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:359`, function `sendLinkToEmails`, send: `foreach ($emialsArray as $email) { Mail::to($email)->send(new SendLinkEmail($link, $wallet)); } return \response()->json([ 'message' => 'Link sent to '.count($emialsArray).' recipients',` - Data bindings and derived links: `$this->link = $link;`; `$data['wallet'] = $this->wallet;`; `$data['link'] = $this->link;` Template: `resources/views/emails/SendLinkEmail.blade.php:1` - Shared components/layouts: `mail::message`, `mail::panel`, `mail::promotion` - Dynamic content expressions: `$link->title`; `$wallet->business_name`; `$wallet->currency.number_format($link->amount,2)`; `$link->short_link`; `$link->description` - Conditional/loop source: `@if($link->description)` - Action destinations: No explicit action URL found. ### SendManualInvoiceReminder Send a user-composed invoice reminder with a caller-supplied subject. - Status: **referenced**. Implementation: `app/Mail/SendManualInvoiceReminder.php:1`. - Subject: `->subject($this->subject);` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Income/invoicesController.php:3599`, function `sendManualReminder`, queued: `return response('Invoice not found', 302); } Mail::to($request->email)->queue(new SendManualInvoiceReminder($request->subject, $request->message, $request->invoice_id)); return response()->json(['message' => 'Reminder sent successfully!']); } public function deactivateReminder(Request $request): JsonResponse` - Data bindings and derived links: `public $subject;`; `public $message;`; `$data['invoice'] = $invoice;`; `$data['business'] = $business;`; `$data['index'] = 1;`; `$data['taxes'] = $invoice->taxes;` - Attachments/PDF views: `$pdf = Pdf::loadView('PDF.invoice', $data);`; `->attachData($pdf->output(), 'Invoice_#'.$invoice->invoice_number.'.pdf')` Template: `resources/views/emails/invoice/reminder.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `nl2br($message)` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### SendNewLoginNotification Warn the user of a sign-in from a new device and offer password reset. - Status: **referenced**. Implementation: `app/Mail/SendNewLoginNotification.php:1`. - Subject: `])->subject('New signin detected on your account');` - Queue: No ShouldQueue declaration. send - Content and workflow notes: States: resolved geolocation or Unknown country/city/code; country flag is optional. Keep device, IP address, country, countryCode, city and user first name. The action is password reset through /confirmreset/, not a device-review screen. No login timestamp is supplied. AuthController and authTwoController call AuthRepository::sendNotificationOnNewLogin. - Recipient, trigger and usage evidence: - `app/Http/Repository/AuthRepository.php:52`, function `sendNotificationOnNewLogin`, send: `$link = config('app.url').'/confirmreset/'.encrypt($new_request->id); Mail::to($email)->send(new SendNewLoginNotification($user, $locationData, $device, $IPAddress, $link)); } public static function resolveIPToLocation($IPAddress) {` - Data bindings and derived links: `'device' => $this->device,`; `'IPAddress' => $this->IPAddress,`; `'link' => $this->resetLink,`; `'user' => $this->user,` Template: `resources/views/emails/SendNewLoginNotification.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name`; `$device`; `$IPAddress`; `$location->country_flag`; `$location->country`; `$location->countryCode`; `$location->city`; `$link`; `config('app.name')` - Conditional/loop source: `Country: @if($location->country_flag)` - Action destinations: `{{$link}}` ### SubscriptionWillExpire Legacy scheduled-delivery experiment for subscription expiry. - Status: **apparently unused**. Implementation: `app/Mail/SubscriptionWillExpire.php:1`. - Subject: `->subject('Send later')` - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Content and workflow notes: emails.SubscriptionWillExpire is a generic scaffold. Contains a legacy withSwiftMessage delivery-time header with a 2020 date; no construction was found. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/emails/SubscriptionWillExpire.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => ''])` ### SupplierInvite Invite a supplier to sign up using a referral code. - Status: **apparently unused**. Implementation: `app/Mail/SupplierInvite.php:1`. - Subject: `return $this->markdown('emails.suppliers.invite')->subject($this->user->first_name.' '.$this->user->last_name.' invites you to use built for free');` - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `public $user;`; `public $code;` Template: `resources/views/emails/suppliers/invite.blade.php:1` - Shared components/layouts: `mail::message`, `mail::panel`, `mail::button`, `mail::subcopy` - Dynamic content expressions: `$user->first_name . ' ' . $user->last_name`; `config('app.url').'/img/built.jpeg'`; `config('app.url')`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://builtaccounting.com/features/`; `@component('mail::button', ['url' => "https://affiliate.builtaccounting.com/supplier-invite/".$code,'color'=>'success'])`; `@component('mail::button',['color'=>'success','url' => "https://affiliate.builtaccounting.com/supplier-invite/".$code,])`; `@component("mail::button",["color"=>"success","url"=> "https://affiliate.builtaccounting.com/supplier-invite/".$code])` ### TestEmail Unused test scaffold referencing a placeholder view. - Status: **unresolved**. Implementation: `app/Mail/TestEmail.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Content and workflow notes: view.name is missing. Scaffold presence is not evidence of an active email. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/view/name.blade.php` **Missing in this checkout.** ### TestMail Test message wrapper. - Status: **apparently unused**. Implementation: `app/Mail/TestMail.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `return $this->markdown('emails.testmail', ['message' => $this->message]);` Template: `resources/views/emails/testmail.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$message` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### TokenRecievedMail Deliver an electricity/network token after wallet purchase. - Status: **referenced**. Implementation: `app/Mail/TokenRecievedMail.php:1`. - Subject: `return $this->subject($this->data['network'].' token received')` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Repository/WalletRepository.php:245`, function `completePurchase`, send: `'business_name' => $wallet->business_name, ]; Mail::to($wallet->email)->send(new TokenRecievedMail($emailData)); } }` - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/emails/TokenRecieved.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$network`; `$business_name`; `number_format($amount,2)`; `$units`; `$pin`; `$ref` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### TwoFAAlert Deliver a two-factor verification code by email. - Status: **referenced**. Implementation: `app/Mail/TwoFAAlert.php:1`. - Subject: `return $this->markdown('emails.TwoFAAlert', $data)->subject('Verification code');` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/TwoFactorAuthentication.php:178`, function `makeCode`, queued: `if (! $isPhoneNumber) { Mail::to($email)->queue(new TwoFAAlert($code)); } else { if ($extra) {` - Data bindings and derived links: `$data['code'] = $this->code;` Template: `resources/views/emails/TwoFAAlert.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$code` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### UngrantPayroll Notify a collaborator that payroll access was revoked. - Status: **referenced**. Implementation: `app/Mail/UngrantPayroll.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/invitationsController.php:1958`, function `ungrantpayroll`, queued: `$business = Business::findOrFail($invite->business_id); Mail::to($invite->user_email) ->queue(new UngrantPayroll($business)); return response()->json($invite); }` - Data bindings and derived links: `$data['business'] = $this->business;` Template: `resources/views/emails/users/UngrantPayroll.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$business->name` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### UserAccountantSubscriptionEmail Welcome a virtual support subscriber and provide onboarding steps. - Status: **referenced**. Implementation: `app/Mail/UserAccountantSubscriptionEmail.php:1`. - Subject: `->subject('Welcome to Built Virtual Support! Meet with us')` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Constructor parameter is named customerName, but its discovered caller passes business->name. Do not silently relabel it as a personal first name. - Recipient, trigger and usage evidence: - `app/Http/Controllers/Billing/AppSubscriptionsController.php:177`, function `subscribe`, queued: `->queue(new accounttantRequest($plan, $user)); Mail::to($user->email) ->queue(new UserAccountantSubscriptionEmail($business->name)); } }` - Data bindings and derived links: `public function __construct(public string $customerName)`; `->with(['user_name' => $this->customerName]);` Template: `resources/views/emails/accountant-support.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user_name` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### UserInvite Invite a collaborator to join a business. - Status: **referenced**. Implementation: `app/Mail/UserInvite.php:1`. - Subject: `->subject($this->business->name.' invites you to collaborate');` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/invitationsController.php:616`, function `store`, queued: `} Mail::to($invite->user_email) ->queue(new UserInvite($business, $invite)); return \response()->json($invite); }` - Data bindings and derived links: `$data['business'] = $this->business;`; `$data['invite'] = $this->invite;`; `$data['link'] = config('app.url').'/confirminvitation/'.encrypt($this->invite->id);` Template: `resources/views/emails/users/UserInvite.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$business->name`; `$link`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => $link])` ### WalletCreatedMail Notify internal staff of a wallet signup. - Status: **referenced**. Implementation: `app/Mail/WalletCreatedMail.php:1`. - Subject: `return $this->subject('New wallet signup')->markdown('emails.WalletCreatedMail', $data);` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Wallet/WalletController.php:399`, function `signup`, send: `Wallet::SetUpSettings($bw->id); Mail::to($user->email)->send(new WelcomeWallet); Mail::to('[address omitted]')->send(new WalletCreatedMail($bw)); return response()->json($bw); }` - `app/Http/Controllers/Wallet/WalletNGController.php:143`, function `store`, send: `Wallet::SetUpSettings($bw->id); Mail::to($user->email)->send(new WelcomeWallet); Mail::to('[address omitted]')->send(new WalletCreatedMail($bw)); return response()->json($bw); }` - Data bindings and derived links: `'business_name' => $this->wallet->business_name,`; `'id' => $this->wallet->id,` Template: `resources/views/emails/WalletCreatedMail.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$business_name`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => 'https://xxxyydd234.builtaccounting.com/wallet-accounts/'.$id])` ### WaybillMail Send an invoice waybill with PDF. - Status: **referenced**. Implementation: `app/Mail/WaybillMail.php:1`. - Subject: `subject: 'Invoice #'.$this->invoice->invoice_number.' Waybill',` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Repository/InvoiceRepository.php:1204`, function `sendWaybill`, queued: `try { Mail::to($email) ->queue(new WaybillMail($business, $invoice, $message)); return response()->json(['message' => 'Invoice waybill sent']); } catch (Exception $e) { report($e);` - Data bindings and derived links: `public function __construct(public Business $business, public Invoice $invoice, public ?string $message = null)`; `'invoice' => $this->invoice,`; `'business' => $this->business,` - Attachments/PDF views: `$pdf = SnappyPdf::loadView('PDF.waybill', ``; `Attachment::fromData(fn () => $pdf->output(), 'invoice_#'.$this->invoice->invoice_number.'_waybill.pdf')` Template: [resources/views/emails/invoice/waybill.blade.php:1` - Shared components/layouts: `mail::message`, `mail::promotion` - Dynamic content expressions: `$invoice->invoice_number`; `$business->name`; `$message` - Conditional/loop source: `@if($message)` - Action destinations: No explicit action URL found. - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### WelcomeCFOAIAccount Welcome a user to Built CFO AI. - Status: **referenced**. Implementation: `app/Mail/WelcomeCFOAIAccount.php:1`. - Subject: `return $this->subject('Welcome to Built CFO AI')->markdown('emails.cfo-ai.welcome');` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/ManagementReportSettingsController.php:35`, function `store`, send: `'tokens' => 1, ]); Mail::to($user->email)->send(new WelcomeCFOAIAccount); return response()->json($settings); }` - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/emails/cfo-ai/welcome.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: No interpolated values found. - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i`; `https://cfoai.built.africa` ### WelcomeCrmAccount Welcome a user to CRM while account approval is pending. - Status: **referenced**. Implementation: `app/Mail/WelcomeCrmAccount.php:1`. - Subject: `return $this->subject('Welcome to Built CRM')->markdown('emails.crm.welcome');` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Settings/CrmSettingController.php:63`, function `store`, send: `'status' => app()->environment('production') ? CrmSetting::PENDING : CrmSetting::APPROVED, ]); Mail::to($request->user()->email)->send(new WelcomeCrmAccount); Mail::to('[address omitted]')->send(new CrmAccountCreatedMail($crmSetting, $business->name)); return response()->json($crmSetting); }` - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/emails/crm/welcome.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: No interpolated values found. - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i`; `https://app.built.africa` ### WelcomeWallet Welcome a user to Built Wallet while approval is pending. - Status: **referenced**. Implementation: `app/Mail/WelcomeWallet.php:1`. - Subject: `return $this->subject('Welcome to BuiltWallet')->markdown('emails.wallet.welcome');` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/Wallet/WalletController.php:397`, function `signup`, send: `Wallet::setupAccounts($bw->id); Wallet::SetUpSettings($bw->id); Mail::to($user->email)->send(new WelcomeWallet); Mail::to('[address omitted]')->send(new WalletCreatedMail($bw)); return response()->json($bw);` - `app/Http/Controllers/Wallet/WalletNGController.php:141`, function `store`, send: `Wallet::setupAccounts($bw->id); Wallet::SetUpSettings($bw->id); Mail::to($user->email)->send(new WelcomeWallet); Mail::to('[address omitted]')->send(new WalletCreatedMail($bw)); return response()->json($bw);` - Data bindings and derived links: See constructor and template expressions below. Template: `resources/views/emails/wallet/welcome.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: No interpolated values found. - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i`; `https://app.built.africa` ### accounttantRequest Tell a subscriber that their plan includes accountant pairing. - Status: **referenced**. Implementation: `app/Mail/accounttantRequest.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Billing/AppSubscriptionsController.php:174`, function `subscribe`, queued: `} Mail::to($user->email) ->queue(new accounttantRequest($plan, $user)); Mail::to($user->email) ->queue(new UserAccountantSubscriptionEmail($business->name)); }` - Data bindings and derived links: `$data['plan'] = $this->plan;`; `$data['user'] = $this->user;` Template: `resources/views/emails/users/accounttantRequest.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name`; `$plan`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### cardTransactionNotification Notify the account holder of a virtual-card debit. - Status: **referenced**. Implementation: `app/Mail/cardTransactionNotification.php:1`. - Subject: `return $this->subject('Card: '.$this->card->card_pan_masked.' transaction')` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Wallet/MapleradController.php:64`, function `handleWebhook`, queued: `if ($user) { Mail::to($user->email)->queue(new cardTransactionNotification($transaction, $localCard)); } }` - Data bindings and derived links: `->markdown('mails.cardTransactionNotification', ['card' => $this->card, 'transaction' => $this->transaction]);` Template: `resources/views/mails/cardTransactionNotification.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$transaction->currency`; `$transaction->amount`; `$card->card_pan_masked`; `$transaction->description` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://app.built.africa` ### confirm Ask a newly registered user to verify their account. - Status: **referenced**. Implementation: `app/Mail/confirm.php:1`. - Subject: `->subject('Verify your account');` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Auth/AuthController.php:287`, function `signup`, queued: `if (! $this->checkIfEmailContainsPhoneNumber($user->email)) { Mail::to($user->email)->send(new GetStarted($user)); Mail::to($user->email)->queue(new confirm($user)); $location = Location::get($request->ip());` - `app/Http/Controllers/Auth/AuthController.php:431`, function `signupV2`, queued: `if (! $this->checkIfEmailContainsPhoneNumber($user->email)) { Mail::to($user->email)->send(new GetStarted($user)); Mail::to($user->email)->queue(new confirm($user)); $location = Location::get($request->ip());` - `app/Http/Controllers/Auth/AuthController.php:960`, function `updateEmail`, queued: `$user->refresh(); Mail::to($user->email)->queue(new confirm($user)); return response()->json($user); } catch (\Exception $e) { return response('Unable to update your email address', 302);` - `app/Http/Controllers/General/emailsController.php:432`, function `sendverify`, queued: `public function sendverify() { $user = auth('api')->user(); Mail::to($user)->queue(new confirm($user)); } public function sendpayslip($id) {` - Data bindings and derived links: `return $this->markdown('emails.users.confirm', ['user' => $this->user])` Template: `resources/views/emails/users/confirm.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name`; `config('app.url').'/verifyaccount/'.encrypt($user->id)` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `{{config('app.url').'/verifyaccount/'.encrypt($user->id)}}` ### customerTransactions Send a customer transaction statement and PDF. - Status: **referenced**. Implementation: `app/Mail/customerTransactions.php:1`. - Subject: `->subject('Transactions Statement from '.$business->name)` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Date range versus all-transactions states; optional message; totals and transaction rows; PDF is attached. Existing message is raw HTML. - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:178`, function `customertransactions`, queued: `Mail::to($base_email) ->bcc($other_emails) ->queue(new customerTransactions($data)); return response('Transactions sent'); } catch (Exception $e) {` - Data bindings and derived links: See constructor and template expressions below. - Attachments/PDF views: `$pdf = Pdf::loadView('PDF.customers.transactions', $this->data);`; `->attachData($pdf->output(), 'Transactions_statement.pdf');` Template: `resources/views/emails/customers/transactions.blade.php:1` - Shared components/layouts: `mail::message`, `mail::promotion` - Dynamic content expressions: `$business->name`; `$from`; `$to`; `\Carbon\Carbon::now()`; `$transactions_count`; `$currency->code`; `number_format($total_amount,2)`; `number_format($total_paid,2)`; `number_format($total_owing,2)`; `$transaction->invoice_number`; `$transaction->fx_currency.number_format($transaction->fx_amount,2)`; `$transaction->fx_currency.number_format(\App\FX::get_base_amount($transaction->amount_paid,$rate),2)`; `$transaction->start_date`; `$transaction->end_date`; `$message` - Conditional/loop source: `@if($from && $to)`; `@else`; `@foreach($transactions as $transaction)`; `@if($i<=10)`; `@if($message)` - Action destinations: No explicit action URL found. - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### disableTwoFA Authorize disabling two-step authentication. - Status: **referenced**. Implementation: `app/Mail/disableTwoFA.php:1`. - Subject: `->subject('Disable two-step authentication request');` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: The existing text says one use only and expires in five minutes. Preserve both restrictions. - Recipient, trigger and usage evidence: - `app/Http/Controllers/Auth/authTwoController.php:370`, function `deactivatetwofaRequest`, queued: `$request = new DisabletwoFARequest(['user_id' => $user->id, 'hash' => $hash]); $request->save(); Mail::to($user->email)->queue(new disableTwoFA($request)); return response()->json(['message' => 'A request was sent to your email for approval']); }` - Data bindings and derived links: `$data['link'] = config('app.url').'/disabletwofa/'.$this->request->hash;` Template: `resources/views/emails/users/disableTwoFA.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$link` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `{{$link}}` ### insuranceActivity Notify a customer of an insurance policy creation through Curasel. - Status: **referenced**. Implementation: `app/Mail/insuranceActivity.php:1`. - Subject: `return $this->subject($this->title)` - Queue: No ShouldQueue declaration. send - Recipient, trigger and usage evidence: - `app/Http/Controllers/FinancialServices/CuraselConrtroller.php:145`, function `handleWebHook`, send: `$description = 'Dear customer, your insurance policy was created. Amount due '.$order['currency'].number_format($order['amount_due']); Mail::to($customer['email'])->send(new \App\Mail\insuranceActivity('Policy Created', $description)); } }` - Data bindings and derived links: `->markdown('emails.insuranceActivity', ['title' => $this->title, 'description' => $this->description]);` Template: `resources/views/emails/insuranceActivity.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$title`; `$description` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### internalAccountNotification Request internal accountant pairing for a subscribed business. - Status: **referenced**. Implementation: `app/Mail/internalAccountNotification.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Billing/AppSubscriptionsController.php:170`, function `subscribe`, queued: `if (app()->environment('production')) { Mail::to('[address omitted]') ->bcc(['[address omitted]', '[address omitted]']) ->queue(new internalAccountNotification($business, $user, $has_accountant, $appbill)); } Mail::to($user->email) ->queue(new accounttantRequest($plan, $user));` - Data bindings and derived links: `$data['business'] = $this->b;`; `$data['user'] = $this->u;`; `$data['has_accountant'] = $this->has_accountant;`; `$data['plan'] = $this->plan;` Template: `resources/views/email/accountrequest/internalnotification.blade.php:1` - Shared components/layouts: `mail::message`, `mail::panel`, `mail::promotion`, `mail::button` - Dynamic content expressions: `$plan->planname`; `$business->name`; `$business->address`; `$business->email`; `$business->phone_number`; `$business->created_at`; `$user->first_name.' '.$user->last_name`; `$user->email`; `$user->phone_number`; `$user->created_at`; `config('app.name')` - Conditional/loop source: `@if($has_accountant)` - Action destinations: `@component('mail::button', ['url' => 'https://xxxyydd234.builtaccounting.com/business/'.$business->id])` ### invoice Send an invoice to a customer with a view or payment-enabled action and PDF. - Status: **referenced**. Implementation: `app/Mail/invoice.php:1`. - Subject: `->subject('Invoice #'.$this->invoice->invoice_number);` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: States: can_pay toggles “View & Pay” versus “View Invoice”; message is optional; send_attachment adds invoice attachments, while the invoice PDF is always attached. invoice->invoice_color is merchant-controlled styling. send_tome is accepted by the constructor but is not consumed in build(). invoice->link is the current email action; the legacy job constructs button.link using enc_id. Preserve the distinction. The local send() override records transport acceptance after parent::send(), not mailbox delivery. - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:328`, function `sendinvoice`, queued: `foreach ($emails as $email) { Mail::to($email) ->queue(new \App\Mail\invoice($invoice, $payment_enabled, $request->send_tome, $business, $message, $send_attachment)); } } return response()->json(['message' => 'Invoice sent']);` - `app/Http/Controllers/Income/invoicesController.php:3339`, function `makeCopy`, queued: `$payment_enabled = UtilityRepository::hasWallet($old_invoice->business_id); Mail::to($old_invoice->customer->business_email) ->queue(new \App\Mail\invoice($new_invoice, $payment_enabled, 0, $business, '')); } } return $data;` - `app/Jobs/SendSelectedInvoices.php:84`, function `handle`, queued: `->where('status', '<>', 'suspended')->exists(); Mail::to($invoice->customer->business_email) ->queue(new invoice($invoice, $payment_enabled, false, $business, $this->message, $this->send_attachments)); } else { if (config('app.env') == 'production') {` - Data bindings and derived links: `SendInvoiceStatus::firstOrCreate(['invoice_id' => $this->invoice->id]);`; `$data['invoice'] = $this->invoice;`; `$data['business'] = $this->business;`; `$data['index'] = 1;`; `$data['taxes'] = $this->invoice->taxes;`; `$data['send_attachment'] = $this->send_attachment;`; `'invoice' => $this->invoice,`; `'can_pay' => $this->can_pay,`; `'business' => $this->business,`; `'message' => $this->message,`; `$data['attachments'] = $attachments;` - Attachments/PDF views: `$pdf = UtilityRepository::shotToPDF($data, 'PDF.invoice_new');`; `$mail->attachData($pdf, 'invoice_#'.$this->invoice->invoice_number.'.pdf', ['mime' => 'application/pdf'])`; `$mail->attach($attachment->url, `` Template: [resources/views/emails/invoice/invoice.blade.php:1` - Shared components/layouts: `mail::message`, `mail::promotion` - Dynamic content expressions: `$invoice->invoice_number`; `$business->name`; `$invoice->end_date`; `$invoice->fx_currency.number_format($invoice->amount_due,2)`; `$invoice->link`; `$invoice->invoice_color`; `$can_pay ? "View & Pay" : "View Invoice"`; `$message` - Conditional/loop source: `@if($message)` - Action destinations: `{{$invoice->link}}` - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### invoiceMail Legacy invoice test Mailable. - Status: **apparently unused**. Implementation: `app/Mail/invoiceMail.php:1`. - Subject: `->subject('Test');` - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `public $pdf = null;`; `public $invoice = null;`; `public $business = null;`; `public $user = null;`; `public $country = null;`; `public $other_mail = '';`; `$data['country'] = $this->country;`; `$data['invoiceMail'] = $this->invoice;`; `$data['current_business'] = $this->business;`; `$data['index'] = 1;`; `$data['taxes'] = $taxes;` Template: `resources/views/mails/invoice.blade.php:1` - Shared components/layouts: `mailtemplate::emails.default` - Dynamic content expressions: `$business->name`; `$currency->symbol`; `number_format($invoice->amount_due,2)`; `date_format(date_create($invoice->end_date),'d-M-Y')`; `$business->phone_number`; `$business->address`; `$business->email` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### passwordReset Send the custom API password reset instructions and one-use link. - Status: **referenced**. Implementation: `app/Mail/passwordReset.php:1`. - Subject: `->subject('Password Reset');` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: The email says one use only and expires in five minutes. Preserve the enter/confirm/submit instructions, unsolicited-request notice and visible fallback URL. app/Mail/ResetPassword.php declares ResetPassword, a different word order from passwordReset, not a case-only collision. The scaffold references emails.users.resetpassword and has no discovered construction; keep the referenced passwordReset sender separate and verify the target's exact class/view path rather than adding another reset flow. - Recipient, trigger and usage evidence: - `app/Http/Controllers/Auth/AuthController.php:771`, function `sendresetlink`, queued: `$link = config('app.url').'/confirmreset/'.encrypt($new_request->id); Mail::to($email)->queue(new \App\Mail\passwordReset($link)); $data['title'] = 'Reset request successful'; $data['description'] = 'Your reset request was successful, a reset link was sent to '.$email; $data['link'] = null; $data['link_text'] = '';` - Data bindings and derived links: `public $link;`; `$this->link = $link;`; `return $this->markdown('emails.users.passwordReset', ['link' => $this->link])` Template: `resources/views/emails/users/passwordReset.blade.php:1` - Shared components/layouts: `mail::message`, `mail::button` - Dynamic content expressions: `$link` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => $link])` ### paymentRecieved Notify the business user of an invoice payment and charges. - Status: **referenced**. Implementation: `app/Mail/paymentRecieved.php:1`. - Subject: `->subject('Payment Received');` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Income/paymentsController.php:386`, function `completeMomopayment`, queued: `$email_charges = $has_wallet ? 0 : $charge_incedis; Mail::to($user->email) ->queue(new paymentRecieved($invoice, $transRef ?: $ref, $transaction->amount, $charge_incedis, $invoice->customer, $description, $email_charges)); }` - `app/Http/Controllers/Income/paymentsController.php:753`, function `completeCardPayment`, queued: `$email_charges = $has_wallet ? 0 : $charge_incedis; Mail::to($user->email) ->queue(new paymentRecieved($invoice, $reference, $paymentTransaction->amount, $charge_incedis, $invoice->customer, $description, $email_charges)); }` - Data bindings and derived links: `$data['invoice'] = $this->invoice;`; `$data['reference'] = $this->reference;`; `$data['amount'] = $this->amount;`; `$data['charges'] = $this->charges;`; `$data['customer'] = $this->customer;`; `$data['description'] = $this->description;`; `$data['charge'] = $this->charge;` Template: `resources/views/emails/invoice/paymentRecieved.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$invoice->base_currency.' '.number_format($amount,2)`; `$customer->business_name`; `$reference`; `$description`; `$invoice->base_currency.number_format($amount,2)`; `$invoice->base_currency.' '.number_format($charge,2)`; `$invoice->base_currency.' '.number_format($amount-$charge,2)`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### payslip Send an employee payslip and attached PDF. - Status: **referenced**. Implementation: `app/Mail/payslip.php:1`. - Subject: `->subject('payslip for '.$run_date_string)` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:444`, function `sendpayslip`, queued: `$email = trim($payslip->employee->email); Mail::to($email)->queue(new payslip($payslip)); return \response()->json($payslip); }` - `app/Http/Controllers/General/emailsController.php:463`, function `sendpayslips`, queued: `if ($item->employee->email) { Mail::to($item->employee->email)->queue(new payslip($item)); } }` - Data bindings and derived links: `$data['payslip'] = $this->payslip;`; `$data['employee'] = $this->payslip->employee;`; `$data['payrun'] = Payrun::find($this->payslip->payrun_id);`; `$data['business'] = Business::find($data['payrun']->business_id);`; `$data['payroll_settings'] = $data['business']->payroll_settings;`; `$data['endorse'] = Endosment::where('business_id', $data['business']->id)->first();`; `$business = Business::find($data['employee']->business_id);`; `$run_date_string = date('F, Y', strtotime($data['payrun']->run_date));`; `->from(config('mail.from.address'), $data['payroll_settings']->Company_name);` - Attachments/PDF views: `$pdf = SnappyPdf::loadView(Payrun::PayslipView($business->country_id), $data);`; `->attachData($pdf->output(), 'Payslip_'.$run_date_string.'.pdf')` Template: `resources/views/emails/payroll/payslip.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$payslip->employee->first_name`; `date('F, Y', strtotime($payrun->run_date))`; `$business->currency->symbol.number_format($payslip->net_salary,2)`; `$business->name` - Conditional/loop source: `@if($payslip->employee->email)` - Action destinations: No explicit action URL found. ### quote Send a quote to a customer and attach its PDF. - Status: **referenced**. Implementation: `app/Mail/quote.php:1`. - Subject: `->subject('Quote #'.$this->quote->quote_number)` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:410`, function `sendquote`, queued: `if (count($other_emails) > 0) { Mail::to($quote->customer->business_email) ->bcc($other_emails) ->queue(new \App\Mail\quote($quote, $business, $message)); } else { Mail::to($quote->customer->business_email) ->queue(new \App\Mail\quote($quote, $business, $message));` - `app/Http/Controllers/General/emailsController.php:414`, function `sendquote`, queued: `} else { Mail::to($quote->customer->business_email) ->queue(new \App\Mail\quote($quote, $business, $message)); } } else { if (count($other_emails) > 0) {` - `app/Http/Controllers/General/emailsController.php:422`, function `sendquote`, queued: `if (count($other_emails) > 0) { Mail::to($other_emails[0]) ->bcc($other_emails) ->queue(new \App\Mail\quote($quote, $business, $message)); } } }` - Data bindings and derived links: `$data['quote'] = $this->quote;`; `$data['current_business'] = $this->business;`; `$data['currency'] = Currency::find($this->business->currency_id);`; `$data['index'] = 1;`; `$data['taxes'] = $this->quote->taxes;`; `$data['message'] = $this->message;` - Attachments/PDF views: `$pdf = Pdf::loadView('PDF.quote', $data);`; `->attachData($pdf->output(), 'Quote_#'.$this->quote->quote_number.'.pdf');` Template: `resources/views/emails/quote/quote.blade.php:1` - Shared components/layouts: `mail::message`, `mail::promotion` - Dynamic content expressions: `$quote->quote_number`; `$current_business->name`; `$quote->created_at`; `$quote->valid_until`; `$quote->fx_currency.number_format($quote->amount_due,2)`; `$quote->link`; `$quote->invoice_color`; `$message` - Conditional/loop source: `@if($message)` - Action destinations: `{{$quote->link}}` - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### salesReciept Send a sales receipt with PDF. - Status: **referenced**. Implementation: `app/Mail/salesReciept.php:1`. - Subject: `->subject('Sales receipt #'.$this->sale->sales_number);` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:530`, function `sendreciept`, queued: `} Mail::to($request->email) ->queue(new salesReciept($sale)); return response()->json(['message' => 'Receipt sent successfully']); }` - Data bindings and derived links: `$data['link'] = config('app.url').'/viewreceipt/'.$this->sale->enc_id;`; `$data['sale'] = $this->sale;`; `$data['sale']->items = SaleItem::where('sale_id', $this->sale->id)->get();`; `$data['business'] = $this->business;`; `->from(config('mail.from.address'), $data['business']->name)` - Attachments/PDF views: `$pdf = Pdf::loadView('PDF.salesreceipt', $data);`; `->attachData($pdf->output(), 'Receipt_#'.$this->sale->sales_number.'.pdf')` Template: `resources/views/emails/invoice/salesReciept.blade.php:1` - Shared components/layouts: `mail::message`, `mail::panel`, `mail::button` - Dynamic content expressions: `$sale->sales_number`; `$business->name`; `$sale->entry_date`; `$business->currency->symbol`; `number_format($sale->amount_due,2)` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => $link,'color'=>'green'])` ### ssnit2report Send tier-two social security contributions and attachment. - Status: **referenced**. Implementation: `app/Mail/ssnit2report.php:1`. - Subject: `->subject('Tier2 Social Security contributions for '.$month)` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:501`, function `sendssnit2`, queued: `'email' => 'required\\|email:dns', ]); Mail::to($request->email) ->queue(new ssnit2report(Payrun::find($id))); } public function sendtier3(Request $request, $id) {` - Data bindings and derived links: `$data['payslips'] = PayRunIitem::where('payrun_id', $this->payrun->id)->get();`; `$data['payrun'] = $this->payrun;`; `$data['payroll_settings'] = PayrollSettings::where('business_id', $this->payrun->business_id)->first();`; `$data['business'] = Business::find($this->payrun->business_id);`; `->from(config('mail.from.address'), $data['payroll_settings']->Company_name);` - Attachments/PDF views: `$pdf = SnappyPdf::loadView('tier2', $data);`; `->attachData($pdf->output(), 'Tier2_social_security_controbutions.pdf')` Template: `resources/views/emails/payroll/ssnit2report.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$payroll_settings->Company_name`; `date('F, Y', strtotime($payrun->run_date))`; `$business->address`; `$business->phone_number` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### ssnitreport Send social security contributions and attachment. - Status: **referenced**. Implementation: `app/Mail/ssnitreport.php:1`. - Subject: `->subject('Social security contributions report for '.$month)` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:490`, function `sendssnit`, queued: `]); Mail::to($request->email) ->queue(new ssnitreport(Payrun::find($id))); } public function sendssnit2(Request $request, $id) {` - Data bindings and derived links: `$data['payslips'] = PayRunIitem::where('payrun_id', $this->payrun->id)->get();`; `$data['payrun'] = $this->payrun;`; `$data['business'] = $business;`; `$data['payroll_settings'] = $business->payroll_settings;`; `$data['business'] = $business;`; `->from(config('mail.from.address'), $data['payroll_settings']->Company_name)` - Attachments/PDF views: `->attach($ex, ['as' => 'Social_security_report.xlsx']);` Template: `resources/views/emails/payroll/ssnitreport.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$payroll_settings->Company_name`; `$payroll_settings->social_security_label`; `date('F, Y', strtotime($payrun->run_date))`; `$business->address`; `$business->phone_number` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### subscriptionFailed Explain a failed subscription or upgrade attempt. - Status: **referenced**. Implementation: `app/Mail/subscriptionFailed.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/Billing/AppSubscriptionsController.php:390`, function `store`, queued: `} Mail::to($request->user('api')->email) ->queue(new subscriptionFailed($transaction_verification['message'])); return response($transaction_verification['message']); }` - Data bindings and derived links: `return $this->markdown('emails.users.subscriptionFailed', ['message' => $this->message]);` Template: `resources/views/emails/users/subscriptionFailed.blade.php:1` - Shared components/layouts: `mail::message`, `mail::panel`, `mail::promotion`, `mail::button` - Dynamic content expressions: `$message`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `@component('mail::button', ['url' => ''])` ### subscriptionNotification Confirm subscription and show billing cycle and amount/tax details. - Status: **referenced**. Implementation: `app/Mail/subscriptionNotification.php:1`. - Subject: `->subject('Subscription Successful');` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: One template serves subscriber confirmation and internal copies. Monthly versus multi-month cycles differ. The GH branch calculates subtotal, VAT 15%, NHIL 2.5%, GETFund 2.5% from plan.amount; the other branch shows amount only. These are existing code rules, not a verification of current tax law. Internal copies have production/country guards. The old mails.subscriptionnotification also contains a no-automatic-charge notice that is absent from the current template; do not merge legacy claims without confirmation. - Recipient, trigger and usage evidence: - `app/Http/Controllers/Billing/AppSubscriptionsController.php:184`, function `subscribe`, queued: `} Mail::to($user->email)->bcc('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); if (app()->environment('production')) { Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency));` - `app/Http/Controllers/Billing/AppSubscriptionsController.php:188`, function `subscribe`, queued: `if (app()->environment('production')) { Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); Mail::to('[address omitted]')` - `app/Http/Controllers/Billing/AppSubscriptionsController.php:191`, function `subscribe`, queued: `->queue(new subscriptionNotification($user, $appbill, $business, $currency)); Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); Mail::to('[address omitted]')` - `app/Http/Controllers/Billing/AppSubscriptionsController.php:194`, function `subscribe`, queued: `->queue(new subscriptionNotification($user, $appbill, $business, $currency)); Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); }` - `app/Http/Controllers/Billing/AppSubscriptionsController.php:197`, function `subscribe`, queued: `->queue(new subscriptionNotification($user, $appbill, $business, $currency)); Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); } if (app()->environment('production')) {` - `app/Http/Controllers/Billing/AppSubscriptionsController.php:207`, function `subscribe`, queued: `if ($business->country && strtolower($business->country->code) == 'ke') { Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); }` - `app/Http/Controllers/Billing/AppSubscriptionsController.php:217`, function `subscribe`, queued: `if ($business->country && strtolower($business->country->code) == 'sl') { Mail::to('[address omitted]') ->queue(new subscriptionNotification($user, $appbill, $business, $currency)); } } if ($coupon_applied) {` - Data bindings and derived links: `$data['user'] = $this->user;`; `$data['plan'] = $this->plan;`; `$data['business'] = $this->business;`; `$plan = SubscriptionPlan::where('country_id', $data['business']->country_id)->first();`; `'amount' => $this->plan->add_ons['employee_extension']['amount'],`; `'quantity' => $this->plan->add_ons['employee_extension']['extraNumber'],`; `'amount' => $this->plan->add_ons['onsite_visits']['amount'],`; `$data['extraAmount'] = $otherAmount;`; `$data['extensions'] = $extensions;`; `$data['currency'] = $this->currency ?? $billplan->currency_code;` - Attachments/PDF views: `$pdf = Pdf::loadView('PDF.user.invoice', $data);`; `->attachData($pdf->output(), 'subscription_invoice.pdf')` Template: `resources/views/emails/users/subscriptionNotification.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$user->first_name`; `$plan->planname`; `$business->name`; `$plan->subscription_cycle`; `$currency.number_format($base, 2)`; `$currency.number_format($vat, 2)`; `$currency.number_format($nhil, 2)`; `$currency.number_format($getfund, 2)`; `$currency.number_format($plan->amount, 2)`; `$currency.number_format($plan->amount,2)`; `config('app.name')` - Conditional/loop source: `@if($plan->cycle == 1)`; `@else`; `@if ($business->country->currency_symbol == 'GH')` - Action destinations: No explicit action URL found. ### supplierTransactions Send a supplier transaction statement and PDF. - Status: **referenced**. Implementation: `app/Mail/supplierTransactions.php:1`. - Subject: `->subject('Transactions Statement from '.$this->data['from'].' to '.$this->data['to'])` - Queue: No ShouldQueue declaration. queued - Content and workflow notes: Date range and transaction rows with optional message and PDF attachment; preserve supplier-specific data rather than copying customer fields. - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:258`, function `suppliertransactions`, queued: `Mail::to($base_email) ->bcc($other_emails) ->queue(new supplierTransactions($data)); return response('Transactions sent'); } catch (Exception $e) { throw new Exception($e->getMessage());` - Data bindings and derived links: See constructor and template expressions below. - Attachments/PDF views: `$pdf = Pdf::loadView('PDF.suppliers.transactions', $this->data);`; `->attachData($pdf->output(), 'Transactions_statement.pdf');` Template: `resources/views/emails/suppliers/transactions.blade.php:1` - Shared components/layouts: `mail::message`, `mail::promotion` - Dynamic content expressions: `$business->name`; `$from`; `$to`; `\Carbon\Carbon::now()`; `$transactions_count`; `$currency->code`; `number_format($total_amount,2)`; `number_format($total_paid,2)`; `number_format($total_owing,2)`; `$transaction->bill_id??''`; `$currencyCode.number_format($transaction->amount_due,2)`; `$currencyCode.number_format($transaction->amount_paid,2)`; `$transaction->purchase_date`; `$transaction->due_date`; `$message` - Conditional/loop source: `@if($from && $to)`; `@else`; `@foreach($transactions as $transaction)`; `@if($i<=10)`; `@if($message)` - Action destinations: No explicit action URL found. - Raw HTML output is present in the baseline. Integration must define trusted/sanitized content, or render escaped text with preserved line breaks; never treat untrusted text as HTML. ### taxreport Send a country-specific payroll income-tax report PDF. - Status: **referenced**. Implementation: `app/Mail/taxreport.php:1`. - Subject: `->subject($data['payroll_settings']->Company_name.': Income tax report for the month of '.$month)` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:478`, function `sendtaxreport`, queued: `'email' => 'required\\|email:dns', ]); Mail::to($request->email)->queue(new taxreport(Payrun::find($id))); } public function sendssnit(Request $request, $id) {` - Data bindings and derived links: `public $payrun;`; `$data['payslips'] = PayRunIitem::where('payrun_id', $this->payrun->id)->get();`; `$data['payrun'] = $this->payrun;`; `$business = Business::find($data['payrun']->business_id);`; `$data['business'] = $business;`; `$data['payroll_settings'] = PayrollSettings::where('business_id', $this->payrun->business_id)->first();`; `$month = date('F, Y', strtotime($data['payrun']->run_date));`; `$file_name = $data['payroll_settings']->Company_name.'_tax_report_'.$month;`; `->subject($data['payroll_settings']->Company_name.': Income tax report for the month of '.$month)`; `->replyTo($data['business']->email ?? $user->email, $data['payroll_settings']->Company_name)`; `->from(config('mail.from.address'), $data['payroll_settings']->Company_name)` - Attachments/PDF views: `$pdf = Pdf::loadView(payrollSettingsController::get_tax_report_PDF($business->country->code), $data)->setPaper('a4', 'landscape');`; `->attachData($pdf->output(), $file_name);` Template: `resources/views/emails/payroll/taxreport.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$business->payroll_settings->Company_name`; `date('F, Y', strtotime($payrun->run_date))`; `$business->address`; `$business->phone_number` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### tier3 Send tier-three social security contributions and PDF. - Status: **referenced**. Implementation: `app/Mail/tier3.php:1`. - Subject: `->subject('Tier3 Social Security contributions for '.$month)` - Queue: No ShouldQueue declaration. queued - Recipient, trigger and usage evidence: - `app/Http/Controllers/General/emailsController.php:512`, function `sendtier3`, queued: `]); Mail::to($request->email) ->queue(new tier3(Payrun::find($id))); } public function sendreciept(Request $request, $id) { $request->validate([` - Data bindings and derived links: `$data['payslips'] = PayRunIitem::where('payrun_id', $this->payrun->id)->get();`; `$data['payrun'] = $this->payrun;`; `$data['payroll_settings'] = PayrollSettings::where('business_id', $this->payrun->business_id)->first();`; `$data['business'] = Business::find($this->payrun->business_id);`; `->from(config('mail.from.address'), $data['payroll_settings']->Company_name);` - Attachments/PDF views: `$pdf = Pdf::loadView('PDF.tier3', $data);`; `->attachData($pdf->output(), 'Tier3_social_security_controbutions.pdf')` Template: `resources/views/emails/payroll/tier3.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$payroll_settings->Company_name`; `date('F, Y', strtotime($payrun->run_date))`; `$business->address`; `$business->phone_number`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ### welcome Legacy personal onboarding welcome email. - Status: **apparently unused**. Implementation: `app/Mail/welcome.php:1`. - Subject: No explicit subject found; Laravel derives it from the Mailable class unless a caller supplies one. - Queue: No ShouldQueue declaration. No construction found; no delivery mode established. - Recipient, trigger and usage evidence: - No executable construction resolving to this App\Mail class found in app/routes/bootstrap. Imports, comments and same-named Eloquent models were not counted. Intended recipient can only be inferred from the purpose/template. - Data bindings and derived links: `return $this->markdown('emails.users.welcome', ['user' => $this->user]);` Template: `resources/views/emails/users/welcome.blade.php:1` - Shared components/layouts: Self-contained HTML; no Blade component directive found. - Dynamic content expressions: `$user->first_name` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: `https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i`; `https://app.built.africa/`; `https://support.built.africa/en/`; `https://calendly.com/builtaccounting/demo`; `https://support.built.africa/`; `https://www.youtube.com/watch?v=t3DsdKX1wjc&list=PLimnqt59Y0L4C-pXIVRgKloegOADta6S0`; `https://built.africa/faqs`; `https://www.facebook.com/builtaccounting`; `https://twitter.com/built_africa`; `https://www.instagram.com/built.africa/`; `https://www.linkedin.com/company/built-accounting`; `https://play.google.com/store/apps/details?id=com.builtaccounting.app`; `https://apps.apple.com/gh/app/built-accounting/id1547855525` ### welcomeEmployee Give a newly registered employee access details for their payroll portal. - Status: **referenced**. Implementation: `app/Mail/welcomeEmployee.php:1`. - Subject: `->subject($this->business->name.': Your Registration')` - Queue: No ShouldQueue declaration. queued; rendered for external bulk sender - Content and workflow notes: Multiple callers share this template, including a bulk-import path that renders the Mailable and submits its HTML to an external scheduler. The existing contract includes a password; no password values were read or copied. A redesign alone must not silently change the account-access workflow. - Recipient, trigger and usage evidence: - `app/Http/Controllers/Payroll/employeesController.php:348`, function `store`, queued: `if ($testEmail) { Mail::to($employee->email) ->queue(new welcomeEmployee($t, $business->payroll_settings, $business, $employee)); } return response()->json($employee);` - `app/Imports/EmployeeImport.php:57`, function `collection`, queued: `if ($employee->email) { Mail::to($employee->email)->queue(new welcomeEmployee($password, $business->payroll_settings, $business, $employee)); } }` - `app/Imports/EmployeeImportKE.php:65`, function `collection`, queued: `$employee->save(); if ($employee->email) { Mail::to($employee->email)->queue(new welcomeEmployee($password, $business->payroll_settings, $business, $employee)); } } }` - `app/Jobs/ImportEmployeesBulkJob.php:186`, function `handle`, rendered for external bulk sender: `return [ 'email' => $employee->email, 'content' => (new welcomeEmployee( $sender['password'], $payrollSettings, $business, $employee ))->build()->render(),` - Data bindings and derived links: `$data['employee'] = $this->employee;`; `$data['email'] = $this->employee->email;`; `$data['password'] = $this->password;`; `$data['payroll_settings'] = $this->payroll_settings;` Template: `resources/views/emails/payroll/welcomeEmployee.blade.php:1` - Shared components/layouts: `mail::message` - Dynamic content expressions: `$employee->first_name`; `$payroll_settings->Company_name`; `$email`; `$password`; `config('app.name')` - Conditional/loop source: No explicit Blade condition/loop found. - Action destinations: No explicit action URL found. ## Additional and legacy email views These views are not the primary template of a Mailable above. References include direct sends, legacy jobs, component includes and scheduler rendering. A view reference inside an untraced job is weaker evidence than a traced dispatch. ### emails.users.welcome-old - Template: `resources/views/emails/users/welcome-old.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate welcome-old email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mail::message` - Dynamic content: `$user->first_name` - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.accountantinvite - Template: `resources/views/mails/accountantinvite.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate accountantinvite email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$business->name` - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.accountantrequest - Template: `resources/views/mails/accountantrequest.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate accountantrequest email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.blitz` - Dynamic content: `$user->first_name`; `$plan` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/accountantnotifiactionJob.php:42` `{ $this->user = auth('api')->user(); $mailer = new Mail; $mailer->send('mails.accountantrequest', ['user' => $this->user, 'plan' => $this->plan], function ($message) { $message->replyTo('[address omitted]', 'Built Accounting'); $message->to($this->user->email, $this->user->first_name)->subject('Built Virtual Support'); }); } }` ### mails.cancelsubscription - Template: `resources/views/mails/cancelsubscription.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate cancelsubscription email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.blitz` - Dynamic content: `$bill->plan->name`; `$bill->start_date`; `$bill->end_date` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/cancelationnotificationJob.php:45` `$mailer = new Mail; $this->email = auth('api')->user()->email; $this->name = auth('api')->user()->first_name; $mailer->send('mails.cancelsubscription', $this->bill, function ($message) { $message->replyTo('[address omitted]', 'Built Accounting'); $message->to($this->email, $this->name)->subject('Built subscription canceled'); }); } }` ### mails.changeinvite - Template: `resources/views/mails/changeinvite.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate changeinvite email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$user->first_name`; `$business->name` - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.getstarted - Template: `resources/views/mails/getstarted.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate getstarted email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.blitz` - Dynamic content: `$first_name` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/sendwelcomeJob.php:45` `{ $mailer = new Mail; $this->email = $this->user->email; $data['first_name'] = $this->user->first_name; $mailer->send('mails.getstarted', $data, function ($message) { $message->from('[address omitted]', 'Edward from Built'); $message->replyTo('[address omitted]', 'Built Accounting Support'); $message->to($this->email, $this->user->first_name)->subject('Welcome to Built'); }); } }` ### mails.grantpayroll - Template: `resources/views/mails/grantpayroll.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate grantpayroll email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$business->name` - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.invitation - Template: `resources/views/mails/invitation.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate invitation email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$business->name` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/InvitationJob.php:56` `$data['button'] = $button; $data['business'] = $this->data['business']; $this->business = $this->data['business']; $mailer->send('mails.invitation', $data, function ($message) { $message->to($this->invite->user_email); $message->subject('Confirm Invitation from '.$this->business->name); }); } }` ### mails.inviteconfirmation - Template: `resources/views/mails/inviteconfirmation.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate inviteconfirmation email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$user->first_name." ".$user->last_name`; `$business->name` - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.passwordreset - Template: `resources/views/mails/passwordreset.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate passwordreset email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: None found. - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.payment_error - Template: `resources/views/mails/payment_error.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate payment_error email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$business->name`; `$currency->symbol`; `number_format($balance/100,2)`; `number_format($amount,2)` - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.payment_limit - Template: `resources/views/mails/payment_limit.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Internal bill-transfer failure alert after collection; recipient address omitted. - Queue/trigger: Two direct Mail::send calls from billsController; synchronous Laravel call. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$description`; `$currency->symbol.number_format($amount,2)`; `$business->name`; `isset($invoice) ? $invoice->invoice_number : "bill"` - Conditions: None found. - Actions/subject/sender context: `app/Http/Controllers/Expenses/billsController.php:559` `$data['amount'] = $request->amount_paid; $data['description'] = $balance_response['message']; Mail::send('mails.payment_limit', $data, function ($message) { $message->to('[address omitted]') ->subject($this->title); }); $ledger = new Leisure(` 'account_id' => $request->payment_accountID,`; [app/Http/Controllers/Expenses/billsController.php:684` `$this->title = 'Payment for bill with number '.$bill->bill_id.' (online payment) '; $data['description'] = $res['message']; Mail::send('mails.payment_limit', $data, function ($message) { $message->to('[address omitted]') ->subject($this->title); }); } $bill = Bill::with('supplier') ->with('attachments')` ### mails.payment_sent - Template: `resources/views/mails/payment_sent.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate payment_sent email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.blitz` - Dynamic content: `$invoice->fx_currency.' '.number_format($amount,2)`; `$customer->business_name`; `$reference`; `$description`; `$invoice->fx_currency.number_format($amount,2)`; `$invoice->fx_currency.' '.number_format($charges,2)`; `$invoice->fx_currency.' '.number_format($amount-$charges,2)` - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.payslip - Template: `resources/views/mails/payslip.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate payslip email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$payslip->employee->first_name`; `date('F, Y', strtotime($payrun->run_date))`; `$business->currency->symbol.number_format($payslip->net_salary,2)` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/sendpayslipJob.php:59` `PDF::setOptions(['dpi' => 50, 'defaultFont' => 'sans-serif', 'fontHeightRatio' => 0.2]); $this->pdf = PDF::loadView('PDF.payslip', $data); $mailer = new Mail; $mailer->send('mails.payslip', $data, function ($message) use ($data) { $from = config('app.mail_from'); $message->from($from, $data['payroll_settings']->Company_name); $message->to($data['payslip']->employee->email); $message->subject($data['payroll_settings']->Company_name.'-payslip for the month of '.date('F, Y', strtotime($data['payrun']->run_date))); $message->replyTo($data['business']->email, $data['business']->name); $message->attachData($this->pdf->output(), 'payslip.pdf'); });` ### mails.quote - Template: `resources/views/mails/quote.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy quote to quote.customer.business_email, optional business copy; PDF and View Quote action. - Queue/trigger: Referenced from a ShouldQueue legacy job; no active construction or dispatch of mailinvoiceJob/mailquote/welcommailJob found. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$current_business->name`; `$current_business->currency->symbol`; `number_format($quote->amount_due,2)`; `date_format(date_create($quote->end_date),'d-M-Y')`; `$current_business->phone_number`; `$current_business->address`; `$current_business->email` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/mailquote.php:71` `$data['button'] = $button; $this->pdf = PDF::loadView('PDF.quote', $data); $mailer = new Mail; $mailer->send('mails.quote', $data, function ($message) { $from = config('app.mail_from'); $message->from($from, $this->business->name); $message->to($this->quote->customer->business_email); if ($this->request['send_tome']) { if ($this->business->email) { $message->bcc($this->business->email); }` ### mails.receipt - Template: `resources/views/mails/receipt.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate receipt email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$invoice->invoice_number`; `$date_paid`; `$method`; `$business->name`; `$business->phone_number`; `$business->address`; `$business->email`; `$business->currency->symbol`; `number_format($amount,2)` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/sendreceiptJob.php:70` `$data['business'] = Business::find($this->invoice->business_id); $this->business = $data['business']; $this->pdf = PDF::loadView('PDF.reciept', $data); $mailer->send('mails.receipt', $data, function ($message) use ($data) { $from = config('app.mail_from'); $message->from($from, $data['business']->name); $message->to($this->invoice->customer->business_email); $message->subject('Payment Receipt #'.$this->invoice->invoice_number); $message->replyTo($this->business->email, $this->business->name); $message->attachData($this->pdf->output(), 'Receipt_#'.$this->invoice->invoice_number.'.pdf'); }); }` ### mails.salesreciept - Template: `resources/views/mails/salesreciept.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate salesreciept email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$sale->sales_number`; `$sale->entry_date`; `$business->name`; `$business->phone_number`; `$business->address`; `$business->email`; `$business->currency->symbol`; `number_format($sale->amount_due,2)` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/sendsalesrecieptJob.php:82` `$data['business'] = $this->business; $mailer = new Mail; $this->pdf = PDF::loadView('PDF.salesreceipt', $data); $mailer->send('mails.salesreciept', $data, function ($message) use ($data) { $from = config('app.mail_from'); $message->from($from, $this->business->name); $message->to($this->email); $message->subject('Payment receipt from '.$this->business->name); $message->replyTo($this->user->email, $this->business->name); $message->attachData($this->pdf->output(), 'Receipt_'.$data['sale']->sales_number.'.pdf'); }); }` ### mails.ssnit - Template: `resources/views/mails/ssnit.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate ssnit email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$payroll_settings->Company_name`; `$payroll_settings->social_security_label`; `date('F, Y', strtotime($payrun->run_date))`; `$business->address`; `$business->phone_number` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/sendssnitJob.php:70` `$this->data['file_info'] = $ex; $mailer = new Mail; $mailer->send('mails.ssnit', $this->data, function ($message) { $message->from('[address omitted]', $this->data['payroll_settings']->Company_name); $message->to($this->data['email']); $message->subject($this->data['payroll_settings']->Company_name.': '.$this->data['payroll_settings']->social_security_label.' Contributions for the month of '.date('F, Y', strtotime($this->data['payrun']->run_date))); $message->replyTo($this->data['business']->email, $this->data['payroll_settings']->Company_name); $message->attach($this->data['file_info']['full']); }); }` ### mails.subscriptionnotification - Template: `resources/views/mails/subscriptionnotification.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate subscriptionnotification email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.blitz` - Dynamic content: `$user->first_name`; `$plan->planname`; `$plan->cycle`; `$business->currency->symbol.number_format($plan->amount,2)` - Conditions: `@if($plan->cycle == 1)`; `@else` - Actions/subject/sender context: `app/Jobs/sendsubnotificationJob.php:46` `$mailer = new Mail; $this->email = $this->data['user']->email; $mailer->send('mails.subscriptionnotification', $this->data, function ($message) { $message->replyTo('[address omitted]', 'Built Accounting'); $message->to($this->email, $this->data['user']->first_name)->subject('Built subscription'); }); } }` ### mails.taxreport - Template: `resources/views/mails/taxreport.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate taxreport email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$payroll_settings->Company_name`; `date('F, Y', strtotime($payrun->run_date))`; `$business->address`; `$business->phone_number` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/sendtaxreportJob.php:59` `$this->pdf = PDF::loadView(payrollSettingsController::get_tax_report_PDF($business->country->code), $data)->setPaper('a4', 'landscape'); $mailer = new Mail; $mailer->send('mails.taxreport', $data, function ($message) use ($data) { $message->from('[address omitted]', $data['payroll_settings']->Company_name); $message->to($this->data['email']); $message->subject($data['payroll_settings']->Company_name.': Income tax for the month of '.date('F, Y', strtotime($data['payrun']->run_date))); $message->replyTo($data['business']->email, $data['payroll_settings']->Company_name); $message->attachData($this->pdf->output(), 'taxreport.pdf'); }); }` ### mails.tier2 - Template: `resources/views/mails/tier2.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate tier2 email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$payroll_settings->Company_name`; `date('F, Y', strtotime($payrun->run_date))`; `$business->address`; `$business->phone_number` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/sendssnit2Job.php:56` `$this->pdf = PDF::loadView('PDF.tier2', $data); $mailer = new Mail; $mailer->send('mails.tier2', $data, function ($message) use ($data) { $message->from('[address omitted]', $data['payroll_settings']->Company_name); $message->to($this->data['email']); $message->subject($data['payroll_settings']->Company_name.': Tier2 Contributions for the month of '.date('F, Y', strtotime($data['payrun']->run_date))); $message->replyTo($data['business']->email, $data['payroll_settings']->Company_name); $message->attachData($this->pdf->output(), 'SSNIT.pdf'); }); }` ### mails.ungrantpayroll - Template: `resources/views/mails/ungrantpayroll.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate ungrantpayroll email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$business->name` - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### mails.verifyaccount - Template: `resources/views/mails/verifyaccount.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate verifyaccount email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$name` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/verifyaccountJob.php:58` `]; $data['button'] = $button; $data['name'] = $this->user->first_name; $mailer->send('mails.verifyaccount', $data, function ($message) { $message->to($this->user->email)->subject('Verify Your account'); }); } }` ### mails.welcome - Template: `resources/views/mails/welcome.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy signup welcome to the job user. - Queue/trigger: Referenced from a ShouldQueue legacy job; no active construction or dispatch of mailinvoiceJob/mailquote/welcommailJob found. - Shared layout/components: `mailtemplate::emails.campaign` - Dynamic content: `$name` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/welcommailJob.php:53` `$this->last_name = $this->user->last_name; $data['name'] = $this->user->first_name; $mailer->send('mails.welcome', $data, function ($message) { $message->to($this->email, $this->first_name.' '.$this->last_name)->subject('Welcome to Built Accounting'); }); } }` ### mails.welcomeemployee - Template: `resources/views/mails/welcomeemployee.blade.php:1`. Status: **referenced; reachability unresolved for legacy jobs**. - Purpose/recipient: Legacy or alternate welcomeemployee email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: `mailtemplate::emails.default` - Dynamic content: `$first_name`; `$payroll_settings->Company_name`; `$email`; `$password` - Conditions: None found. - Actions/subject/sender context: `app/Jobs/welcomeemployeeJob.php:51` `$data['last_name'] = $this->data['last_name']; $data['email'] = $this->data['email']; $data['password'] = $this->data['password']; $mailer->send('mails.welcomeemployee', $data, function ($message) use ($data) { $message->from('[address omitted]', $data['payroll_settings']->Company_name); $message->to($data['email']); $message->subject($data['payroll_settings']->Company_name.'- your payroll registration'); $message->replyTo($data['business']->email, $data['business']->name); }); }` ### vendor.maileclipse.templates.welcomeWallet - Template: `resources/views/vendor/maileclipse/templates/welcomeWallet.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate welcomeWallet email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: None found. - Dynamic content: None found. - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ### vendor.maileclipse.templates.welcomeWallet_plain_text - Template: `resources/views/vendor/maileclipse/templates/welcomeWallet_plain_text.blade.php:1`. Status: **apparently unused**. - Purpose/recipient: Legacy or alternate welcomeWallet_plain_text email; no independent live workflow established. - Queue/trigger: Not established without an executable caller. - Shared layout/components: None found. - Dynamic content: None found. - Conditions: None found. - Actions/subject/sender context: No executable caller found; subject and delivery behavior unresolved. ## Direct sends and legacy job contracts This section also covers views already listed under a Mailable: an unused Mailable does not make a directly sent view unused. All legacy job classes below implement ShouldQueue, but no executable construction or static dispatch reference for these legacy jobs was found in app/routes/bootstrap. Their queue contract exists; actual scheduling remains unresolved. ### Direct mails.payment_limit at app/Http/Controllers/Expenses/billsController.php - Status: **referenced**. Sender: `app/Http/Controllers/Expenses/billsController.php:559`. - Trigger: bill transfer failure path in billsController. - Recipient, subject, data, action and attachment contract: `$data['currency'] = Currency::find($current_business->currency_id);`; `$data['business'] = $current_business;`; `$data['amount'] = $request->amount_paid;`; `$data['description'] = $balance_response['message'];`; `$message->to('[address omitted]')`; `->subject($this->title);`; `$data['currency'] = Currency::find($current_business->currency_id);`; `$data['business'] = $current_business;`; `$data['amount'] = $request->amount_paid;`; `$data['description'] = $res['message'];`; `$message->to('[address omitted]')`; `->subject($this->title);`; `$data['bill'] = Bill::with('supplier')`; `$data['business'] = Business::find($data['bill']->business_id);`; `'link' => '/expenses/'.$bill->id,`; `$data['business_id'] = businessesController::get_current_business()->id;` ### Direct mails.payment_limit at app/Http/Controllers/Expenses/billsController.php - Status: **referenced**. Sender: `app/Http/Controllers/Expenses/billsController.php:684`. - Trigger: bill transfer failure path in billsController. - Recipient, subject, data, action and attachment contract: `$data['currency'] = Currency::find($current_business->currency_id);`; `$data['business'] = $current_business;`; `$data['amount'] = $request->amount_paid;`; `$data['description'] = $balance_response['message'];`; `$message->to('[address omitted]')`; `->subject($this->title);`; `$data['currency'] = Currency::find($current_business->currency_id);`; `$data['business'] = $current_business;`; `$data['amount'] = $request->amount_paid;`; `$data['description'] = $res['message'];`; `$message->to('[address omitted]')`; `->subject($this->title);`; `$data['bill'] = Bill::with('supplier')`; `$data['business'] = Business::find($data['bill']->business_id);`; `'link' => '/expenses/'.$bill->id,`; `$data['business_id'] = businessesController::get_current_business()->id;` ### Direct mails.accountantrequest at app/Jobs/accountantnotifiactionJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/accountantnotifiactionJob.php:42`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$message->replyTo('[address omitted]', 'Built Accounting');`; `$message->to($this->user->email, $this->user->first_name)->subject('Built Virtual Support');` ### Direct mails.cancelsubscription at app/Jobs/cancelationnotificationJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/cancelationnotificationJob.php:45`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$message->replyTo('[address omitted]', 'Built Accounting');`; `$message->to($this->email, $this->name)->subject('Built subscription canceled');` ### Direct mails.invitation at app/Jobs/InvitationJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/InvitationJob.php:56`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `'text' => 'Accept Invitation',`; `'link' => config('app.url').'/confirminvitation/'.encrypt($this->invite->id),`; `$data['button'] = $button;`; `$data['business'] = $this->data['business'];`; `$message->to($this->invite->user_email);`; `$message->subject('Confirm Invitation from '.$this->business->name);` ### Direct mails.invoice at app/Jobs/mailinvoiceJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/mailinvoiceJob.php:88`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['invoice'] = $this->invoice;`; `$data['business'] = $this->business;`; `$data['index'] = 1;`; `'text' => $label,`; `'link' => config('app.url').'/viewinvoice/'.$this->invoice->enc_id,`; `$data['button'] = $button;`; `$data['taxes'] = $this->invoice->taxes;`; `->subject($this->title);`; `$message->bcc($this->business->email);`; `$message->replyTo($this->business->email, $this->business->name);`; `$message->attachData($this->pdf->output(), 'invoice_'.$this->invoice->invoice_number.'.pdf');` ### Direct mails.quote at app/Jobs/mailquote.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/mailquote.php:71`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['quote'] = $this->quote;`; `$data['current_business'] = $this->business;`; `$data['index'] = 1;`; `$data['taxes'] = $this->quote->taxes;`; `'text' => 'View Quote',`; `'link' => config('app.url').'/viewquote/'.$this->quote->enc_id,`; `$data['button'] = $button;`; `$message->to($this->quote->customer->business_email);`; `$message->bcc($this->business->email);`; `$message->subject('Quote #'.$this->quote->quote_number);`; `$message->replyTo($this->business->email, $this->business->name);`; `$message->attachData($this->pdf->output(), $this->quote->quote_number.'.pdf');` ### Direct mails.payslip at app/Jobs/sendpayslipJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/sendpayslipJob.php:59`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['payslip'] = PayRunIitem::find($this->id);`; `$data['payrun'] = Payrun::find($data['payslip']->payrun_id);`; `$data['payroll_settings'] = PayrollSettings::where('business_id', $data['payrun']->business_id)->first();`; `$data['business'] = Business::find($data['payrun']->business_id);`; `$data['endorse'] = Endosment::where('business_id', $data['business']->id)->first();`; `$message->from($from, $data['payroll_settings']->Company_name);`; `$message->to($data['payslip']->employee->email);`; `$message->subject($data['payroll_settings']->Company_name.'-payslip for the month of '.date('F, Y', strtotime($data['payrun']->run_date)));`; `$message->replyTo($data['business']->email, $data['business']->name);`; `$message->attachData($this->pdf->output(), 'payslip.pdf');` ### Direct mails.receipt at app/Jobs/sendreceiptJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/sendreceiptJob.php:70`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$this->invoice = $data['invoice'];`; `$this->method = $data['method'];`; `$this->amount = $data['amount'];`; `$this->date_paid = $data['date_paid'];`; `'text' => 'View Receipt',`; `'link' => config('app.url').'/invoicereciept/'.encrypt($this->invoice->id),`; `$data['button'] = $button;`; `$data['invoice'] = $this->invoice;`; `$data['amount'] = $this->amount;`; `$data['method'] = $this->method;`; `$data['date_paid'] = $this->date_paid;`; `$data['business'] = Business::find($this->invoice->business_id);`; `$this->business = $data['business'];`; `$message->from($from, $data['business']->name);`; `$message->to($this->invoice->customer->business_email);`; `$message->subject('Payment Receipt #'.$this->invoice->invoice_number);`; `$message->replyTo($this->business->email, $this->business->name);`; `$message->attachData($this->pdf->output(), 'Receipt_#'.$this->invoice->invoice_number.'.pdf');` ### Direct mails.salesreciept at app/Jobs/sendsalesrecieptJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/sendsalesrecieptJob.php:82`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['sale'] = Sale::find($this->id);`; `'text' => 'View Receipt',`; `'link' => config('app.url').'/viewreceipt/'.encrypt($data['sale']->id),`; `'link' => '#',`; `$data['sale']->items = SaleItem::where('sale_id', $this->id)->get();`; `$data['button'] = $button;`; `$data['logo'] = $logo;`; `$data['business'] = $this->business;`; `$message->to($this->email);`; `$message->subject('Payment receipt from '.$this->business->name);`; `$message->replyTo($this->user->email, $this->business->name);`; `$message->attachData($this->pdf->output(), 'Receipt_'.$data['sale']->sales_number.'.pdf');` ### Direct mails.tier2 at app/Jobs/sendssnit2Job.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/sendssnit2Job.php:56`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['payslips'] = PayRunIitem::where('payrun_id', $this->data['id'])->get();`; `$data['payrun'] = Payrun::find($this->data['id']);`; `$data['payroll_settings'] = PayrollSettings::where('business_id', $data['payrun']->business_id)->first();`; `$data['business'] = Business::find($data['payrun']->business_id);`; `$message->from('[address omitted]', $data['payroll_settings']->Company_name);`; `$message->to($this->data['email']);`; `$message->subject($data['payroll_settings']->Company_name.': Tier2 Contributions for the month of '.date('F, Y', strtotime($data['payrun']->run_date)));`; `$message->replyTo($data['business']->email, $data['payroll_settings']->Company_name);`; `$message->attachData($this->pdf->output(), 'SSNIT.pdf');` ### Direct mails.ssnit at app/Jobs/sendssnitJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/sendssnitJob.php:70`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$message->to($this->data['email']);`; `$message->subject($this->data['payroll_settings']->Company_name.': '.$this->data['payroll_settings']->social_security_label.' Contributions for the month of '.date('F, Y', strtotime($this->data['payrun']->run_date)));`; `$message->replyTo($this->data['business']->email, $this->data['payroll_settings']->Company_name);` ### Direct mails.subscriptionnotification at app/Jobs/sendsubnotificationJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/sendsubnotificationJob.php:46`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$message->replyTo('[address omitted]', 'Built Accounting');`; `$message->to($this->email, $this->data['user']->first_name)->subject('Built subscription');` ### Direct mails.taxreport at app/Jobs/sendtaxreportJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/sendtaxreportJob.php:59`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['payslips'] = PayRunIitem::where('payrun_id', $this->data['id'])->get();`; `$data['payrun'] = Payrun::find($this->data['id']);`; `$business = Business::find($data['payrun']->business_id);`; `$data['business'] = $business;`; `$data['payroll_settings'] = $business->payroll_settings;`; `$message->from('[address omitted]', $data['payroll_settings']->Company_name);`; `$message->to($this->data['email']);`; `$message->subject($data['payroll_settings']->Company_name.': Income tax for the month of '.date('F, Y', strtotime($data['payrun']->run_date)));`; `$message->replyTo($data['business']->email, $data['payroll_settings']->Company_name);`; `$message->attachData($this->pdf->output(), 'taxreport.pdf');` ### Direct mails.getstarted at app/Jobs/sendwelcomeJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/sendwelcomeJob.php:45`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['first_name'] = $this->user->first_name;`; `$message->replyTo('[address omitted]', 'Built Accounting Support');`; `$message->to($this->email, $this->user->first_name)->subject('Welcome to Built');` ### Direct mails.verifyaccount at app/Jobs/verifyaccountJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/verifyaccountJob.php:58`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `'text' => 'Verify Account',`; `'link' => config('app.url').'/verifyaccount/'.encrypt($this->user->id),`; `$data['button'] = $button;`; `$data['name'] = $this->user->first_name;`; `$message->to($this->user->email)->subject('Verify Your account');` ### Direct mails.welcomeemployee at app/Jobs/welcomeemployeeJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/welcomeemployeeJob.php:51`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['payroll_settings'] = businessesController::get_current_business()->payroll_settings;`; `$data['business'] = businessesController::get_current_business();`; `$data['first_name'] = $this->data['first_name'];`; `$data['last_name'] = $this->data['last_name'];`; `$data['email'] = $this->data['email'];`; `$data['password'] = $this->data['password'];`; `$message->from('[address omitted]', $data['payroll_settings']->Company_name);`; `$message->to($data['email']);`; `$message->subject($data['payroll_settings']->Company_name.'- your payroll registration');`; `$message->replyTo($data['business']->email, $data['business']->name);` ### Direct mails.welcome at app/Jobs/welcommailJob.php - Status: **unresolved (view referenced by a job with untraced dispatch)**. Sender: `app/Jobs/welcommailJob.php:53`. - Trigger: handle() if this legacy job is dispatched; no project dispatch found. - Recipient, subject, data, action and attachment contract: `$data['name'] = $this->user->first_name;`; `$message->to($this->email, $this->first_name.' '.$this->last_name)->subject('Welcome to Built Accounting');` ## Shared templates, meaningful states and unresolved evidence - InfoMail has two product-import notification types sharing one template. Insurance order-created and claim-submitted notifications share their customer template with internal copies. Subscription success shares its template with several guarded internal recipients. Employee welcomes share a template across controllers, import classes and an external bulk sender. - FundsRequestConfirmation has generic and Fido service states. Invoice has payment-enabled/view-only and optional-message/attachment states. MultipleInvoicesCreatedMail has complete success and failure-list states. Insurance status templates have cancellation/completion branches, and provider purchase has motor/life variants. Subscription confirmation has monthly/multi-month and GH/other-currency branches. Transaction statements have date-range/all-transactions states. Sign-in alerts have located/unknown and optional-flag states. - View names differing only in case are not silently merged; deployment on a case-sensitive filesystem may behave differently from this Windows checkout. In particular the two password-reset classes need an integration decision. - Template variables not established by a build binding remain unresolved; for example insurance templates reading user while only order/policy is passed. A static view reference cannot prove successful rendering. - welcomeWallet_plain_text.blade.php is empty, so it does not supply a useful plain-text alternative. No caller was found for the paired maileclipse HTML file. Root resetpassword/resetpage and auth/* are browser forms/screens, not sendable emails. PDF/* and receipt/statement report views are attachments or browser documents unless called as email bodies above. - No source-only conclusion here establishes expiry enforcement, current commercial offers, tax-law correctness or provider delivery. Preserve established baseline values during design and separately confirm product changes. ## Recommended redesign scope 1. **Invoice notification (App\Mail\invoice)**: a traced customer workflow with financial summary, attached document and two action states. Keep the merchant identity and optional message, avoid calling its view URL a direct external checkout, and decide how merchant invoice_color relates to the Built brand. 2. **New sign-in alert (SendNewLoginNotification)**: a traced security workflow with device, IP and location context, optional flag and password-reset action. It exercises long values and unknown geolocation without requiring invented fields. A reasonable alternative is passwordReset instead of invoice if this draft should focus entirely on account security. The tradeoff is losing the merchant-brand and financial-content case. The user confirmed this pair and palette. See index.html for the implemented first draft and integration-notes.html for the contracts.