# G1/SP3c — полные платёжные реквизиты (фронт) — дизайн

**Дата:** 19.06.2026
**Статус:** дизайн утверждён владельцем (брейншторм)
**Спринт:** G1/SP3c. Предшественники: SP1 (самозапись), SP2 (бэкенд реквизитов+гейт), SP3a (фронт входа), SP3b (лёгкая форма реквизитов + гейт).
**Граница:** только фронт. Бэкенд (поля + валидация) готов в SP2, не меняется.

---

## 1. Цель

Дать клиенту возможность дозаполнить **полные платёжные реквизиты** (КПП / ОГРН /
юр.адрес / банковские реквизиты) — для будущего этапа оплаты (счёт/договор).
Расширяет ту же вкладку «Реквизиты» из SP3b, добавляя блок ниже лёгких полей.

`requisites_completed_at` бэкенд ставит при заполнении расчётного счёта
(`RequisitesService::upsert`). Пока этот флаг **не потребляется** никаким
гейтом оплаты (этап оплаты — будущее); в SP3c он используется только для
информативного чипа-статуса.

---

## 2. Готовый бэкенд (контракт, не меняем)

Все поля уже есть в таблице `tenant_requisites` (миграция SP2) и в
`RequisitesResource`. Эндпоинты — те же `GET/PUT /api/tenant/requisites`
(SP3b api-обёртка `getRequisites`/`updateRequisites` уже их покрывает; новых
api-функций не нужно).

**Поля (nullable) и форматы валидации** (`UpdateRequisitesRequest`):
- `kpp` — `regex:/^\d{9}$/`
- `ogrn` — `regex:/^(\d{13}|\d{15})$/`
- `legal_address` — `string` (nullable)
- `bank_name` — `string` max:255
- `bank_bik` — `regex:/^\d{9}$/`
- `bank_account` — `regex:/^\d{20}$/`
- `corr_account` — `regex:/^\d{20}$/`

**`requisites_completed_at`**: ставится в `now()` если `bank_account` заполнен,
иначе `null` (`RequisitesService::upsert`). Возвращается в `RequisitesResource`.

`Requisites`-интерфейс (`api/requisites.ts`, SP3b) **уже включает** все эти поля —
менять api-слой не нужно.

---

## 3. Что добавляем во фронте

Только расширение `app/resources/js/views/settings/RequisitesTab.vue`. Новых
файлов, роутов, api-функций, правок бэкенда — нет.

### 3.1. Блок «Реквизиты для оплаты»

Ниже лёгких полей (после строки контакт/ИНН) — отдельный блок:

- Заголовок «Реквизиты для оплаты (для счёта и договора)».
- **Чип-статус** рядом с заголовком:
  - 🟢 `color="success"` «Готово к оплате» — если `form.requisites_completed_at` заполнен;
  - ⚪ `color="default"`/grey «Не заполнено» — иначе.
- Поясняющая подпись: «Нужны для выставления счёта и договора. Можно заполнить позже.»

### 3.2. Поля по типу лица

Видимость завязана на `form.subject_type` (computed-флаги):

- **legal_entity (Юрлицо):** КПП · ОГРН · Юр.адрес · Наименование банка · БИК · Р/с · К/с
- **sole_proprietor (ИП):** ОГРНИП *(поле `ogrn`)* · Юр.адрес · Наименование банка · БИК · Р/с · К/с — **без КПП**
- **individual (Физлицо):** Наименование банка · БИК · Р/с · К/с — **без КПП/ОГРН/юр.адреса**

Лейбл поля `ogrn`: «ОГРН» для ЮЛ, «ОГРНИП» для ИП.

### 3.3. Валидация (клиент зеркалит бэкенд)

Все платёжные поля **необязательные**. Проверка только если поле заполнено:
- `kpp` — ровно 9 цифр;
- `ogrn` — для ЮЛ ровно 13 цифр, для ИП ровно 15 цифр (UI-уточнение; бэкенд
  принимает 13 или 15);
- `bank_bik` — ровно 9 цифр;
- `bank_account`, `corr_account` — ровно 20 цифр.

Клиентская проверка добавляется в существующий `validateClient()` (SP3b) — он
по-прежнему сначала проверяет обязательные лёгкие поля, затем (если заполнены)
платёжные форматы. Серверные `422` раскладываются по полям (механизм SP3b).

### 3.4. Данные / поведение

- `GET` (onMounted, SP3b) уже предзаполняет все поля, включая платёжные.
- `PUT` (`save()`, SP3b) уже отправляет всю форму целиком — платёжные поля
  уедут вместе с лёгкими.
- После сохранения `Object.assign(form, updated)` (SP3b) обновит
  `requisites_completed_at` → чип перерисуется.

---

## 4. Обработка ошибок

- `422` с полевыми `errors` → раскладка по полям (готово в SP3b `save()`).
- Прочие → общий `saveError` через `extractErrorMessage` (готово в SP3b).
- Отдельной обработки SP3c не требует.

---

## 5. Верификация

vitest сломан (G8). Проверяем:

- `npm --prefix app run type-check` (`vue-tsc`) = exit 0.
- eslint по `RequisitesTab.vue` = 0 ошибок.
- `npm --prefix app run build` = успех (перед Playwright обязательна пересборка).
- **Живой Playwright (обязательно):**
  1. Клиент из SP3b (лёгкие реквизиты есть) → вкладка реквизитов; чип «Не заполнено».
  2. Тип «ИП» → видны ОГРНИП + юр.адрес + банк, КПП скрыт; заполнить валидно
     (ОГРНИП 15 цифр, БИК 9, р/с 20, к/с 20) → Сохранить → чип «Готово к оплате».
  3. Тип «Юрлицо» → появляется КПП (9 цифр); тип «Физлицо» → КПП/ОГРН/юр.адрес
     скрыты, остаётся только банк (проверка видимости по типу).
  4. Негатив: БИК `8 цифр` → видимая ошибка под полем.

---

## 6. YAGNI / границы

- НЕ трогаем бэкенд (поля и валидация готовы в SP2).
- НЕ добавляем api-функции (SP3b обёртка уже шлёт всю форму).
- НЕ делаем кросс-полевую обязательность банковского набора (бэкенд этого не
  требует; `requisites_completed_at` ставится по `bank_account`). Чип честно
  отражает бэкенд-правило.
- НЕ делаем гейт оплаты (этап оплаты — будущий эпик).
- НЕ чиним сторонние находки (register-500, стейл-тест, NBSP-lint).

---

## 7. Затрагиваемые файлы

| Файл | Действие |
|---|---|
| `app/resources/js/views/settings/RequisitesTab.vue` | правка — +блок платёжных реквизитов, +чип-статус, +валидация платёжных полей |
