← Назад к справке

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();

Источники