09fd0bada2
4 Mailables auto-trigger pe model events: - WorkOrderReadyMail: la WO.status → 'ready', către client.email • Atașat PDF fișa lucru (via WorkOrderPdfService) • Total/achitat/rest, recomandări (warning box) - PaymentReceivedMail: la Payment::created, confirmare cu sumă/metodă/ref - AppointmentConfirmedMail: la Appointment::created status='scheduled' - ServiceReminderMail: dispatch manual (vehicle, type=itp/oil/general, note) Layout email branded (resources/views/emails/layout.blade.php): - Header cu logo tenant + theme_color border-bottom - Footer cu telefon/email/disclaimer - Stiluri inline (compatibil tot mail client) Settings page extins cu 4 toggle: - 'Mașina e gata de ridicat' - 'Confirmare plată primită' - 'Programare confirmată' - 'Reminder ITP / revizie' Salvate în companies.settings.notify (JSON), default true. NotificationDispatcher service centralizat: - Verifică isEnabled() pe settings.notify[$key] - Skip dacă client n-are email - Try/catch + Log::warning pe eșec (nu crapă request-ul) Mailables folosesc UsesTenantBranding trait pentru context unitar. Test prin Mailpit: https://mailpit.service.mir.md (capturează toate).
48 lines
1.4 KiB
PHP
48 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Mail;
|
|
|
|
use App\Mail\Concerns\UsesTenantBranding;
|
|
use App\Models\Central\Company;
|
|
use App\Models\Tenant\Appointment;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Mail\Mailable;
|
|
use Illuminate\Mail\Mailables\Content;
|
|
use Illuminate\Mail\Mailables\Envelope;
|
|
use Illuminate\Queue\SerializesModels;
|
|
|
|
class AppointmentConfirmedMail extends Mailable
|
|
{
|
|
use Queueable, SerializesModels, UsesTenantBranding;
|
|
|
|
public function __construct(public Appointment $appointment, Company $company)
|
|
{
|
|
$this->company = $company;
|
|
}
|
|
|
|
public function envelope(): Envelope
|
|
{
|
|
return new Envelope(
|
|
subject: "[{$this->company->name}] Programare confirmată — " . $this->appointment->date?->format('d.m.Y'),
|
|
from: new \Illuminate\Mail\Mailables\Address(
|
|
config('mail.from.address'),
|
|
$this->company->display_name ?? $this->company->name,
|
|
),
|
|
);
|
|
}
|
|
|
|
public function content(): Content
|
|
{
|
|
return new Content(
|
|
view: 'emails.appointment-confirmed',
|
|
with: array_merge($this->buildBrandingContext(), [
|
|
'appointment' => $this->appointment,
|
|
'client' => $this->appointment->client,
|
|
'vehicle' => $this->appointment->vehicle,
|
|
'master' => $this->appointment->master,
|
|
'post' => $this->appointment->post,
|
|
]),
|
|
);
|
|
}
|
|
}
|