77 lines
2.5 KiB
PHP
77 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\PaymentScheduleItem;
|
|
use App\Models\User;
|
|
use App\Notifications\PaymentDueNotification;
|
|
use Illuminate\Console\Command;
|
|
|
|
class SendPaymentDueNotifications extends Command
|
|
{
|
|
protected $signature = 'notifications:send-due-payments
|
|
{--days=7 : Số ngày trước hạn để cảnh báo}
|
|
{--dry-run : Chỉ liệt kê, không gửi}';
|
|
|
|
protected $description = 'Gửi cảnh báo đợt thanh toán sắp đến hạn cho tất cả users';
|
|
|
|
public function handle(): int
|
|
{
|
|
$days = (int) $this->option('days');
|
|
$dryRun = $this->option('dry-run');
|
|
|
|
$from = now();
|
|
$to = now()->addDays($days);
|
|
|
|
$items = PaymentScheduleItem::query()
|
|
->with(['schedule.contract', 'payments'])
|
|
->whereHas('schedule.contract')
|
|
->whereDate('due_date', '>=', $from)
|
|
->whereDate('due_date', '<=', $to)
|
|
->whereRaw('amount > (SELECT COALESCE(SUM(amount), 0) FROM payments WHERE payments.schedule_item_id = payment_schedule_items.id)')
|
|
->orderBy('due_date')
|
|
->get();
|
|
|
|
if ($items->isEmpty()) {
|
|
$this->warn('Không có đợt thanh toán nào sắp đến hạn trong ' . $days . ' ngày tới.');
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$this->info("Tìm thấy {$items->count()} đợt thanh toán sắp đến hạn.");
|
|
|
|
$users = User::all();
|
|
|
|
if ($users->isEmpty()) {
|
|
$this->warn('Không có user nào trong hệ thống để nhận thông báo.');
|
|
return self::FAILURE;
|
|
}
|
|
|
|
foreach ($items as $item) {
|
|
$contract = $item->schedule?->contract;
|
|
$remaining = (float) $item->remaining_amount;
|
|
|
|
$this->line(sprintf(
|
|
'- HĐ %s | Đợt %d | Ngày %s | Còn thiếu: %s VNĐ',
|
|
$contract?->contract_number ?? 'N/A',
|
|
$item->installment_no,
|
|
$item->due_date?->format('d/m/Y'),
|
|
number_format($remaining)
|
|
));
|
|
|
|
if (! $dryRun) {
|
|
foreach ($users as $user) {
|
|
$user->notify(new PaymentDueNotification($item));
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($dryRun) {
|
|
$this->info('Chế độ dry-run: Không có thông báo nào được gửi.');
|
|
} else {
|
|
$this->info("Đã gửi thông báo cho {$users->count()} user(s).");
|
|
}
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|