- Mail campaign: mẫu nhắc gia hạn thanh toán QR, chọn dịch vụ + chu kỳ từng dòng (renewal_services) - Hosting: nhiều server Plesk cho một gói (service_plan_servers), chuyển server khi server chết - Admin xem/sửa giấy tờ định danh khách, tuỳ chọn gia hạn cho khách, nhật ký cấp phát dịch vụ - Đánh dấu mẫu email dịch vụ là non-marketing Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
63 lines
2.2 KiB
PHP
63 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
use App\Models\Bank;
|
|
use App\Models\Customer;
|
|
use App\Models\MailCampaign;
|
|
use App\Models\Service;
|
|
|
|
class RenewalCampaign
|
|
{
|
|
private const SERVICE_KEYS = ['service_name', 'billing_cycle', 'period_start', 'period_end', 'expires_date', 'total_amount', 'vat_rate', 'vat_amount', 'payment_content', 'bank_qr_url'];
|
|
|
|
public static function withoutServiceValues(?array $variables): ?array
|
|
{
|
|
$kept = array_diff_key($variables ?? [], array_flip(self::SERVICE_KEYS));
|
|
|
|
return $kept ?: null;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, string>
|
|
*/
|
|
public static function sampleValues(MailCampaign $campaign): array
|
|
{
|
|
$first = $campaign->renewal_services[0]['service_id'] ?? null;
|
|
$service = $first ? Service::with('customer')->find($first) : null;
|
|
|
|
return $service?->customer ? (self::valuesFor($campaign, $service->customer, $service->id) ?? []) : [];
|
|
}
|
|
|
|
public static function isRenewalTemplate(MailCampaign $campaign): bool
|
|
{
|
|
$keys = MailPlaceholders::extract($campaign->subject, $campaign->message);
|
|
|
|
return in_array('period_end', $keys, true) && in_array('bank_qr_url', $keys, true);
|
|
}
|
|
|
|
/**
|
|
* @return array<string, string>|null null khi dịch vụ không còn thuộc khách hoặc không thể gia hạn
|
|
*/
|
|
public static function valuesFor(MailCampaign $campaign, Customer $customer, int $serviceId): ?array
|
|
{
|
|
$months = collect($campaign->renewal_services)->firstWhere('service_id', $serviceId)['months'] ?? null;
|
|
$service = Service::with(['orderItem', 'product', 'customProduct'])
|
|
->whereKey($serviceId)
|
|
->where('customer_id', $customer->id)
|
|
->first();
|
|
$quote = $service ? RenewalQuote::forService($service, $months) : null;
|
|
if (! $quote) {
|
|
return null;
|
|
}
|
|
|
|
unset($quote['service_id'], $quote['cycles'], $quote['months']);
|
|
|
|
$bank = Bank::where('account_no', $campaign->variables['bank_account_no'] ?? '')->first();
|
|
|
|
return $bank
|
|
? [...$quote, 'bank_qr_url' => VietQr::url($bank, $quote['total_amount'], $quote['payment_content'])]
|
|
: $quote;
|
|
}
|
|
}
|