Товарные позиции в документах¶
Список товаров и услуг из карточки сделки, смарт-процесса или смарт-счёта можно вывести в документ таблицей: у сущности есть служебная коллекция productrows, а у каждой позиции — стандартный набор полей (название, количество, цена, скидка, налоги).
Работает для объектов типов: сделка (crm_deal), смарт-процесс (crm_item_<id>), смарт-счёт (crm_smart_invoice).
Вывод списка позиций¶
Коллекция obj.productrows перебирается обычным циклом for — внутри доступны поля конкретной позиции через переменную цикла (в примерах — row):
{% for row in obj.productrows %}
{{ loop.index }}. {{ row.productName }} — {{ row.quantity }} {{ row.measureName }} × {{ row.price }} ₽
{% endfor %}
Таблица в Word
Чтобы каждая позиция стала строкой таблицы, размещайте цикл в теге строки таблицы {%tr — тогда строки документа будут расти вместе со списком товаров.
{%tr for row in obj.productrows %}
{{ loop.index }} {{ row.productName }} {{ row.quantity }} {{ row.measureName }} {{ "%.2f"|format(row.price * row.quantity) }}
{%tr endfor %}
Поля позиции (row.*)¶
| Поле | Описание |
|---|---|
row.productName |
Название товара/услуги, как указано в позиции |
row.quantity |
Количество |
row.measureName |
Единица измерения (шт, кг и т.п.) |
row.price |
Цена за единицу |
row.priceExclusive |
Цена без скидки |
row.priceAccount |
Цена для учёта (в валюте сделки) |
row.priceNetto |
Цена без НДС |
row.priceBrutto |
Цена с НДС |
row.discountRate |
Скидка, % |
row.discountSum |
Скидка, сумма |
row.taxRate |
Ставка НДС, % |
row.taxIncluded |
НДС включён в цену (да/нет) |
row.sort |
Порядок позиции в карточке (позиции выводятся уже отсортированными) |
Пример строки «сумма с учётом количества» с форматированием до двух знаков:
Итого по позиции: {{ "%.2f"|format(row.price * row.quantity) }} ₽
Данные товара из каталога (row.product.*)¶
Если к позиции привязан товар из каталога, через row.product доступны его поля — например, {{ row.product.NAME }}. Поддерживаются и файловые поля товара: главная фотография (DETAIL_PICTURE) и свойства-галереи — их вставляют фильтром inline_image:
Товар: {{ row.productName }}
Фото: {{ row.product.DETAIL_PICTURE|inline_image(Cm(8)) }}
Галерея (каждая картинка свойства — отдельной строкой):
{% for img in row.product.PROPERTY_101 %}
{{ img|inline_image(Cm(6)) }}
{% endfor %}
Свойства товара подставляются своими именами полей (PROPERTY_…) из карточки товара торгового каталога.
Картинки и файлы из карточки товара¶
Файловые поля товара — главная фотография (DETAIL_PICTURE), превью (PREVIEW_PICTURE), свойства-галереи (PROPERTY_…) — можно вставлять в документ как картинки или использовать ссылки на них.
Для вставки картинки в документ используйте фильтр inline_image — файл скачивается с портала Битрикс24 в момент генерации и вставляется в нужный размер:
{{ row.product.DETAIL_PICTURE|inline_image(Cm(8)) }}
Свойства-галереи перебираются циклом — каждая картинка выводится отдельно:
{% for img in row.product.PROPERTY_101 %}
{{ img|inline_image(Cm(6)) }}
{% endfor %}
Если нужна не сама картинка, а ссылка на файл, обращайтесь к атрибутам источника:
Ссылка на фото: {{ row.product.DETAIL_PICTURE.downloadUrl }}
Как это работает под капотом:
- файл не скачивается, пока шаблон его не использует: обращение к полю отдаёт ленивый источник, байты грузятся только при
inline_image; - в рамках одной генерации каждый файл скачивается один раз (кэш по ссылке), повторные вставки той же картинки бесплатны;
- вставляются картинки PNG, JPEG и GIF размером до 10 МБ; файлы другого типа, слишком большие файлы и недоступные ссылки не вставляются — документ не падает, вместо картинки остаётся пустое место;
- если ссылка на файл устарела (например, после обновления прав на портале), приложение само обновит данные сущности и попробует скачать файл заново.
Файловые поля работают не только у товара: так же доступны файловые UF-поля сделок и смарт-процессов — для них действуют те же правила (ленивая загрузка, inline_image); ссылка на файл у UF-поля — в атрибуте urlMachine, а не downloadUrl.
Поведение текста
Если файловое поле вывести просто как текст ({{ obj.UF_FILE }} без inline_image), в документ попадёт видимая заглушка %файл% (или %имя-файла%, если имя известно), а не ссылка. Для ссылки используйте атрибут downloadUrl (у UF-полей — urlMachine), для картинки — фильтр inline_image.
Актуальность данных¶
obj.productrows читается из локальной базы приложения — позиции синхронизируются вместе с объектом при генерации документа. Если нужна гарантированно свежая выборка прямо из Битрикс24, используйте функцию rev:
{% set rows = obj.rev("crm_item_productrow", "ownerId", raw_filter={"ownerType": "D"}) %}
где ownerType: D — сделка, I — счёт (старая версия), Q — предложение, SI — смарт-счёт; для смарт-процессов код владельца вычисляется из его ID (вида Tb1).
Частые вопросы¶
Почему в документе нет габаритов товара (ширина/длина/высота)?
В позицию попадают данные, которые Битрикс24 отдаёт для товарной строки: название, количество, цена, скидки, налоги, единица измерения. Габариты из карточки торгового каталога в этот список не входят, поэтому вставить их в шаблон сейчас нельзя — ни через row.*, ни через row.product.*.
Почему часть позиций не выводится?
Позиции берутся из локальной синхронизации: если товары добавили в карточку позже последней синхронизации или у сущности другой тип (лид, контакт, компания — у них товарных позиций в этом формате нет), список будет неполным или пустым. Для лидов доступны только строковые поля CRM_PRODUCT_NAME, CRM_PRODUCT_COUNT (см. Имена полей Лида).
Обращайтесь к нашим специалистам
По любым вопросам настройки и расширения имеющегося функционала приложений обращайтесь в нашу службу поддержки.
Мы всегда поможем вам решить вашу задачу.
- Телеграмм: https://t.me/pavzhukov
- Телефон: +7 495 124-84-27