Files
portal-api/app/Console/Commands/SendInvoiceReminders.php
T
2026-09-23 15:17:18 +07:00

80 lines
2.9 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Invoice;
use App\Services\InvoicePaymentService;
use App\Services\InvoiceReminderService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class SendInvoiceReminders extends Command
{
protected $signature = 'invoices:send-reminders {--dry-run : Preview which invoices would be reminded}';
protected $description = 'Send payment reminders for invoices approaching or past their due date.';
public function handle(InvoiceReminderService $reminders): int
{
$dryRun = (bool) $this->option('dry-run');
$offsets = (array) config('billing.reminder_offsets', []);
if ($offsets === []) {
$this->warn('invoices:send-reminders | billing.reminder_offsets rỗng — không có mốc nào để nhắc.');
return Command::SUCCESS;
}
// Chỉ quét hoá đơn nằm trong cửa sổ nhắc [mốc sớm nhất … mốc muộn nhất], để không
// kéo cả bảng và không đụng vào hoá đơn cũ đã qua mốc cuối (vd. dữ liệu import từ WHMCS).
$earliest = min($offsets);
$latest = InvoiceReminderService::reminderCutoff($offsets);
$invoices = Invoice::query()
->with('customer')
->whereNotNull('due_date')
->whereIn('status', InvoicePaymentService::PAYABLE_STATUSES)
->whereDate('due_date', '<=', now()->subDays($earliest)->toDateString())
->whereDate('due_date', '>=', now()->subDays($latest)->toDateString())
->get();
$this->info("invoices:send-reminders | Xét {$invoices->count()} hoá đơn.");
$sent = 0;
foreach ($invoices as $invoice) {
$dueStep = $reminders->dueStep($invoice);
if ($dueStep <= (int) $invoice->reminder_step) {
continue;
}
if ($dryRun) {
$this->line(sprintf(
' [dry-run] Hoá đơn #%s hạn %s — mốc %d/%d',
$invoice->invoice_number,
$invoice->due_date->format('Y-m-d'),
$dueStep,
count($offsets),
));
continue;
}
try {
if ($reminders->remind($invoice)) {
$sent++;
$this->line(" [sent] Hoá đơn #{$invoice->invoice_number} → {$invoice->customer?->email}");
}
} catch (\Throwable $e) {
Log::error('invoices:send-reminders error', [
'invoice_id' => $invoice->id,
'error' => $e->getMessage(),
]);
$this->error(" [error] Hoá đơn #{$invoice->invoice_number}: " . $e->getMessage());
}
}
$this->info("invoices:send-reminders | Đã gửi {$sent} email nhắc.");
return Command::SUCCESS;
}
}