Печатные бланки: теги и подстановки
Суммы прописью, числа для колонок, реквизиты компании в бланке и счёт на каждый склад — с готовыми кусками разметки.
На этой странице
Счёт, накладная и всё остальное, что магазин печатает по заказу, — это тоже шаблоны: обычная разметка страницы с подстановками из заказа. Правятся они в «Настройки» → «Печатные формы», каждая на своём языке, а кнопка «Посмотреть» показывает готовую бумагу на настоящем заказе — можно ввести номер того заказа, ради которого правка и затевалась.
Бланк пишется теми же тегами, что и тема, плюс несколько своих — денежных.
Деньги, числа и количество
{sum amount=$order.total} Разом: 1 250,50 ₴
{in_words amount=$order.total} Одна тисяча двісті п’ятдесят гривень 50 коп.
{number value=$item.price} 1250.50
{number value=$item.weight precision=3} 6.100
{qty value=$item.qty} 1.5
{sum} берёт валюту самого заказа — писать её в каждом месте бланка не нужно.
{number} печатает голое число ровно в сотых: его ставят в колонки, где валюта
вынесена в шапку. {qty} печатает количество без хвостовых нулей, чтобы штучный
товар не выглядел как «2.000».
Заказ — это снимок: суммы, цены и курс в нём остаются такими, какими были в день оформления. Бланк ничего не пересчитывает, он только печатает.
От какой компании счёт
{profile id=2} дальше весь бланк печатается от этой компании
{profile id=2 assign=seller} реквизиты лягут в $seller, $shop не тронут
Компанию объявляет сам бланк, а не тот, кто нажал «Печать». Поэтому «Счёт от ФОП» и «Счёт от ТОВ» — два разных бланка: выбирать компанию при каждой печати не нужно, да и в письме со счётом выбирать некому. Номер профиля показывает подсказка под редактором, там же его можно вставить нажатием.
Профиль удалили, а бланк на него ссылается — напечатается продавец витрины заказа: пустая шапка счёта хуже неточной.
Что доступно в бланке
| Переменная | Что внутри |
|---|---|
$doc |
сам документ: number, date, title |
$shop |
продавец: name, legal_name, tax_number, vat_number, tax_system, address, phone, email, bank_name, iban, director, accountant, logo, stamp, signature |
$order |
заказ: number, date, comment, items_total, services_total, discount_total, shipping_total, tax_total, total, paid_total, due, total_in_words, weight, storefront, status |
$customer |
покупатель: name, company, tax_number, phone, email, address |
$recipient |
другой получатель — или null, если посылку принимает сам покупатель |
$items |
позиции заказа, перебираются {foreach} |
$warehouses |
тот же заказ, разложенный по складам |
$shipping, $payment |
доставка и оплата: id, code, name, адрес и точка получения, номер накладной, оплачено и когда |
Позиция ($item внутри цикла) даёт n, name, sku, unit, qty, price,
discount, total, tax_rate, tax, photo, weight, упаковку (pack.name,
pack.packs, pack.rest), характеристики (features, feature), услуги
(services) и склад отгрузки (warehouse, warehouse_id).
Полный перечень с человеческими подписями лежит прямо под редактором бланка —
«Что можно подставить в бланк»: нажатие вставляет подстановку туда, где стоит
курсор. А что пришло в этот конкретный документ, покажет {dump}.
Таблица позиций
<table>
{foreach $items as $item}
<tr>
<td>{$item.n}</td>
<td>{$item.name}{if $item.sku} ({$item.sku}){/if}</td>
<td>{qty value=$item.qty} {$item.unit}</td>
<td>{number value=$item.price}</td>
<td>{number value=$item.total}</td>
</tr>
{/foreach}
</table>
<p>Всього до сплати: {sum amount=$order.total}</p>
<p>Прописом: {in_words amount=$order.total}</p>
Другой получатель — отдельным блоком
{if $recipient}
<h3>Отримувач</h3>
<p>{$recipient.name}, {$recipient.phone}</p>
{* или всё, что магазин спросил у покупателя, — с подписями полей *}
{foreach $recipient.fields as $f}
<div>{$f.label}: {$f.value}</div>
{/foreach}
{/if}
Получатель приходит своим набором, а не подмешивается в поля покупателя: посылку принимает человек, даже когда заказ оформляет компания. Нет другого получателя — переменная пуста, и блок не печатается.
Состав полей получателя владелец задаёт сам, поэтому кроме name и телефона в
бланке есть перебираемый список fields — с подписью и значением каждого поля.
Отметка «заказ забирает компания» лежит отдельно, в is_company, и в перебор не
попадает.
Счёт на каждый склад
Магазину, у которого склады принадлежат разным юрлицам, нужен счёт от того, чей
товар в строке. Заказ приходит в бланк разложенным по складам, а компанию для
каждого объявляет {profile}:
{$fops = [1 => 2, 5 => 3, 6 => 4]} {* номер склада → номер профиля *}
{foreach $warehouses as $w}
{profile id=$fops[$w.id] assign=seller}
<h2>{$seller.legal_name}</h2>
<p>{$seller.address}, {$seller.iban}</p>
{foreach $w.items as $item}
<div>{$item.name} — {qty value=$item.qty} × {number value=$item.price}</div>
{/foreach}
<p>Разом: {sum amount=$w.total}</p>
{/foreach}
Готовую заготовку этого куска можно вставить из подсказки под редактором — останется вписать свои номера складов и профилей. Доставку и скидку на заказ магазин между складами не делит: как их разнести между юрлицами, решаете вы в самом бланке.
Бумага и печать
Бланк печатается браузером и сохраняется в PDF, поэтому вёрстка простая: таблицы, отступы, размеры в миллиметрах. Размер листа задаётся в стилях бланка:
<style>{literal}
@page { size: A4 portrait; margin: 12mm; }
body { font-family: Arial, "DejaVu Sans", sans-serif; font-size: 11px; }
{/literal}</style>
{literal} здесь обязателен: без него фигурные скобки CSS шаблонизатор примет
за свои теги.
Если бланк сломался
Опечатка в разметке не роняет магазин: вместо документа откроется страница с объяснением, в какой форме ошибка. Кнопка «Вернуть заводской вид» возвращает бланк, который идёт с магазином, — ваши правки при этом заменяются, отменить это нельзя.
Тем же способом смотрят, что нового появилось в заводском бланке после обновления магазина: ваши правки обновление не трогает, поэтому свежий бланк виден только так.