161 lines
7.0 KiB
PHP
161 lines
7.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\EmailNotificationTemplate;
|
|
use App\Models\Invoice;
|
|
use Illuminate\Support\Facades\View;
|
|
|
|
class EmailNotificationTemplateRenderer
|
|
{
|
|
private const BANNERS = [
|
|
'vm_credentials' => 'https://res.cloudinary.com/izpast9i/image/upload/v1786503590/email_banner_cloud_vps.png',
|
|
];
|
|
|
|
public function render(EmailNotificationTemplate $tpl, Invoice $invoice, string $companyName = ''): string
|
|
{
|
|
$blocks = collect($tpl->blocks)
|
|
->filter(fn($b) => $b['enabled'] ?? false)
|
|
->sortBy('order')
|
|
->values();
|
|
|
|
$bodyHtml = '';
|
|
foreach ($blocks as $block) {
|
|
$bodyHtml .= $this->renderBlock($block, $invoice, $companyName);
|
|
}
|
|
|
|
$title = $tpl->header_title ?? 'Thông báo hóa đơn';
|
|
|
|
return $this->wrapLayout($title, $bodyHtml, $companyName, self::BANNERS[$tpl->type] ?? null);
|
|
}
|
|
|
|
/**
|
|
* Render a vm_credentials template using the emailData array from SendVmCredentialsEmailJob.
|
|
* $emailData keys: company_name, client_name, product_name, product_billing, product_price,
|
|
* service_host, service_username, service_port, service_password, os_name, service_due_exp
|
|
*/
|
|
public function renderVmCredentials(EmailNotificationTemplate $tpl, array $emailData, ?Invoice $invoice = null): string
|
|
{
|
|
$blocks = collect($tpl->blocks)
|
|
->filter(fn($b) => $b['enabled'] ?? false)
|
|
->sortBy('order')
|
|
->values();
|
|
|
|
$companyName = $emailData['company_name'] ?? '';
|
|
$bodyHtml = '';
|
|
|
|
foreach ($blocks as $block) {
|
|
$bodyHtml .= match ($block['type'] ?? '') {
|
|
'greeting' => $this->renderView('emails.partials.greeting', ['name' => $emailData['client_name'] ?? 'Quý khách']),
|
|
'vm_credentials' => $this->renderView('emails.partials.vm-credentials', ['fields' => $block['config']['fields'] ?? null, 'data' => $emailData]),
|
|
'product_info' => $this->renderView('emails.partials.product-info', ['fields' => $block['config']['fields'] ?? null, 'data' => $emailData]),
|
|
'invoice_info' => $invoice ? $this->renderView('emails.partials.invoice-info', ['fields' => $block['config']['fields'] ?? null, 'invoice' => $invoice]) : '',
|
|
'order_items' => $invoice ? $this->renderOrderItems($invoice) : '',
|
|
'attachments' => $invoice ? $this->renderAttachments($invoice) : '',
|
|
'custom_text' => $this->renderView('emails.partials.custom-text', ['content' => $block['config']['content'] ?? '']),
|
|
'footer' => $this->renderView('emails.partials.signature', ['companyName' => $companyName]),
|
|
default => '',
|
|
};
|
|
}
|
|
|
|
$title = $tpl->header_title ?? 'Thông tin truy cập VPS';
|
|
|
|
return $this->wrapLayout($title, $bodyHtml, $companyName, self::BANNERS[$tpl->type] ?? null);
|
|
}
|
|
|
|
public function renderPreview(EmailNotificationTemplate $tpl): string
|
|
{
|
|
if ($tpl->type === 'vm_credentials') {
|
|
return $this->renderVmCredentials($tpl, $this->sampleVmData(), null);
|
|
}
|
|
|
|
$invoice = $this->sampleInvoice();
|
|
return $this->render($tpl, $invoice, 'Công ty Demo');
|
|
}
|
|
|
|
// ─── Block renderers ──────────────────────────────────────────────────────
|
|
|
|
private function renderBlock(array $block, Invoice $invoice, string $companyName): string
|
|
{
|
|
return match ($block['type'] ?? '') {
|
|
'greeting' => $this->renderView('emails.partials.greeting', ['name' => $invoice->customer?->fullname ?? 'Quý khách']),
|
|
'invoice_info' => $this->renderView('emails.partials.invoice-info', ['fields' => $block['config']['fields'] ?? null, 'invoice' => $invoice]),
|
|
'customer_info' => $this->renderView('emails.partials.customer-info', ['fields' => $block['config']['fields'] ?? null, 'customer' => $invoice->customer]),
|
|
'order_items' => $this->renderOrderItems($invoice),
|
|
'attachments' => $this->renderAttachments($invoice),
|
|
'custom_text' => $this->renderView('emails.partials.custom-text', ['content' => $block['config']['content'] ?? '']),
|
|
'footer' => $this->renderView('emails.partials.signature', ['companyName' => $companyName]),
|
|
default => '',
|
|
};
|
|
}
|
|
|
|
private function renderOrderItems(Invoice $invoice): string
|
|
{
|
|
$order = $invoice->order;
|
|
if (!$order) return '';
|
|
|
|
$order->loadMissing('orderItems.product');
|
|
|
|
return $this->renderView('emails.partials.order-items', ['items' => $order->orderItems]);
|
|
}
|
|
|
|
private function renderAttachments(Invoice $invoice): string
|
|
{
|
|
$invoice->loadMissing('attachments');
|
|
|
|
return $this->renderView('emails.partials.attachments', ['attachments' => $invoice->attachments]);
|
|
}
|
|
|
|
private function renderView(string $view, array $data): string
|
|
{
|
|
return View::make($view, $data)->render();
|
|
}
|
|
|
|
// ─── Layout wrapper ───────────────────────────────────────────────────────
|
|
|
|
private function wrapLayout(string $title, string $body, string $companyName, ?string $bannerUrl = null): string
|
|
{
|
|
return View::make('emails.layouts.notification', [
|
|
'title' => $title,
|
|
'body' => $body,
|
|
'companyName' => $companyName ?: config('app.name', 'Thế Giới Số'),
|
|
'bannerUrl' => $bannerUrl,
|
|
])->render();
|
|
}
|
|
|
|
// ─── Sample data for preview ──────────────────────────────────────────────
|
|
|
|
private function sampleVmData(): array
|
|
{
|
|
return [
|
|
'company_name' => 'Công ty Demo',
|
|
'company_logo' => '',
|
|
'client_name' => 'Nguyễn Văn A',
|
|
'product_name' => 'VPS Starter',
|
|
'product_billing' => 'Hàng tháng',
|
|
'product_price' => '420.000',
|
|
'service_host' => '203.113.x.x',
|
|
'service_username' => 'root',
|
|
'service_port' => '22',
|
|
'service_password' => 'P@ssw0rd!2026',
|
|
'os_name' => 'Ubuntu 22.04 LTS',
|
|
'service_due_exp' => date('d/m/Y', strtotime('+1 month')),
|
|
];
|
|
}
|
|
|
|
private function sampleInvoice(): Invoice
|
|
{
|
|
$invoice = new Invoice([
|
|
'invoice_number' => 'INV-20260521-00001',
|
|
'sub_total' => 420000,
|
|
'tax' => 0,
|
|
'total' => 420000,
|
|
'status' => 2,
|
|
'payment_method' => 'credit',
|
|
]);
|
|
$invoice->created_at = now();
|
|
$invoice->due_date = now()->addDays(7)->toDateString();
|
|
return $invoice;
|
|
}
|
|
}
|