feat: khởi tạo/huỷ domain Plesk qua job, gửi mail hoá đơn qua queue, đính kèm triển khai
- ProvisionDnsDomainJob/SuspendDnsDomainJob: tạo domain admin lên Plesk, huỷ = suspend (is_created=3) - Khách xem zone DNS được gán ở /dich-vu/domain, quản lý bản ghi A/AAAA/CNAME/TXT/MX/SRV - send-mail hoá đơn đẩy SendInvoiceMailJob, preview + sửa nội dung, ghi mail.order_id - invoice_attachments.type (payment_proof/deployment) - CacheService xoá theo SCAN pattern, Redis không persistent mặc định - Backfill transactions.public_code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
30898ea46f
commit
94614d9cb3
@@ -5,9 +5,9 @@ namespace App\Mail;
|
||||
use App\Enums\Invoice\InvoiceStatus;
|
||||
use App\Models\Invoice;
|
||||
use App\Services\InvoicePaymentService;
|
||||
use App\Support\MailGlobals;
|
||||
use App\Support\EmailTemplateShell;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Mail\Mailables\Attachment;
|
||||
|
||||
/**
|
||||
@@ -19,9 +19,10 @@ use Illuminate\Mail\Mailables\Attachment;
|
||||
*/
|
||||
class InvoiceNotificationMail extends TemplateMailable
|
||||
{
|
||||
public const SCENARIO = 'invoice_notification';
|
||||
|
||||
public function __construct(
|
||||
public readonly Invoice $invoice,
|
||||
public readonly Collection $invoiceAttachments,
|
||||
public readonly string $customerName,
|
||||
public readonly string $message,
|
||||
public readonly string $companyName,
|
||||
@@ -31,6 +32,29 @@ class InvoiceNotificationMail extends TemplateMailable
|
||||
public readonly ?string $paymentUrl = null,
|
||||
) {}
|
||||
|
||||
public static function forInvoice(
|
||||
Invoice $invoice,
|
||||
string $type = 'invoice',
|
||||
?string $message = null,
|
||||
?string $invoicePdf = null,
|
||||
?string $invoicePdfFileName = null,
|
||||
): self {
|
||||
$message ??= $type === 'renewal'
|
||||
? "Dịch vụ của quý khách sắp đến hạn gia hạn. Vui lòng kiểm tra hóa đơn #{$invoice->order_num} được đính kèm và hoàn tất thanh toán để dịch vụ không bị gián đoạn."
|
||||
: "Vui lòng xem thông tin hóa đơn #{$invoice->order_num} của bạn.";
|
||||
|
||||
return new self(
|
||||
$invoice,
|
||||
$invoice->customer->fullname,
|
||||
$message,
|
||||
setting('general.company_name') ?: config('app.name'),
|
||||
$type,
|
||||
$invoicePdf,
|
||||
$invoicePdfFileName,
|
||||
MailGlobals::frontendUrl() . $invoice->clientPath(),
|
||||
);
|
||||
}
|
||||
|
||||
public function attachments(): array
|
||||
{
|
||||
if ($this->invoicePdf !== null && $this->invoicePdfFileName !== null) {
|
||||
@@ -45,7 +69,7 @@ class InvoiceNotificationMail extends TemplateMailable
|
||||
|
||||
protected function scenario(): string
|
||||
{
|
||||
return 'invoice_notification';
|
||||
return self::SCENARIO;
|
||||
}
|
||||
|
||||
protected function variables(): array
|
||||
@@ -67,7 +91,7 @@ class InvoiceNotificationMail extends TemplateMailable
|
||||
? 'File PDF hóa đơn gia hạn đã được đính kèm trong email này. Vui lòng hoàn tất thanh toán trước hạn để dịch vụ không bị gián đoạn.'
|
||||
: 'File PDF hóa đơn đã được đính kèm trong email này để Quý khách tiện lưu trữ và đối chiếu.',
|
||||
'pay_button' => $this->payButton(),
|
||||
'attachments_block' => $this->attachmentsBlock(),
|
||||
'attachments_block' => '',
|
||||
'note_block' => $this->noteBlock(),
|
||||
];
|
||||
}
|
||||
@@ -132,24 +156,6 @@ class InvoiceNotificationMail extends TemplateMailable
|
||||
. '<p style="margin: 0 0 18px 0; word-break: break-all; font-size: 13px; color: #6b7280;">Hoặc sao chép liên kết thanh toán: <a href="' . $url . '" style="color: #f16723;">' . $url . '</a></p>';
|
||||
}
|
||||
|
||||
private function attachmentsBlock(): string
|
||||
{
|
||||
if ($this->invoiceAttachments->isEmpty()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$items = $this->invoiceAttachments
|
||||
->map(fn($file) => '<li style="margin-bottom: 6px;"><a href="'
|
||||
. htmlspecialchars((string) $file->url, ENT_QUOTES, 'UTF-8')
|
||||
. '" target="_blank" rel="noopener" style="color: #f16723; text-decoration: none;">'
|
||||
. htmlspecialchars((string) $file->filename, ENT_QUOTES, 'UTF-8')
|
||||
. '</a></li>')
|
||||
->implode('');
|
||||
|
||||
return '<div style="margin: 20px 0;"><p style="margin: 0 0 8px 0; font-size: 14px; font-weight: 600; color: #374151;">File đính kèm</p>'
|
||||
. '<ul style="padding-left: 18px; margin: 0; font-size: 14px;">' . $items . '</ul></div>';
|
||||
}
|
||||
|
||||
private function noteBlock(): string
|
||||
{
|
||||
if (empty($this->invoice->note)) {
|
||||
|
||||
Reference in New Issue
Block a user