Задача
Ресторанная сеть постоянно обновляет печатные материалы: меню, таблички, вывески, листовки, сезонные плакаты, канцелярию, стартовые наборы для новых локаций. Без единой платформы каждый такой запрос идёт письмом — с пересылкой файлов, уточнением тиража и адреса и ручной проверкой того, актуален ли макет.
Из этого вырастает набор системных рисков. Ресторан может напечатать прошлогоднюю версию меню или уже закрытой кампании. Локальная правка макета «на месте» ломает брендовые правила. Один и тот же запрос вводится заново в нескольких системах. Маркетинг тратит время дизайнера на замену адреса и даты. Превышение допустимого тиража обнаруживается только при ручной обработке. Складские остатки и допечатка рассматриваются раздельно, хотя это один и тот же заказ. Ресторан не видит статуса и уточняет его у людей. И самое неприятное: производственный файл, ушедший в типографию, может отличаться от версии, которую согласовали.
Решение
DAMS как источник истины по контенту. Отдельная система на Symfony хранит рабочие исходники, готовые к печати версии, превью, утверждённые шаблоны, сезонные кампании и региональные варианты. Карточка продукта отделена от файла: к одной позиции привязываются исходник, превью, печатный PDF, локализованные варианты и дополнительные изображения. Один материал может лежать в нескольких логических коллекциях — в кампании, в категории вывесок и в подборке региона — без физического дублирования.
Публикация без двойного ввода. Из DAMS карточки публикуются в каталог Magento вместе с идентификатором, категориями, вариантами, производственным файлом и правилами видимости. Обмен версионный и идемпотентный: повтор события не создаёт вторую карточку, замена файла обновляет только свою версию, снятый с публикации материал исчезает из новых заказов, но остаётся в истории, а уже оформленный заказ продолжает ссылаться на конкретную утверждённую версию. Ошибка синхронизации уходит в очередь с безопасным повтором.
Генератор брендовых шаблонов. Ресторан открывает утверждённый шаблон и заполняет только разрешённые поля: адрес, даты кампании, часы работы, локальное предложение. Логотип, типографика, цвета, отступы, обязательные подписи и технические зоны заблокированы. Известные данные подставляются из профиля локации, правила проверяют обязательные значения, длину текста и допустимость конфигурации, при необходимости макет уходит на согласование. Только после подтверждения генерируется зафиксированная версия для печати, которая и попадает в заказ и в типографию. Шаблон и созданный экземпляр хранятся раздельно: обновление шаблона не меняет уже утверждённый заказ, но новые запросы берут актуальную версию.
Лимиты и пересчёт согласований. Превышение лимита не блокирует заявку, а переводит её на согласование. Матрица учитывает ресторан, регион и роль автора, категорию и материал, количество и внутреннюю стоимость. В расчёт идут также кампания и период, стандартная или нестандартная конфигурация, наличие остатка, срочность и способ доставки. Согласующий видит причину срабатывания правила, действующий лимит, выбранный макет и предполагаемый способ исполнения. Он может утвердить заявку, уменьшить количество, вернуть на изменение или отклонить с комментарием. После правки количества, макета или адреса правила пересчитываются заново, и решение по предыдущей версии на изменённую заявку не переносится.
Выбор источника исполнения. Заказ может закрываться готовым остатком, новой печатью или их сочетанием. Оркестратор сравнивает наличие, расположение ресторана и склада, срок и стоимость перевозки, возможность и срок допечатки, загрузку вендора, обязательную дату кампании и стоимость разделённого исполнения. Если локальная допечатка быстрее перевозки с удалённого склада, задание уходит типографии, даже когда остаток есть. Часть тиража при этом может приехать со склада, остаток — из печати, а ресторан видит один заказ с несколькими линиями исполнения и отдельным отслеживанием каждой посылки. Дешёвый вариант, не успевающий к запуску кампании, допустимым не считается.
Нестандартные заказы. Если нужной конфигурации нет в каталоге, пользователь заполняет структурированный бриф: тип материала, назначение и кампания, тираж и срок, размеры, материал, референсы, адрес. У запроса свой маршрут: проверка полноты, назначение ответственного, уточнение, расчёт стоимости, согласование, макет. Затем он становится обычным производственным заказом, проходит общую цепочку исполнения и отслеживания и поэтому не выпадает из истории ресторана.
Идемпотентность и объяснимость. Повторный webhook не должен создавать второй заказ, резерв, задание на печать или отправление: каждая внешняя операция хранит идентификатор корреляции, исходное событие, результат и число попыток. При частичном сбое выполненная физическая операция не отменяется вслепую. Оркестратор запускает компенсирующее действие. Правила, лимиты и матрицы согласований имеют период действия и версию, поэтому старый заказ можно объяснить настройками, которые действовали в момент его создания.
Архитектурно продукт повторяет схему Yokohama Print, адаптированную под ресторанную операционную модель.
Результат
Tender Greens управляет печатными материалами сети в одной системе. Маркетинг и дизайнеры владеют источниками и версиями в DAMS, рестораны заказывают только разрешённые позиции, а типовые локальные правки выполняются через безопасные брендовые шаблоны, не проходя через дизайнера.
Согласования, склад, печать по требованию, доставка и отслеживание идут в одном процессе, без разрозненной ручной работы. Каждая заявка сохраняет связь между рестораном, утверждённой версией макета, решением согласующего, источником исполнения и конкретным отправлением. Корпоративный вход и серверная авторизация не дают обойти лимит прямой ссылкой или чужим идентификатором локации.
Операционная аналитика показывает спрос по ресторанам и кампаниям, время согласований, долю смешанного исполнения и загрузку типографий. По ней же видно, какие повторяющиеся нестандартные заказы пора завести в каталог обычной карточкой.