CRM
Товары в сделках
Рабочая справка по товарам в сделках CRM в коробочном Bitrix24: товарные строки, LoadProductRows, SaveProductRows, поля и события.
Товары сделки — это товарные строки, а не просто одно поле сделки. При сохранении набора товаров важно помнить: часто сохраняется весь список строк, а не одна отдельная строка.
Общее понимание
Товарные строки описывают, что продаётся в сделке: товар, количество, цена, скидка, налог.
Что такое товарные строки
Одна сделка может иметь несколько товарных строк. Каждая строка — отдельная позиция с товаром, ценой и количеством.
Старые и новые методы
В REST старые методы crm.deal.productrows.* помечены как устаревшие, а
для новых интеграций рекомендуются crm.item.productrow.*. В коробочном PHP
для сделок часто используются старые методы класса CCrmDeal.
| Задача | Коробочный PHP | REST |
|---|---|---|
| Получить товары сделки | CCrmDeal::LoadProductRows() | crm.item.productrow.list |
| Заменить товары сделки | CCrmDeal::SaveProductRows() | crm.item.productrow.set |
| Изменить одну строку | Зависит от версии и задачи | crm.item.productrow.update |
Коробочный PHP
Базовые операции с товарами сделки через CCrmDeal.
Получить товары сделки
<?php
use Bitrix\Main\Loader;
Loader::includeModule('crm');
/**
* Получает товарные строки сделки.
*/
function fetchDealProductRows(int $deal_id): array
{
if ($deal_id <= 0) {
return [];
}
$product_rows = \CCrmDeal::LoadProductRows($deal_id);
return is_array($product_rows) ? $product_rows : [];
}
$product_rows = fetchDealProductRows($deal_id);
print_r($product_rows); Сохранить товары сделки
SaveProductRows() сохраняет переданный список строк. Перед вызовом лучше
получить текущие строки и явно понимать, заменяется весь набор или только добавляется
позиция.
<?php
use Bitrix\Main\Loader;
Loader::includeModule('crm');
/**
* Собирает товарную строку.
*/
function buildProductRow(int $product_id, string $product_name, float $price, float $quantity): array
{
return [
'PRODUCT_ID' => $product_id,
'PRODUCT_NAME' => $product_name,
'PRICE' => $price,
'QUANTITY' => $quantity,
'DISCOUNT_TYPE_ID' => 1,
'DISCOUNT_RATE' => 0,
'TAX_RATE' => 0,
];
}
/**
* Сохраняет товарные строки сделки.
*/
function saveDealProductRows(int $deal_id, array $product_rows): bool
{
if ($deal_id <= 0) {
return false;
}
return \CCrmDeal::SaveProductRows($deal_id, $product_rows);
}
$product_rows = [
buildProductRow(0, 'Услуга внедрения', 15000, 1),
];
$is_saved = saveDealProductRows($deal_id, $product_rows);
var_dump($is_saved); Скопировать товары в другую сделку
При копировании строк в другую сделку ID строк лучше обнулить, чтобы они были созданы заново.
<?php
use Bitrix\Main\Loader;
Loader::includeModule('crm');
/**
* Копирует товарные строки из одной сделки в другую.
*/
function copyDealProductRows(int $source_deal_id, int $target_deal_id): bool
{
$product_rows = \CCrmDeal::LoadProductRows($source_deal_id);
if (!is_array($product_rows)) {
return false;
}
foreach ($product_rows as &$product_row) {
$product_row['ID'] = 0;
}
unset($product_row);
return \CCrmDeal::SaveProductRows($target_deal_id, $product_rows);
}
$is_copied = copyDealProductRows($source_deal_id, $target_deal_id);
var_dump($is_copied); Поля товарной строки
Чаще всего нужны товар, название, цена, количество, скидка и налог.
Основные поля
| Поле | Что означает |
|---|---|
ID | ID товарной строки. |
PRODUCT_ID | ID товара каталога. Может быть 0 для произвольной позиции. |
PRODUCT_NAME | Название позиции. |
PRICE | Цена. |
QUANTITY | Количество. |
DISCOUNT_TYPE_ID | Тип скидки. |
DISCOUNT_RATE | Размер скидки. |
TAX_RATE | Ставка налога. |
События товарных строк
У сделок есть события сохранения товарных строк:
OnBeforeCrmDealProductRowsSave и
OnAfterCrmDealProductRowsSave.
<?php
use Bitrix\Main\EventManager;
/**
* Регистрирует обработчик после сохранения товаров сделки.
*/
function registerAfterDealProductRowsSaveHandler(): void
{
EventManager::getInstance()->addEventHandlerCompatible(
'crm',
'OnAfterCrmDealProductRowsSave',
'handleAfterDealProductRowsSave'
);
}
/**
* Логирует сохранение товарных строк сделки.
*/
function handleAfterDealProductRowsSave(int $deal_id, array $product_rows): void
{
AddMessage2Log(
[
'message' => 'Товары сделки сохранены',
'deal_id' => $deal_id,
'product_rows' => $product_rows,
],
'deal_product_rows'
);
}
registerAfterDealProductRowsSaveHandler();