Юридические лица

Источник требований

Владелец франшизы ведёт реестр юридических лиц — своего (головного) и партнёрских (франчайзи). ЮЛ — основа для привязки торговых точек, сотрудников, финансов и документооборота.


Два типа юрлиц

ЮЛ Франшизы (головное)

Юрлицо владельца бренда. Одно на всю сеть. Используется для автоподстановки в документы (счета, акты, договоры).

  • Нет статуса “Приостановлен” — всегда активно
  • Одно из ЮЛ Франшизы назначается главным (для автоподстановки в документы)

ЮЛ Франчайзи (партнёра)

Юрлицо партнёра, работающего под брендом франшизы.

  • У одного франчайзи может быть несколько ЮЛ
  • Одно ЮЛ принадлежит строго одному франчайзи (не может быть общим)
  • Одно ЮЛ может обслуживать несколько торговых точек
  • Можно создать ЮЛ франчайзи без привязки к конкретному франчайзи — привязать позже
  • Статус: Активен или Приостановлен

Поля сущности

Общие поля (оба типа)

ПолеОбязательностьОписание
НаименованиеОбязательноПолное наименование организации
ИННОбязательно10 цифр (ООО) или 12 цифр (ИП), проверка контрольной суммы
КППНеобязательно9 цифр (у ИП нет — поле остаётся пустым)
ОГРНОбязательно13 цифр (ООО) или 15 цифр (ИП/ОГРНИП)
Юридический адресОбязательноОдно текстовое поле, без разбивки по частям
БанкНеобязательноНазвание банка
БИКНеобязательно9 цифр
Расчётный счётНеобязательно20 цифр
Корр. счётНеобязательно20 цифр
Контактный телефонНеобязательноФормат +7 (XXX) XXX-XX-XX
Контактный emailНеобязательно

Дополнительные поля (только ЮЛ Франчайзи)

ПолеОбязательностьОписание
Номер договора франчайзингаНеобязательноМожно дозаполнить позже
Дата договораНеобязательноМожно дозаполнить позже
СтатусОбязательноАктивен / Приостановлен
Владелец (франчайзи)НеобязательноМожно привязать позже

ООО и ИП не разделяются как отдельные типы

Тип определяется автоматически по длине ИНН: 10 цифр = ООО, 12 цифр = ИП.


Валидация и маски ввода

ПолеМаскаПроверка
ИНН10 или 12 цифрКонтрольная сумма (не только длина)
КПП9 цифр
ОГРН13 или 15 цифр
БИК9 цифр
Расчётный счёт20 цифр
Корр. счёт20 цифр
Телефон+7 (XXX) XXX-XX-XX

Бизнес-правила

  1. ИНН нельзя менять после создания — смена ИНН по сути означает другое юрлицо. Если ошиблись при вводе — удалить и создать заново.

  2. Главное ЮЛ — ЮЛ Франшизы является главным по определению. Может существовать только одно ЮЛ типа “Франшиза” на всю франшизу. При создании ЮЛ с типом “Франшиза” — оно автоматически становится главным. Нет действия “Назначить главным” — это свойство типа, не переключатель. (Изменено в BR 1.2)

  3. Приостановка ЮЛ Франчайзи — при приостановке все торговые точки этого ЮЛ снимаются с публикации (перестают принимать заказы).

  4. Возобновление ЮЛ — торговые точки НЕ возвращаются в публикацию автоматически. Каждую нужно опубликовать вручную (чтобы ничего не включилось случайно).

  5. Удаление ЮЛ — soft delete (запись скрывается, но остаётся в системе). Удалить можно только если к ЮЛ не привязано ни одной торговой точки — ни активной, ни закрытой.

  6. ЮЛ Франшизы не имеет статуса “Приостановлен” — оно всегда активно.

  7. ЮЛ Франчайзи можно создать без владельца — привязку к конкретному франчайзи можно выполнить позже.


Влияние franchises.type на раздел

(Введено в BR 1.4.4 §3, §7)

