# Уведомления о предоплате (Telegram + Max)

Когда по заказу проходит предоплата (`purchase.paymentConfirm = 1`), админу нужно прислать уведомление в Telegram и/или в Max (мессенджер VK). Раньше это работало в гибридном виде: Telegram — по чату из БД, Max — захардкоженным `chat_id` только для одного отдела продаж. Сейчас оба мессенджера читают `chat_id` из таблицы `domainNotificationSetting`.

## Таблица `domainNotificationSetting`

| Колонка | Тип | Назначение |
|---|---|---|
| `id` | PK | |
| `domainId` | int | FK → `domain.id`, CASCADE/CASCADE |
| `email` | string?, 255 | Адрес для email-уведомлений (используется отдельно) |
| `tgChatId` | string?, 255 | ID Telegram-чата для уведомлений о предоплате |
| `maxChatId` | string?, 255 | ID Max-чата для уведомлений о предоплате |

Колонка `maxChatId` добавлена миграцией `m260515_120000_add_maxChatId_column_to_domainNotificationSetting_table`.

Модель — `app\modules\admin\models\DomainNotificationSetting`.

## Откуда берутся `chat_id`

Чаты привязаны к **группе пользователей** в `adminka.store`. Логика прямая:

- если у домена есть пользователь с `id = 5` → это «основная» команда, чат `tgChatId = -350641615`, в Max не шлём;
- если пользователя 5 нет, но в группе есть другие пользователи → команда «через Max», `tgChatId = -4168763449`, `maxChatId = -70800685883546`;
- если в группе вообще никого нет → `tgChatId = -4168763449`, `maxChatId = NULL`.

Заполнение делает CLI-команда (см. ниже), вручную в админке поля тоже можно править.

## CLI: `notice/sync-chat-ids`

`commands/NoticeController.php::actionSyncChatIds` — синхронизация `tgChatId`/`maxChatId` для всех активных доменов из `adminka.store`.

```bash
docker exec php74_mebel php yii notice/sync-chat-ids
```

Что делает:

1. Берёт все `domain.active = 1`.
2. Для каждого — `GET https://adminka.store/api/domain/info?name={domain.name}` (Guzzle, timeout 10 c, `http_errors = false`).
3. Если ответ не 200 — пропуск с логом.
4. Парсит `users[].id` из JSON-ответа.
5. По правилам выше определяет `tgChatId` / `maxChatId`.
6. Upsert: `findOne(['domainId' => $id])` или новый `DomainNotificationSetting`.
7. Сохраняет, печатает результат через `League\CLImate`.

### Важные моменты

- Команда **перезаписывает** уже выставленные значения — если кто-то правил руками, изменения затрутся. Для щадящего режима нужно добавить флаг.
- Прав записи в `domainNotificationSetting` хватает любому, кто запускает yii-команды — отдельной авторизации нет.
- Реальный пользовательский набор по доменам читается онлайн, поэтому команда должна запускаться, когда `adminka.store` доступен.

## Отправка: `notice/payment`

`commands/NoticeController.php::actionPayment` — крон-команда, которая разгребает очередь подтверждённых, но не уведомлённых заказов.

```bash
docker exec php74_mebel php yii notice/payment
```

Поток:

1. Берёт **один** заказ (`->one()`) с `paymentConfirm = 1`, `paymentAdminNotice = 0`, `saleDepartment IN (2, 3, 4, 5)`, сортировка по `dateCreated ASC`.
2. Если у домена нет `notificationSetting.tgChatId` — ошибка в лог, команда выходит.
3. Формирует текст:
   ```
   Поступила оплата {prepay} руб.
   Заказ №{publicId}
   Сайт {domain.name}
   Имя: {firstName}
   Телефон: {phone}
   Email: {email}
   ```
4. Отправляет в Telegram (`api.telegram.org/bot{token}/sendMessage`, `parse_mode=MarkdownV2`, спецсимволы экранируются).
5. Ставит `paymentAdminNotice = 1`.
6. Если `notificationSetting.maxChatId` непустой → шлёт то же сообщение в Max через `components/Max.php::sendMaxMessage` (`platform-api.max.ru/messages`).

### Что поменялось в `actionPayment`

Раньше отправка в Max была обёрнута в `if ($purchase->saleDepartment == 5)` и шла на захардкоженный `-70800685883546`. Сейчас:

```php
if (!empty($purchase->notificationSetting->maxChatId)) {
    Max::sendMaxMessage($token, $purchase->notificationSetting->maxChatId, $maxMessage, true);
}
```

То есть признак «слать в Max» — это **наличие `maxChatId` в БД**, а не отдел продаж. Условие `saleDepartment IN (2,3,4,5)` сверху не трогали — оно про допуск к уведомлениям вообще.

## Захардкоженные секреты

| Что | Где | Замечание |
|---|---|---|
| Telegram bot token `1015398443:AAFqj...` | `commands/NoticeController.php:400`, `components/Telegram.php`, `components/Notification.php` | Дублируется в трёх местах |
| Max bot token `f9LHodD0...` | `commands/NoticeController.php:493` | Один бот на все домены, отдельной колонки `maxToken` пока нет |

Если появятся разные боты по доменам — добавлять колонку `maxToken` в `domainNotificationSetting` и убирать дубль.

## Триггер

Уведомление **не отправляется** в момент установки `paymentConfirm = 1`. `Purchase::afterSave` ничего не дёргает. Сообщение уйдёт, когда крон отработает `notice/payment`. Период крона задаётся снаружи (в репо crontab нет).

За один вызов уходит **одно** уведомление (`->one()`). Если в очереди 10 — нужны 10 запусков. Чтобы крон не отставал, ставить интервал в минуту или меньше; либо переписать на `each()`/цикл.
