Логика
Ядро раздела — Документ. Это одна карточка договора, акта или иного бумажного документа компании: либо сгенерированная автоматически из Шаблона документа, либо загруженная вручную файлом. Документ не хранит содержимое в одном универсальном поле «файл» — вместо этого:- для сгенерированного документа HTML-содержимое хранится прямо в самом Документе;
- реальные файлы (оригинал, слой для подписи, подписанная версия и т.д.) хранятся отдельными записями Файл документа, привязанными к документу.
Поле «Ссылка на документ-основание» (связь документа с его прежней версией) в модели существует, но в описанной ниже логике никогда не заполняется — предыдущая и новая версия документа при повторном подписании между собой не связываются.
Статусы, типы, источник
- Источник («Сгенерирован» / «Загружен») задаётся один раз при создании и определяет, какая ветка логики создания/обновления применяется к документу.
- Формат документа — для сгенерированных документов при создании всегда фиксируется как HTML; для загруженных — всегда PDF (см. «Генерация документа и PDF»).
- Статус подписания хранится не на документе, а на каждой отдельной Подписи документа — у документа с несколькими подписантами могут одновременно существовать подписи в разных статусах (подробнее — в разделе «Подписание документов»).
- Подписан — флаг, вычисляемый автоматически (см. ниже).
Список документов: фильтрация и поиск
Список документов компании отдаётся отсортированным от новых к старым, с предзагрузкой файлов, подписей, их подписантов и истории этапов подписания. Само HTML-содержимое документа в список не включается — оно отдаётся только в подробном ответе, чтобы не раздувать список. Доступные фильтры: ID документа, тип и ID связанного объекта, шаблон, формат документа, источник, создатель, дата создания (диапазон), «Подписан», статус подписи, «Активные» (есть хотя бы одна подпись), а также способ подписания, подписант и тип подписанта — эти три фильтруют документы через связанные подписи, а не через собственные поля документа. Поиск (свободный текст) ищется одновременно по названию документа, названию шаблона, имени и телефону подписанта — по подстроке, без учёта регистра.Автоматического сопоставления ввода в «неправильной» раскладке клавиатуры больше нет: запрос латиницей не найдёт кириллические названия и наоборот — искать нужно в той раскладке, в которой заведены данные.
Создание документа
Способ создания зависит от переданного источника.Сгенерированный документ (источник по умолчанию)
- Если передан ID связанного объекта, система обязательно ищет по нему существующую заявку на аренду; если заявка не найдена — ошибка «не найдено».
- Документу присваивается порядковый номер — сквозной счётчик, отдельный для каждого выбранного шаблона (если шаблон не выбран — используется один общий счётчик по умолчанию).
- Тип связанного объекта копируется из выбранного шаблона (если шаблон не выбран — остаётся пустым).
- Если название не передано, но есть и шаблон, и заявка — название формируется автоматически по шаблону «Название шаблона — ID заявки»; если название всё равно осталось пустым — ошибка «Введите название документа».
- Если к документу привязана заявка на аренду, содержимое всегда генерируется автоматически подстановкой реальных данных клиента, точки проката, инвентаря, доставок, штрафов и услуг — любое содержимое, переданное вручную, будет перезаписано.
- Если заявка не привязана, содержимое, переданное в запросе, сохраняется как есть — генерация не выполняется.
- Создатель документа фиксируется как текущий пользователь.
Выбрать шаблон можно только из активных шаблонов своей компании: по отключённому (удалённому) шаблону, как и по шаблону другой компании, создать документ нельзя — такой шаблон не будет принят.
Генерация содержимого всегда опирается на конкретную заявку на аренду и данные её клиента — даже если у шаблона источником данных настроен «клиент», система всё равно ожидает ID именно заявки в качестве связанного объекта, а данные клиента берёт из этой заявки.
Загруженный документ
- Обязательно нужно приложить файл — иначе ошибка «Прикрепите файл документа».
- Название берётся из запроса, а если не указано — из оригинального имени файла.
- Если расширение файла не «pdf», файл автоматически конвертируется в PDF перед сохранением.
- Документу присваиваются: источник «Загружен», формат «PDF», шаблон/тип связанного объекта/ID связанного объекта — пустые, порядковый номер не выдаётся.
- Файл сохраняется отдельной записью с типом «Оригинал».
Изменение документа и блокировка после начала подписания
Если у документа уже есть хотя бы одна подпись в статусе «На подтверждении» или «Подписан», документ считается заблокированным: менять содержимое, шаблон, формат — а также требовать перегенерацию содержимого — напрямую нельзя. Остальные поля редактировать по-прежнему можно: переименовать подписанный документ разрешено. Штатный способ обойти блокировку — явный флаг повторного подписания:- Пересоздать при повторном подписании. Если к документу так или иначе относятся и шаблон, и связанный объект — вместо изменения существующего документа создаётся совершенно новый документ (новый ID, UUID, порядковый номер) с тем же шаблоном, связанным объектом и названием; содержимое генерируется заново с нуля. Исходный документ и его подписи не меняются — это способ «начать подписание заново».
- Перегенерировать. Для незаблокированного документа содержимое перегенерируется заново из шаблона и текущих данных, документ сохраняется на месте (подписи не сбрасываются). Для заблокированного документа этот флаг отклоняется.
Перевыпуск заблокированного документа возможен только тогда, когда у документа есть и шаблон, и связанный объект — то есть когда содержимое действительно можно собрать заново. Иначе запрос отклоняется: без шаблона и объекта перевыпуск раньше приводил к тому, что присланное содержимое записывалось прямо в подписанный документ.
Поле «Источник» не защищено явной блокировкой: если отправить полное (не частичное) обновление документа без указания источника, оно молча примет значение по умолчанию «Сгенерирован» — даже для документа, изначально загруженного файлом.
Автоматические последствия
Пересчёт признака «Подписан»
После каждого изменения статуса любой подписи документа признак «Подписан» пересчитывается: он становится «истина», только если все подписи документа имеют статус «Подписан» и у документа не менее двух подписей.Документ с единственным подписантом (например, только со стороны компании) никогда не станет «Подписан» — для этого обязательно нужны минимум две стороны подписания.
Уведомление о подписании
При каждом сохранении уже подписанного документа система создаёт (если такого уведомления ещё не было) или обновляет уведомление «Документ подписан». Фактическая рассылка выполняется только один раз — при первом создании; при последующих сохранениях уведомление лишь обновляется на месте (текст пересобирается, отметки «прочитано»/«архивировано» сбрасываются), но повторной рассылки по каналам не происходит.Списание лимита подписей (пакеты документов)
Если компании назначен режим биллинга подписания «за документ», при подписании система списывает один слот из её пакета документов — один на весь документ, независимо от числа подписантов. В режиме «за SMS» (он по умолчанию) пакеты не расходуются вообще, а компания платит только за сообщения подписания. Подробный механизм — в разделе «Пакеты, баланс и квоты подписи».Управление через административную панель
Административная панель раздела документов должна предоставлять доступ к моделям Подписант, Шаблон документа, Документ, Подпись документа, Этап подписания, Файл документа и Пакет документов — см. предупреждение ниже.Особенности поведения
- Уведомление «Документ подписан» реально рассылается по push/Telegram/веб-каналам только один раз — при первом создании записи; повторные сохранения подписанного документа лишь обновляют текст и сбрасывают отметки «прочитано»/«архивировано».
- При повторном подписании (флаг «пересоздать») создаётся полностью новый, независимый документ; поле «Ссылка на документ-основание» при этом не заполняется и вообще нигде не устанавливается.
- Заблокированный документ (на подтверждении или подписанный) можно переименовать, но нельзя перерисовать: требование перегенерации отклоняется, а перевыпуск возможен только при наличии и шаблона, и связанного объекта.
- Шаблон для нового документа принимается только из активных шаблонов своей компании — отключённый шаблон и шаблон чужой компании отклоняются.
- Фильтр списка документов «Активные» реально фильтрует только при значении «истина»; при явной передаче значения «ложь» фильтр не применяется.
- Поле «Источник» не защищено при обновлении документа: полное обновление без указания источника молча выставит значение по умолчанию «Сгенерирован», в том числе для документа, изначально загруженного файлом.
- Порядковый номер документа — отдельный счётчик для каждого выбранного шаблона (или общий счётчик по умолчанию, если шаблон не выбран); загруженные документы порядковый номер не получают вовсе.
- Генерация содержимого всегда требует привязанной заявки на аренду и берёт данные клиента из неё, независимо от того, что настроено как источник данных на самом шаблоне.