cdfae077a3
Клиент сам выставляет PDF-счёт (TopupDialog вкладка «По счёту»), счета и акты — в отдельной вкладке «Счета». Админ (/admin/invoices) отмечает оплату одной кнопкой → атомарно зачисляет баланс (BillingTopupService), формирует Акт (без НДС, saas_upd_documents ДОП) и шлёт клиенту письмо «Счёт оплачен» с вложением PDF-акта. PDF открываются inline в браузере (ASCII-имя). - Сервисы InvoiceNumberGenerator/InvoiceService/ActService/InvoicePaymentService/PdfRenderer - Контроллеры InvoiceController (клиент) + AdminInvoiceController (список+mark-paid) - Модели SaasInvoice/SaasInvoiceItem/SaasUpdDocument; шаблоны pdf/invoice|act - Нумерация СЧ-ГГГГ-NNNNN (advisory-lock); просрочка invoices:expire (cron) - Наименование услуги: «Оплата генерации рекламных лидов» - Зависимость barryvdh/laravel-dompdf (default_font dejavu sans); схема БД не менялась - Этап 2 (автомат через ВТБ API) — отдельно, спека/план в docs/superpowers Тесты: счета 13, Billing 138, фронт зелёные; larastan baseline +6 (Pest false-pos). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
29 lines
891 B
PHP
29 lines
891 B
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\SaasInvoice;
|
|
use Illuminate\Console\Command;
|
|
|
|
/**
|
|
* Помечает просроченные неоплаченные счета статусом overdue (Этап 1 «оплата по счёту»).
|
|
* Только issued → overdue по expires_at; оплаченные/отменённые не трогаются.
|
|
*/
|
|
class ExpireInvoicesCommand extends Command
|
|
{
|
|
protected $signature = 'invoices:expire';
|
|
|
|
protected $description = 'Помечает просроченные неоплаченные счета статусом overdue';
|
|
|
|
public function handle(): int
|
|
{
|
|
SaasInvoice::where('status', SaasInvoice::STATUS_ISSUED)
|
|
->where('expires_at', '<', now())
|
|
->update(['status' => SaasInvoice::STATUS_OVERDUE]);
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|