4c33323f0e
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>
45 lines
2.1 KiB
PHP
45 lines
2.1 KiB
PHP
<!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: #0F6E56; font-size: 20px;">Лидерра. Баланс пополнен</h1>
|
||
|
||
<p>Здравствуйте, {{ $recipient->first_name ?? $recipient->email }}.</p>
|
||
|
||
<p>Платёж принят. Баланс аккаунта <strong>{{ $tenant->organization_name ?? $tenant->subdomain }}</strong>
|
||
пополнен на:</p>
|
||
|
||
<table style="width: 100%; border-collapse: collapse; margin: 16px 0;">
|
||
<tr>
|
||
<td style="padding: 8px 12px; background: #F6F3EC; width: 140px; vertical-align: top;">Сумма</td>
|
||
<td style="padding: 8px 12px; background: #FFFFFF; border-left: 1px solid #E1EEEA;">
|
||
<strong>{{ $amountRub }} ₽</strong>
|
||
</td>
|
||
</tr>
|
||
@if ($amountLeads !== null)
|
||
<tr>
|
||
<td style="padding: 8px 12px; background: #F6F3EC; vertical-align: top;">Лидов</td>
|
||
<td style="padding: 8px 12px; background: #FFFFFF; border-left: 1px solid #E1EEEA;">
|
||
<strong>+{{ $amountLeads }}</strong>
|
||
</td>
|
||
</tr>
|
||
@endif
|
||
<tr>
|
||
<td style="padding: 8px 12px; background: #F6F3EC; vertical-align: top;">Текущий баланс</td>
|
||
<td style="padding: 8px 12px; background: #FFFFFF; border-left: 1px solid #E1EEEA;">
|
||
{{ $tenant->balance_leads }} лидов
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p style="margin-top: 24px;">Спасибо, что используете Лидерру.</p>
|
||
|
||
<p style="color: #66635C; font-size: 12px; margin-top: 32px;">
|
||
Это автоматическое уведомление о событии «Пополнение». Чтобы изменить настройки уведомлений — перейдите в Настройки → Уведомления.
|
||
</p>
|
||
</body>
|
||
</html>
|