franchises.typeПоведение раздела «Юр. лица»
corporateРаздел виден в меню, можно создавать оба типа ЮЛ (franchise — одно главное, franchisee — сколько угодно)
individualРаздел скрыт в меню и на дашборде. API: попытка создать ЮЛ type=franchisee403 FRANCHISE_TYPE_INDIVIDUAL. Главное ЮЛ (type=franchise) создаётся один раз при bootstrap и не требует UI-управления

Подробнее: Франшизы.


Ролевая матрица

(Переработано в BR 1.4.4 — колонки scope вместо enum)

ДействиеВладелец франшизыВладелец партнёраОбычный сотрудник
Просмотр списка ЮЛВсе ЮЛ франшизыТолько свои ЮЛlegal_entities.read permission (в рамках ТТ в своём scope)
Создание ЮЛ type=franchiseНет (создаётся только при bootstrap)НетНет
Создание ЮЛ type=franchiseeДа (только если franchises.type=corporate)Нет (scope)Нет
Редактирование ЮЛ (все поля)ЛюбоеТолько своиlegal_entities.edit + scope
Редактирование ЮЛ (только банковские реквизиты, контакты, адрес)ЛюбоеТолько свои — стандартный сценарийПо настройке permission
Удаление ЮЛ (если нет привязанных ТТ)ДаНетНет
Приостановка / возобновление ЮЛ ФранчайзиДаНетНет
Импорт ЮЛ из ExcelДа (только если franchises.type=corporate)НетНет
Управление вкладкой «Права» владельца своего партнёраДаНетНет

Владелец партнёра не может менять: наименование, ИНН, КПП, ОГРН, статус, данные договора своего ЮЛ.


Список юрлиц

Колонки

  • Наименование
  • ИНН
  • Тип (Франшиза / Франчайзи)
  • Статус (Активен / Приостановлен)
  • Количество привязанных ТТ
  • Признак “Главное” (если есть)

Фильтры

  • По статусу (Активен / Приостановлен)
  • По типу (Франшиза / Франчайзи)

Поиск

  • По наименованию и по ИНН (ищет по обоим полям одновременно)

Сортировка

  • По умолчанию по наименованию (А-Я)

Пагинация

  • 20 записей на страницу, постраничная навигация

Особенности отображения

  • Главное ЮЛ выделяется бейджем “Главное” и закрепляется вверху списка
  • Приостановленное ЮЛ отображается серым цветом, статус “Приостановлен” красной меткой

Карточка юрлица

  • Все поля юрлица
  • Количество привязанных торговых точек (как число, со ссылкой на список)
  • Вкладки “Сотрудники”, “Документы” — не в MVP, появятся в будущем

Действия и подтверждения

Удаление

  • Если есть привязанные ТТ (любые, даже закрытые) — показать ошибку со списком этих ТТ и ссылками на них, чтобы пользователь мог перейти и отвязать
  • Если нет привязанных ТТ — модальное окно “Вы уверены? Это действие нельзя отменить”
  • Повторный ввод пароля не нужен

Приостановка

  • Модальное окно с предупреждением: “Будет приостановлено ЮЛ [название]. Следующие торговые точки будут сняты с публикации:” и список ТТ
  • Кнопка “Приостановить”

Возобновление

  • Модальное окно: “ЮЛ [название] будет возобновлено. Торговые точки потребуется опубликовать вручную.”

Импорт из Excel

Процесс

  1. На странице списка ЮЛ кнопка “Импорт из Excel”
  2. Рядом — ссылка “Скачать шаблон” (готовый xlsx-файл с заголовками колонок)
  3. Пользователь загружает заполненный файл
  4. Система проверяет все строки и показывает результат: “Корректных: N, С ошибками: M”
  5. Ошибки показываются таблицей: номер строки, поле, что не так
  6. Можно скачать ошибочные строки отдельным Excel-файлом — исправить и загрузить повторно
  7. Кнопка “Импортировать корректные” — подтверждение
  8. Исправлять ошибки прямо в интерфейсе не нужно — проще перезагрузить файл

