Товарные позиции сделки — это строки с товарами и услугами, из которых складывается её сумма. Методы crm.deal.productrows.get и crm.deal.productrows.set читают и полностью перезаписывают этот список. Разберём структуру строки, скидки, налоги и пересчёт итога.
Как устроены товарные строки
Товарные строки — самостоятельная сущность, привязанная к сделке. У сделки нет отдельного «товара»: сумма OPPORTUNITY формируется из строк, если не включён ручной режим. Работают с ними два основных метода:
crm.deal.productrows.get— вернуть все строки сделки;crm.deal.productrows.set— заменить весь набор строк новым.
Важно понимать: set работает по принципу полной замены. Нельзя добавить одну строку, не передав остальные, — метод удалит всё, чего нет в переданном массиве. Чтобы дописать позицию, сначала получите текущие строки через get, добавьте новую в массив и отправьте его целиком.
crm.item.productrow.*, к которому Битрикс постепенно смещает акцент.Поля строки товара
Каждая позиция описывается набором полей. Ниже — те, что нужны чаще всего.
| Поле | Смысл |
|---|---|
PRODUCT_ID | ID товара из каталога (0 — свободная позиция) |
PRODUCT_NAME | Название позиции |
PRICE | Цена за единицу с учётом скидки и налога |
QUANTITY | Количество |
DISCOUNT_TYPE_ID | Тип скидки: 1 — абсолютная, 2 — процентная |
DISCOUNT_RATE / DISCOUNT_SUM | Процент или сумма скидки |
TAX_RATE | Ставка НДС, % |
TAX_INCLUDED | Налог включён в цену: Y / N |
MEASURE_CODE / MEASURE_NAME | Единица измерения (код и название) |
Полный перечень возвращает crm.deal.productrows.fields. Единица измерения по умолчанию — штука (код 796 по ОКЕИ).
Запись строк: crm.deal.productrows.set
Перезапишем состав сделки двумя позициями — товаром из каталога и услугой:
POST /rest/1/xxxxxx/crm.deal.productrows.set.json
{
"id": 145,
"rows": [
{
"PRODUCT_ID": 51,
"PRICE": 50000,
"QUANTITY": 2,
"DISCOUNT_TYPE_ID": 2,
"DISCOUNT_RATE": 10,
"TAX_RATE": 20,
"TAX_INCLUDED": "Y"
},
{
"PRODUCT_NAME": "Пусконаладка",
"PRICE": 25000,
"QUANTITY": 1
}
]
}Параметр называется id (ID сделки) и массив rows. После успешной записи сумма сделки пересчитается автоматически, если у неё не выставлен флаг IS_MANUAL_OPPORTUNITY = Y.
Чтение строк и логика скидок
Метод crm.deal.productrows.get принимает только id сделки и возвращает массив строк с рассчитанными значениями. Поле PRICE отдаётся уже с учётом скидки, а исходную цену смотрите в PRICE_EXCLUSIVE, PRICE_NETTO и PRICE_BRUTTO.
PRICE_NETTO— базовая цена без скидки и без налога;- применяется скидка →
PRICE_EXCLUSIVE; - добавляется налог →
PRICE_BRUTTOи итоговаяPRICE.
При интеграции с внешним расчётом цен удобнее передавать уже готовую PRICE и указывать скидку явно, чем полагаться на автоматический пересчёт по каталогу.
Связь с каталогом и единицами измерения
Если PRODUCT_ID ссылается на товар каталога, он подтягивает название, единицу измерения и, при желании, цену. Товары каталога живут в отдельном модуле с методами catalog.product.* и старым crm.product.*.
- Свободная позиция (
PRODUCT_ID = 0) требует явногоPRODUCT_NAME; - единицы измерения задаются кодом ОКЕИ в
MEASURE_CODE: 796 — штука, 006 — метр, 166 — килограмм; - для корректных отчётов по товарам лучше ссылаться на реальные
PRODUCT_ID, а не плодить одноимённые свободные строки.
PRODUCT_ID без PRICE цена возьмётся из каталога и может отличаться от ожидаемой. Для детерминированного результата задавайте цену явно.Итог
Товарные строки сделки читаются crm.deal.productrows.get и полностью перезаписываются crm.deal.productrows.set. Помните про принцип полной замены, различайте PRICE_NETTO, PRICE_EXCLUSIVE и PRICE_BRUTTO, задавайте скидки и налоги явно и следите за флагом ручной суммы.
Мы в B2Bsite переносим корзину и позиции заказа с сайта в сделки Битрикс24 без потери скидок и НДС, синхронизируем каталог и единицы измерения с 1С. Если товары в сделках должны совпадать с учётной системой копейка в копейку — поможем выстроить обмен.
Частые вопросы
Можно ли добавить одну строку, не трогая остальные?
Нет, crm.deal.productrows.set полностью заменяет набор. Сначала получите текущие строки через get, добавьте новую в массив и отправьте его целиком.
Как передаётся ID сделки в этих методах?
В параметре id. В set рядом идёт массив rows со строками товаров, в get достаточно одного id.
Чем отличаются PRICE, PRICE_NETTO и PRICE_BRUTTO?
PRICE_NETTO — базовая цена без скидки и налога, PRICE_EXCLUSIVE — после скидки без налога, PRICE_BRUTTO и PRICE — итог с налогом.
Как задать процентную скидку на позицию?
Установите DISCOUNT_TYPE_ID равным 2 и укажите процент в DISCOUNT_RATE. Для абсолютной скидки используйте тип 1 и сумму в DISCOUNT_SUM.
Пересчитается ли сумма сделки после записи строк?
Да, если у сделки не выставлен флаг IS_MANUAL_OPPORTUNITY равный Y. В ручном режиме сумма OPPORTUNITY остаётся неизменной.
Как указать единицу измерения?
Через MEASURE_CODE по классификатору ОКЕИ: 796 — штука, 006 — метр, 166 — килограмм. Название дублируется в MEASURE_NAME.
Что будет, если передать PRODUCT_ID без цены?
Цена подтянется из каталога и может отличаться от ожидаемой. Для предсказуемого результата всегда задавайте PRICE явно.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.