Договор, счёт и акт формируются сами: как это устроено
Автоматическое формирование документов — это не кнопка «сделать красиво», а связка из четырёх частей: структурированные данные о сделке, шаблон с помеченными местами для подстановки, генератор файла на сервере и журнал выданных номеров. Ниже — как каждая часть устроена и почему её нельзя выкинуть.
Откуда система берёт данные
Документ невозможно собрать из того, чего нет. Поэтому первый вопрос всегда не про шаблон, а про хранение.
Реквизиты юрлица должны лежать в системе отдельными полями: наименование, ИНН, КПП, ОГРН, адрес, банк, счёт, БИК, ФИО подписанта, основание полномочий. Не одной строкой в примечании, а полями, каждое со своим именем.
То же самое с предметом сделки. Строка «столешница дуб 1200×600, 2 шт.» в документе появляется не как текст, а как набор: наименование, единица измерения, количество, цена, сумма, ставка НДС или отметка о её отсутствии.
Когда данные разложены так, документ собирается механически. Когда нет — генерация превращается в разбор строк, и любое отклонение от привычного написания ломает результат.
Что такое шаблон с полями
Шаблон — обычный текст договора, в котором вместо конкретных значений стоят метки. Выглядит примерно так: «Исполнитель, {{ispolnitel_name}}, в лице {{podpisant}}, действующего на основании {{osnovanie}}».
Метки заменяются значениями в момент сборки. Юрист правит текст вокруг меток сколько угодно и не трогает разработчика, пока не появляется новая метка.
Хранить шаблон лучше в формате, который открывается в обычном редакторе — тогда правки вносит юрист, а система только подставляет значения. Хранить его внутри кода — распространённая ошибка: каждая запятая в договоре начинает стоить как задача разработчику.
Отдельная деталь — склонения и числа прописью. «Двести сорок тысяч рублей 00 копеек» не должен писать человек, это делает библиотека, и она же ставит правильный падеж у наименований.
Нумерация: единственное место, где легко всё сломать
Номер документа обязан быть уникальным и непрерывным в рамках своей серии. Это самая скучная часть системы и самая опасная.
Если номер вычисляется как «максимальный существующий плюс один» без блокировки, два счёта, выставленные в одну секунду, получат один номер. Такое случается редко, но случается, а обнаруживается через месяц при сверке с бухгалтерией.
Правильно вести отдельный счётчик серии, который выдаёт номер атомарно — то есть так, что два запроса физически не могут получить одно значение. Номер выдаётся один раз и закрепляется за документом навсегда.
Отсюда следует правило, которое удивляет заказчиков: удалять документ нельзя, можно только аннулировать. Дыра в нумерации объясняется аннулированным документом, а исчезнувший номер объяснить нечем.
Как рождается сам файл
Собранный текст надо превратить в файл, который одинаково выглядит у всех. Здесь два рабочих пути.
Первый: HTML-разметка, которую сервер печатает в PDF безголовым браузером. Плюс — вёрстка делается привычными средствами, таблицы и колонтитулы ведут себя предсказуемо. Минус — на сервере живёт браузер, и он ест память.
Второй: шаблон DOCX, в котором подменяются значения. Плюс — документ остаётся редактируемым, юрист правит его в привычной программе. Минус — вёрстка сложных таблиц капризна.
Мы обычно делаем оба: DOCX для тех, кто будет править, PDF для тех, кто будет подписывать и хранить. Файл генерируется на сервере, а не в браузере клиента, иначе результат зависит от шрифтов на конкретном компьютере.
Готовый файл кладётся в хранилище и привязывается к сделке. Повторное нажатие кнопки не создаёт второй файл, а отдаёт тот же самый — иначе в папке накапливаются пять версий одного счёта с разным временем создания.
Порядок состояний, а не набор кнопок
Документы связаны между собой порядком, и система должна этот порядок знать.
Счёт выставляется по сделке. Оплата привязывается к счёту, а не к сделке вообще — иначе при частичной оплате непонятно, что закрыто. Акт формируется после выполнения работ и ссылается на договор и на состав сделки.
В коде это выглядит как набор разрешённых переходов: из «черновик» можно в «выставлен», из «выставлен» в «оплачен» или «аннулирован», из «оплачен» назад нельзя. Такой список переходов дешевле любой инструкции для менеджера, потому что он не зависит от того, прочитал ли менеджер инструкцию.
В проектах, где мы делаем админку, к этому почти всегда добавляется разделение прав: менеджер формирует и отправляет документы, но не меняет реквизиты компании и не правит шаблоны. Тот же принцип, что и в наших магазинах, где сборщик видит заказы, но не видит денег.
Что ещё придётся сделать, кроме генерации
Три вещи, которые всплывают уже после того, как файл научился собираться.
Отправка. Документ надо доставить клиенту: письмом со ссылкой, в личный кабинет, в мессенджер. Ссылка должна быть неугадываемой, иначе чужой счёт открывается перебором номера.
Хранение версий. Если договор переподписан в новой редакции, старая не исчезает. Хранится обе, с датами и с пометкой, какая действует.
Журнал действий. Кто сформировал, кто аннулировал, когда. Это тот самый ответ на вопрос «почему пропал счёт», который иначе занимает полдня переписки.
Кому это не нужно
Если вы выставляете три-четыре документа в месяц, автоматизация не окупится. Шаблон в текстовом редакторе и папка с файлами закроют задачу дешевле, а сэкономленное время измеряется минутами.
Смысл появляется примерно с двадцати-тридцати документов в месяц, при повторяющемся составе сделок и при наличии второго человека, который эти документы трогает. Тогда исчезают опечатки в ИНН, разъехавшаяся нумерация и вопрос «а мы точно выставили счёт этому клиенту».
Если у вас стандартный товарный документооборот и вы уже работаете в бухгалтерской системе, часто дешевле стыковать сайт с ней, чем строить генерацию заново. Свою генерацию имеет смысл делать, когда документы нестандартные, зависят от расчёта на сайте или должны выдаваться клиенту мгновенно в момент заказа. Порядок цен на такие работы — в разделе цены.
Коротко
Автоматические документы держатся на четырёх опорах: данные разложены по полям, текст живёт в шаблоне отдельно от кода, номера выдаёт атомарный счётчик без права на удаление, файл генерируется на сервере и привязывается к сделке. Состояния документа описываются списком разрешённых переходов, а не устной договорённостью с менеджером. При малом объёме документов всё это не нужно: пока их единицы, шаблон в редакторе честно выигрывает по деньгам.
Первый разговор — разбор задачи: нужна ли вам система или хватит одной страницы. Без обязательств и без счёта.
Частые вопросы
Документы, сформированные системой, имеют юридическую силу?
Силу даёт содержание и подписи, а не способ создания файла. Печатный договор, собранный по шаблону и подписанный сторонами, ничем не отличается от набранного руками. Если нужен обмен без бумаги, добавляется электронная подпись — это отдельный узел и отдельные деньги.
Что будет, если юрист поменяет формулировку в договоре?
Меняется шаблон, а не код. Шаблон лежит отдельным файлом с подставляемыми полями, и правка текста не требует разработчика. Ломается только тот случай, когда юрист добавляет новое поле, которого нет в данных: тогда нужно решить, откуда его брать.
Можно ли встроить это в уже работающий сайт?
Обычно да, если в системе уже есть заказы и реквизиты клиента в структурированном виде. Если реквизиты хранятся строкой в комментарии к заказу, сначала придётся разделить их на поля. Это и есть основная часть работы, а не сама генерация файла.
Те, что не помогают, мы переписываем — по этой кнопке и решаем, какие именно.
Ещё по теме
Что малому бизнесу от CRM реально нужно, чем готовая система отличается от своей внутри сайта и по каким признакам выбирать между ними.
тем, кто заказывает CRM купили, а работать в ней не стали: разбор причинШесть ошибок, из-за которых оплаченная CRM превращается в пустую базу, и что делать с каждой, пока подписка ещё действует.
тем, кто заказывает Freedom Gym: клубная система с абонементами и расписаниемИстория одного проекта: как из журнала на ресепшене выросла клубная система с абонементами, расписанием и правами тренеров, и что пошло не так.
тем, кто заказывает