Files
portal/app/resources/views/emails/zero_balance.blade.php
T
Дмитрий 4c33323f0e phase2(notifications-stage6): low_balance + zero_balance + topup + invoice email/inapp
P0 этап 6 — 4 оставшихся email-события. Авто-план P0 (6 этапов) закрыт
полностью: все 8 schema-default событий имеют рабочую интеграцию
(new_lead/reminder/low_balance/zero_balance/topup_success/invoice_paid +
заглушки для new_device_login/marketing).

Backend:
- 4 новых Mailable: LowBalanceNotification (threshold), ZeroBalanceNotification,
  TopupSuccessNotification (amountRub, amountLeads?), InvoicePaidNotification
  (amountRub, invoiceNumber?, tariffName?).
- 4 blade-шаблона в emails/ (Forest-палитра, таблицы balance/amount/invoice).
- NotificationService +4 методов: notifyLowBalance / notifyZeroBalance /
  notifyTopupSuccess / notifyInvoicePaid. Все шлют email + inapp по prefs.

Интеграция в ProcessWebhookJob:
- chargeNewLead после lead_charge: notifyLowBalance при пересечении порога
  сверху-вниз (balance_after <= threshold AND (balance_after+1) > threshold).
  Иначе спам при каждом lead_charge при balance < threshold.
- logRejection(zero_balance): notifyZeroBalance ТОЛЬКО если в последний час
  не было другого RejectedDealsLog с тем же reason (anti-spam 1 email/час).
  Защита от self-just-inserted через id!= (timestamp-сравнение ненадёжно
  из-за PG microsecond precision).
- topup_success / invoice_paid — service-методы готовы, integration после
  появления endpoints для пополнения (ЮKassa-webhook) и оплаты тарифа.
- lowBalanceThreshold() читает system_settings.low_balance_threshold_leads
  (default 10, schema seed).

Pest +12 в BalanceNotificationsTest (359/359 за 41.37 сек, 1233 assertions):
- low_balance: пересечение порога / уже < threshold / > threshold /
  prefs.email=false (только inapp).
- zero_balance: первое отклонение / 2-е в час не дублирует / >1ч снова шлёт.
- topup_success / invoice_paid: notify создаёт email+inapp / prefs=email:false.
- balance events изолированы между tenants.

NewLeadNotificationTest: «balance=0 не шлёт» обновлён —
Mail::assertNotSent(NewLeadNotification) вместо Mail::assertNothingSent
(ZeroBalanceNotification теперь шлётся при balance=0 — новое поведение).

PHPStan baseline регенерирован.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 12:51:32 +03:00

28 lines
1.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Баланс закончился</title>
</head>
<body style="font-family: Inter, -apple-system, sans-serif; max-width: 600px; margin: 0 auto; padding: 24px; color: #081319;">
<h1 style="color: #B94837; font-size: 20px;">Лидерра. Баланс закончился</h1>
<p>Здравствуйте, {{ $recipient->first_name ?? $recipient->email }}.</p>
<p>Баланс аккаунта <strong>{{ $tenant->organization_name ?? $tenant->subdomain }}</strong>
обнулился <strong>входящие лиды отклоняются</strong>.</p>
<p style="background: #FEF3F2; padding: 12px; border-left: 3px solid #B94837;">
<strong>Что делать:</strong> пополните баланс в разделе Биллинг.
После пополнения новые лиды снова начнут приниматься.
</p>
<p>Уже отклонённые лиды не возвращаются посмотрите их в журнале
«Отклонённые лиды» в разделе Отчёты.</p>
<p style="color: #66635C; font-size: 12px; margin-top: 32px;">
Это автоматическое уведомление о событии «Нулевой баланс». Чтобы изменить настройки уведомлений перейдите в Настройки Уведомления.
</p>
</body>
</html>