Ограничения

  • Только формат .xlsx
  • Максимум 10 000 строк за раз
  • Импортируются только ЮЛ Франчайзи (ЮЛ Франшизы создаётся вручную — оно одно)
  • Дубликаты ИНН — показываются как ошибка (не пропускаются молча и не обновляют существующую запись)
  • Для больших файлов (больше 1000 строк) — показывать прогресс-бар

Пустые состояния

Франшиза — первый вход, ЮЛ ещё нет

  • Пустая страница с текстом “Юридические лица пока не добавлены” и две кнопки: “Добавить юрлицо” и “Импортировать из Excel”

Франчайзи — его ЮЛ приостановлено

  • Видит карточку своего ЮЛ с меткой “Приостановлено”. В систему заходить может, но видит предупреждение что ТТ сняты с публикации.

Аудит-лог

  • В MVP не нужен
  • В будущем: кто создал, кто менял, кто приостановил, когда — в отдельной вкладке карточки ЮЛ

Открытые вопросы

ADR-002 — Ожидает ответа от бизнеса

Обязательны ли номер и дата договора франчайзинга при создании ЮЛ Франчайзи? Текущее решение: необязательны. (BR 1.2)


Создание ЮЛ Франчайзи с владельцем

Источники

  • BR 1.4.2 — механика создания сотрудника-владельца в одной транзакции с ЮЛ
  • (Переработано в BR 1.4.4) — enum admin_franchisee удалён. Владельцу выдаётся либо системная «Администратор», либо скрытая персональная роль (в зависимости от режима «Права владельца»)

При создании ЮЛ типа franchisee одновременно создаётся сотрудник-владелец. Одна транзакция — чтобы не было осиротевших сущностей (ЮЛ без владельца или владелец без ЮЛ).

Предусловие

Доступно только если franchises.type = corporate. При individual backend возвращает 403 FRANCHISE_TYPE_INDIVIDUAL.

Блок “Владелец” в форме создания ЮЛ Франчайзи

Форма создания ЮЛ (type=franchisee) обязательно включает блок “Владелец”:

ПолеТипОбязательностьОписание
ИмяtextОбязательно
ФамилияtextОбязательно
Email (логин)emailОбязательноУникален в рамках franchise_id; становится логином для входа в админку
ТелефонtextОпционально
ПарольpasswordОпциональноЕсли не задан — генерируется временный пароль

Для type=franchise (головное ЮЛ бренда) блок “Владелец” не показывается и игнорируется backend-ом.

Блок “Права владельца”

(Введено в BR 1.4.4 §5.2)

В форме создания ЮЛ type=franchisee под блоком «Владелец» — блок «Права владельца» с выбором режима:

РежимЧто происходит
«Полный доступ» (default, рекомендуется)Владельцу назначается системная роль «Администратор» (полный набор permissions). Scope ограничен его ЮЛ через правила scope
«Настроенные права»Создаётся скрытая персональная роль (в таблице roles с owner_legal_entity_id = {id ЮЛ}) с permissions, выбранными админом в чекбоксах. См. Роли § Скрытые роли

В режиме «Настроенные права» показывается матрица permissions (разделы бэк-офиса + функции POS) как в обычной роли.

Минимум permissions (всегда, нельзя снять):

  • pos.access — логин на POS по PIN
  • stores.read — видеть свои ТТ
  • employees.read — видеть свой персонал

Галки этих permissions в UI заблокированы; форсится также серверной валидацией.

Транзакционная логика

