Files
portal-api/app/Support/RenewalCampaign.php
baodev0andClaude Sonnet 5.5 55a834a2f8 feat: nhắc gia hạn QR theo dịch vụ, failover server hosting, CCCD admin, log cấp phát dịch vụ
- 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>
2026-10-30 18:36:41 +07:00

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;
}
}