Автоматическая генерация договоров, счетов и актов в PDF
Как устроена автоматическая сборка документов: откуда берутся данные, как выбрать шаблон, на чём собирать PDF, где чаще всего ошибаются в расчётах и что с подписью. С примерами кода.
Содержание
Счёт, договор, акт, коммерческое предложение — документы, которые в небольшой компании часто собирают вручную. Открыть прошлый файл, поменять реквизиты, пересчитать сумму, не забыть сумму прописью, сохранить в PDF, отправить. На один документ уходит 10–15 минут, а ошибка в ИНН или сумме всплывает уже у бухгалтера клиента.
Автоматизация здесь простая по смыслу: данные вводятся один раз, а документ собирается сам. Ниже — как это устроено и о чём подумать заранее.
Какие документы автоматизируют чаще всего
- Коммерческое предложение. Не имеет строгой формы, зато его часто нужно быстро и красиво.
- Счёт на оплату. Важно: счёт — не первичный учётный документ, а предложение оплатить. Строгих требований закона к его форме нет, но в нём должны быть реквизиты для оплаты, позиции и итог.
- Договор. Обычно это шаблон с подстановкой сторон, предмета, сроков и сумм, иногда со спецификацией.
- Акт. Первичный документ, подтверждающий оказание услуг или выполнение работ.
- УПД, накладные, доверенности, анкеты, заявления — всё, что собирается по шаблону.
Обязательные реквизиты первички
Для первичных документов, например акта, закон о бухучёте (ч. 2 ст. 9 402-ФЗ) перечисляет обязательные реквизиты:
- наименование документа;
- дата составления;
- наименование организации, составившей документ;
- содержание факта хозяйственной жизни;
- величина натурального или денежного измерения с единицами измерения;
- должность ответственного лица;
- подписи с расшифровкой — фамилией и инициалами.
Шаблон акта стоит один раз сверить с этим списком, и дальше генератор будет следовать ему без исключений. Это одно из главных преимуществ автоматизации: человек может забыть поле, шаблон — нет.
Как устроена генерация
Схема одинаковая почти для любого проекта:
данные → шаблон → документ → доставка → хранение
Откуда берутся данные
- форма в браузере — менеджер вводит реквизиты и позиции, документ собирается на экране;
- CRM — по кнопке в сделке Битрикс24 или amoCRM данные уходят в генератор, а готовый PDF возвращается в карточку сделки;
- бот — клиент отвечает на вопросы в Telegram или MAX и получает документ прямо в чат;
- таблица или учётная система — пакетная генерация, например актов за месяц по всем клиентам.
Реквизиты контрагента по ИНН можно подтягивать из открытых сервисов, чтобы не вводить вручную название, КПП и адрес.
Шаблон: HTML или DOCX
HTML и CSS → PDF. Шаблон вёрстается как веб-страница, а в PDF его превращает специальная библиотека. Плюсы: точный контроль над видом документа, таблицы, логотип, фирменные цвета, предпросмотр в браузере ровно таким, каким будет PDF. На Python для этого хорошо подходит WeasyPrint.
DOCX-шаблон. Документ готовят в Word, ставят в нём метки вроде {{ client_name }}, а программа подставляет значения. Плюс — шаблон может править юрист или бухгалтер, не трогая код. Для Python есть docxtpl и python-docx; чтобы получить из DOCX ещё и PDF, используют LibreOffice в режиме без интерфейса.
Часто нужны оба формата: PDF — чтобы отправить клиенту, DOCX — чтобы можно было поправить вручную.
Минимальный пример сборки PDF из HTML-шаблона:
from jinja2 import Environment, FileSystemLoader
from weasyprint import HTML
env = Environment(loader=FileSystemLoader("templates"), autoescape=True)
html = env.get_template("invoice.html").render(invoice=invoice)
pdf_bytes = HTML(string=html, base_url="templates").write_pdf()
Где ошибаются чаще всего
Деньги во float
Классическая ошибка — считать суммы в числах с плавающей точкой. В Python 0.1 + 0.2 даёт 0.30000000000000004, и на большом счёте копейки в итоге могут разойтись с суммой строк. Деньги считают в Decimal с явным округлением до копейки.
НДС «в том числе» и «сверху»
С 1 января 2026 года основная ставка НДС — 22%. Генератор должен уметь оба варианта:
- НДС в том числе — цена уже включает налог, его выделяют из суммы;
- НДС сверху — налог начисляют на цену без НДС.
Плюс другие ставки — 10%, 0%, ставки 5% и 7% для упрощенцев — и вариант «без НДС».
from decimal import Decimal, ROUND_HALF_UP
KOP = Decimal("0.01")
def vat_included(total: Decimal, rate: int) -> Decimal:
"""НДС в том числе: выделяем налог из суммы."""
return (total * rate / (100 + rate)).quantize(KOP, ROUND_HALF_UP)
def vat_on_top(net: Decimal, rate: int) -> Decimal:
"""НДС сверху: начисляем налог на сумму без НДС."""
return (net * rate / 100).quantize(KOP, ROUND_HALF_UP)
vat_included(Decimal("122000.00"), 22) # Decimal('22000.00')
Отдельный вопрос — округлять налог построчно или по итогу. Правило нужно выбрать один раз, согласовать с бухгалтером и зашить в генератор.
Сумма прописью
«Сто двадцать две тысячи рублей 00 копеек». Кажется мелочью, но в русском языке это склонения рублей, тысяч и миллионов, женский род у тысяч — «одна тысяча», «две тысячи» — и много граничных случаев. Такую функцию обязательно покрывают тестами: 1, 2, 5, 11, 21, 101, 1 000 000 и так далее.
Шрифты
Если не встроить шрифт с кириллицей в PDF, на другом компьютере вместо текста могут появиться квадратики. Генератор должен встраивать шрифт в файл, а не надеяться на шрифты получателя.
Нумерация
Номера счетов и актов должны идти по порядку и не дублироваться, даже если два менеджера нажали кнопку одновременно. Это решается на уровне базы данных, а не «возьмём последний номер и прибавим единицу».
Подпись и юридическая значимость
Сгенерированный PDF — это электронная копия. Как она становится документом с юридической силой, зависит от того, как вы его подписываете.
- Печать и подпись на бумаге. PDF распечатывают, подписывают и сканируют или отправляют оригинал почтой. Генератор просто экономит время на подготовке.
- Картинка подписи в PDF. Удобно для КП и счетов, но картинка — не электронная подпись в смысле закона.
- Электронная подпись (63-ФЗ) и ЭДО. Для юридически значимого электронного документооборота документы подписывают квалифицированной электронной подписью и обычно передают через оператора ЭДО. Если документ подписывает не руководитель, а уполномоченный сотрудник, с 1 сентября 2024 года нужна личная подпись сотрудника и машиночитаемая доверенность — МЧД.
Генератор хорошо встраивается в любую из этих схем: он собирает документ, а дальше файл уходит на подпись тем способом, который принят у вас и ваших контрагентов. Интересно, что подписание документов появляется и в мессенджерах: на платформе MAX для партнёров есть опция подписания документов «Госключом» — правда, только для юрлиц и ИП.
Доставка и хранение
Документ мало собрать — его нужно отправить и потом найти.
- Отправка: на email клиента, в чат бота, в карточку сделки в CRM.
- Хранение: в облаке или на своём сервере, с понятной структурой — по клиентам и датам — и с поиском.
- Журнал: кто и когда сформировал документ, с какими данными. Это помогает разобраться, если клиент говорит «мне пришёл не тот счёт».
Если в документах есть персональные данные — например, паспортные данные в договоре с физлицом, — к хранению применяются требования 152-ФЗ. Генерировать документ «на лету» и не хранить лишнего — хорошая практика.
Сколько времени это экономит
Считать стоит на своих цифрах. Если менеджер вручную собирает документ за 10–15 минут, а генератор — за минуту на ввод данных, то при 20 документах в неделю это несколько часов рабочего времени каждую неделю. Плюс меньше ошибок, которые потом исправляют бухгалтеры с обеих сторон. Если документов два в месяц, автоматизация, скорее всего, не окупится — и это тоже нормальный вывод.
Документы прямо в чат-боте
Отдельный удобный сценарий — генерация документов в мессенджере. Клиент или сотрудник отвечает на несколько вопросов в Telegram или MAX, а бот присылает готовый PDF в тот же чат. Никаких форм на сайте и писем с вложениями.
Где это работает хорошо:
- счёт по запросу — клиент выбирает услугу и вводит ИНН, бот присылает счёт на оплату;
- анкета или заявление — бот задаёт вопросы по очереди, проверяет ответы и собирает документ;
- акт после выполнения работ — менеджер нажимает кнопку в рабочем чате, акт уходит клиенту.
Технически бот просто вызывает тот же генератор, а затем загружает файл в мессенджер и прикрепляет к сообщению. Так устроен мой демо-бот «Виртуальный рекрутер» в MAX: после скрининга он собирает анкету кандидата в PDF и присылает её прямо в чат.
Важная деталь: если в документ попадают персональные данные, бот должен получить согласие на их обработку и не хранить больше, чем нужно для задачи.
Как это выглядит вживую
Я сделал онлайн-демо генератора документов. Это демо-проект, введённые данные нигде не сохраняются. В нём можно:
- собрать КП, счёт, договор со спецификацией и акт;
- добавлять позиции и смотреть живой предпросмотр;
- выбрать ставку НДС — 0, 5, 7, 10 или 22% — и вариант «в том числе», «сверху» или без НДС;
- получить сумму прописью;
- добавить логотип, выбрать тему оформления и скачать результат в PDF или DOCX.
Под капотом — всё, о чём шла речь выше: расчёты в Decimal, сумма прописью с тестами, PDF из HTML-шаблона через WeasyPrint со встроенным шрифтом и нативные таблицы Word в DOCX.
С чего начать автоматизацию
- Выберите один документ, который делаете чаще всего, — обычно это счёт или акт.
- Соберите эталонный шаблон и согласуйте его с бухгалтером.
- Определите, откуда берутся данные: форма, CRM, бот или таблица.
- Решите, куда уходит готовый файл и где он хранится.
- Когда первый документ заработает, добавьте остальные по тому же шаблону.
Если хотите автоматизировать документы под свои шаблоны и встроить генератор в CRM или бота, напишите мне — разберу процесс и предложу, как сделать его проще.
Посмотреть вживую
Мои демо-проекты по теме статьи. Они работают, их можно открыть и потрогать. Это демонстрации, а не работы для клиентов.