При POST /legal-entities с type=franchisee backend в одной транзакции:

  1. Проверяет franchises.type = corporate (иначе 403 FRANCHISE_TYPE_INDIVIDUAL)
  2. Создаёт запись в legal_entitiesowner_user_id = NULL на этом шаге)
  3. Создаёт запись в employees с email/паролем из блока “Владелец” (без поля role — enum удалён в BR 1.4.4)
  4. В зависимости от режима:
    • «Полный доступ» → в employee_roles назначается системная роль «Администратор» (единственная запись; магазины — будут пополняться по мере создания ТТ партнёра)
    • «Настроенные права» → создаётся скрытая роль в roles с owner_legal_entity_id = {id ЮЛ} и permissions из формы; форсятся обязательные permissions; назначается владельцу в employee_roles
  5. Обновляет legal_entities.owner_user_id → ID созданного employee
  6. Возвращает в ответе и ЮЛ, и owner credentials (email + временный пароль если был сгенерирован)

UI после создания

После успешного сохранения показывается модалка “Партнёр создан”:

  • Email владельца (крупно)
  • Временный пароль (крупно, с кнопкой “Скопировать”) — показывается только если был сгенерирован системой
  • Инструкция: “Передайте эти данные партнёру. Пароль можно изменить после первого входа.”
  • Кнопка “Закрыть”

Связь с soft delete

  • При soft-delete ЮЛ Франчайзи владелец деактивируется (status=inactive)
  • При восстановлении ЮЛ — владелец реактивируется
  • При физическом удалении ЮЛ (если допустимо — нет привязанных ТТ) его скрытая роль (если была) удаляется каскадом

Вкладка «Права» в карточке ЮЛ партнёра

(Введено в BR 1.4.4 §5.2)

В карточке ЮЛ type=franchisee есть вкладка «Права», через которую главный админ управляет правами владельца партнёра.

Содержимое вкладки

  • Радио-переключатель режима: «Полный доступ» / «Настроенные права»
  • В режиме «Настроенные права» — та же матрица permissions, что в форме создания
  • Обязательные permissions (pos.access, stores.read, employees.read) — галки заблокированы
  • Кнопка «Сохранить» — применяет изменения немедленно

Переключение режима

  • «Настроенные» → «Полный доступ»: скрытая роль отсоединяется от владельца (employee_roles удаляется); владельцу назначается системная «Администратор»; скрытая роль помечается удалённой или физически удаляется
  • «Полный доступ» → «Настроенные»: системная «Администратор» отсоединяется; создаётся новая скрытая роль (с owner_legal_entity_id = {id ЮЛ}, permissions по умолчанию — все включены) и назначается владельцу

Доступ к вкладке

  • Владелец франшизы — полный доступ
  • Владелец партнёра — не видит вкладку у своего же ЮЛ (не может сам себе давать/снимать права)
  • Прочие — нет доступа

Интеграция с PayKeeper

(Добавлено в BR 3.3)

Каждое юрлицо может иметь подключение к PayKeeper (провайдер платежей + фискализации 54-ФЗ). Один ЛК PK = одно юрлицо. В карточке ЮЛ — секция «PayKeeper» (видна при integrations.read) с формой подключения и статусом.

ПолеОбязательностьОписание
Хост ЛК (pk_server_host)ОбязательноURL вида {tsp}.server.paykeeper.ru
Логин ЛК (pk_login)Обязательно
Пароль ЛК (pk_password)ОбязательноШифруется at rest, в UI masked
Секретное слово (informer_seed)ОбязательноДля валидации webhook-подписи, шифруется
Номер договора (paykeeper_id)Необязательно
СтатусОбязательноАктивна / Приостановлена

Редактирование — только integrations.manage (владелец франшизы — любое ЮЛ, владелец партнёра — только свои ЮЛ). Менеджер ТТ / кассир не видят.

Подробнее: главная спека PayKeeper.


Связи с другими модулями

  • Торговые точки — каждая ТТ привязана к одному юрлицу
  • Сотрудники — сотрудник может быть привязан к юрлицу (не в MVP)
  • Финансы — движение денег ведётся по юрлицам (не в MVP)
  • Документы — счета и акты формируются от имени главного ЮЛ (не в MVP, отдельный модуль)
  • PayKeeper — один ЛК PK привязывается к одному ЮЛ (BR 3.3)

Прочее

  • Только десктоп (бэк-офис), мобильная версия не нужна
  • Язык интерфейса — только русский

Ссылки