80 lines
2.9 KiB
PHP
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;
|
|
}
|
|
}
|