Логика
Любой документ в системе рано или поздно превращается в PDF-файл — сгенерированный из шаблона и заполненный данными заявки/клиента, загруженный менеджером (Word, Excel и т.п.), либо кассовый чек. Во всех случаях превращение выполняет один и тот же внешний сервис конвертации (движок на базе Chromium и утилиты работы с PDF). Модуль отвечает за то, что передать в этот сервис и как собрать результат: подставить данные в шаблон, отрисовать PDF, поставить QR-штамп с UUID документа и, при необходимости, приложить страницу-подтверждение с историей подписания.Подстановка данных в шаблон (сборка HTML документа)
Когда документ создаётся или запрашивается пересборка контента, система берёт шаблон и связанную заявку на аренду и строит готовый HTML-текст, заменяя плейсхолдеры реальными значениями.- Если у шаблона задан фильтр по инвентарю и/или услугам, он применяется к списку позиций заявки. Для инвентаря фильтр влияет и на итоговые суммы, и на построчную таблицу; для услуг — только на построчную таблицу и счётчик их количества (итоговые суммы «по услугам» и «цена доставки» этим фильтром не затрагиваются).
- Позиции аренды, заменённые (обменянные) на другие, всегда исключаются из документа.
- Если у пользователя-создателя документа есть доверенность, оформленная от имени другого сотрудника, в плейсхолдеры доверенности подставляются данные именно родительской доверенности.
- Если данных для плейсхолдера нет, подставляется технический прочерк-заполнитель.
Версия «прописью» любой денежной суммы озвучивает её в валюте компании — из той же настройки, что и числовая версия. Для валют без словесной формы прописью выводится целая часть плюс символ валюты, копейки — цифрами; незаполненная сумма читается как ноль. Подробности — в «Плейсхолдерах шаблонов».
Построчные таблицы документа
Шесть видов данных заявки подставляются построчно, размножая строку HTML-таблицы: арендуемый инвентарь, проданные товары, группы инвентаря, услуги, штрафы и доставки. Если в шаблоне нет строки с плейсхолдером нужного вида — соответствующие данные из базы вообще не запрашиваются (это особенно важно для таблицы групп инвентаря, чей расчёт требует нескольких дополнительных подзапросов).Во всех шести таблицах неизвестный (или ещё не поддерживаемый) плейсхолдер внутри строки просто остаётся текстом «как есть» — сборка документа не прерывается, а сам факт записывается в журнал, чтобы опечатку в шаблоне можно было найти. Раньше в таблицах услуг, штрафов и доставок такой плейсхолдер завершал сборку документа ошибкой.
Рендер HTML в PDF
Готовый HTML оборачивается в общий шаблон печати и отправляется во внешний сервис как задание «HTML в PDF». Настройки страницы берутся из шаблона документа, только если он вообще выбран — если нет, эти параметры не передаются, и размер страницы определяется настройками сервиса по умолчанию. Результат сохраняется как файл типа «Оригинал» — «чистый» PDF без отметок о подписании.QR-штамп и страница-подтверждение подписания
Помимо «чистого» оригинала, для каждого документа готовится «Подписанный файл» — тот же контент, но с QR-кодом и UUID документа в подвале каждой страницы, а также (при выполнении условий) с приложенной страницей-подтверждением подписания.- Сгенерированный документ. Подвал и боковая полоса передаются в сервис конвертации одновременно с основным содержимым — штамп встраивается прямо на этапе рендера, за один проход.
- Загруженный документ. Исходный PDF уже существует, поэтому система измеряет его фактический размер, отдельно рендерит подвал той же ширины и высоты и накладывает штамп поверх всех страниц через отдельную операцию.
Когда файлы пересобираются
Отдельная фоновая задача поддерживает актуальность производных файлов документа и запускается при создании документа, при добавлении/изменении подписанта и при завершении подписания по SMS-коду.Конвертация загруженных файлов и генерация чеков
Если менеджер загружает документ не в формате PDF (Word, Excel и т.п.), система по расширению имени файла определяет, что конвертация нужна, и прогоняет файл через отдельную операцию конвертации того же внешнего сервиса — исходный файл не хранится отдельно.В модуле подготовлена (и полностью реализована) отдельная функция генерации кассового чека, но по всему проекту ни один сценарий её сейчас не использует.
Особенности поведения
- Плейсхолдер «цена доставки по заявке» на самом деле суммирует стоимость всех типизированных доп. услуг заявки, включая, например, услуги мастерской, а не только услуги доставки.
- После подстановки всех значений из готового HTML убираются переносы строк, а также любое буквальное вхождение служебного слова-маркера — если оно случайно встретится в тексте шаблона, оно молча исчезнет из документа.
- Расширенный синтаксис плейсхолдера с уточняющим суффиксом в квадратных скобках распознаётся при поиске строки для клонирования, но логика подстановки значения по суффиксу нигде не реализована.
- Определение, нужно ли конвертировать загруженный файл в PDF, делается по расширению имени файла без анализа реального содержимого.
- В модуле есть более старая функция построения PDF с жёстко заданным форматом страницы (близким к A4); она нигде не используется — реальный процесс использует более новую функцию с настройками страницы из шаблона.
- Для загруженных документов QR-штамп накладывается отдельной операцией поверх уже готового PDF, тогда как для сгенерированных документов подвал с QR-кодом встраивается сразу при рендере HTML в PDF.