Пустые <ид> и <идкаталог> при обмене заказами, созданными через D7 API Bitrix

Предыстория

Создаю по примеру заказ через API

Код
if ($item = $basket->getExistsItem('catalog', $productId) {
    $item->setField('QUANTITY', $item->getQuantity() + $quantity);
}
else {
    $item = $basket->createItem('catalog', $productId);
    $item->setFields(array(
        'QUANTITY' => $quantity,
        'CURRENCY' => Bitrix\Currency\CurrencyManager::getBaseCurrency(),
        'LID' => Bitrix\Main\Context::getCurrent()->getSite(),
        'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProvider',
    ));
}
$basket->save();

Все создается, но далее при обмене с 1С получается блеберда.
Оказывается, что в обмене у товара нет ИД

Код
<Товары>         <Товар>
            <Ид></Ид>
            <ИдКаталога></ИдКаталога>
            <Наименование>(100/80W) 12V Лампа OFFROAD 1шт. в картонной коробке, арт. 64203 OSRAM</Наименование>
            .....

Но, если в админке тыкнуть на изменить заказ и ничего не меняя сохранить его, то имеем:

Код
<Товары>         <Товар>
            <Ид>321427</Ид>
            <ИдКаталога>3bec4b0f-e741-4970-a49b-c5934c940d36</ИдКаталога>
            <Наименование>(100/80W) 12V Лампа OFFROAD 1шт. в картонной коробке, арт. 64203 OSRAM</Наименование>

и в 1С полный порядок.

По делу.

Если честно, то все не так было.

Есть мой любимый RetailCRM, где можно создать заказ, который передастся в bitrix, но при обмене с 1С вместо товара будет что-то не ясное. У меня это одна из  папок каталога была.

А очень уж хотелось, чтобы наши менеджеры работали ТОЛЬКО в RetailCRM, а в 1С только отгрузки и приходы товара фиксировались. Но, если клиент что-то хотел изменить в заказе, то нужно было его менять или в Битриксе или в 1С. Господа из ретейла, ознакомившись с ситуацией, сказали, что смогут предложить решение этого вопроса на возмездной основе, т.к. в ближайших планах этого нет, а дел и так хватает. Тогда я решил, что я Ж программист! И начал копать их модуль обмена.

Изучив несколько строк функций и крайне скудное описание API D7 (т.к. большую часть свойств и полей пришлось вылавливать через var_dump();), пришел к выводу, что ретейлеры ничем не виноваты, а оказывается, что в битриксе (нафига не ясно) если положить товар к корзину программно, то в корзину не кладуться его … да ничего его. Ни название, ни свойства. Все нужно класть ручками. Даже XML_ID, о котором и знать-то нам вредно, т.к. он УНИКАЛЕН и является ТОЛЬКО ОДНИМ возможным у товара, надо класть самому.

И тогда, обычный код

$item = $basket->createItem('catalog', $product['offer']['externalId']);
if ($item instanceof \Bitrix\Sale\BasketItem) {
    $elem = self::getInfoElement($product['offer']['externalId']);
    $item->setFields(array(
        'CURRENCY' => \Bitrix\Currency\CurrencyManager::getBaseCurrency(),
        'LID' => $site,
        'BASE_PRICE' => $product['initialPrice'],
        'NAME' => $product['name'] ? RCrmActions::fromJSON($product['name']) : $elem['NAME'],
        'DETAIL_PAGE_URL' => $elem['URL'],    
    ));
}

пришлось модернизировать в

$item = $basket->createItem('catalog', $product['offer']['externalId']);
if ($item instanceof \Bitrix\Sale\BasketItem) {
    $elem = self::getInfoElement($product['offer']['externalId']);
    $item->setFields(array(
        'CURRENCY' => \Bitrix\Currency\CurrencyManager::getBaseCurrency(),
        'LID' => $site,
        'BASE_PRICE' => $product['initialPrice'],
        'NAME' => $product['name'] ? RCrmActions::fromJSON($product['name']) : $elem['NAME'],
        'DETAIL_PAGE_URL' => $elem['URL'],
        'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProvider',
        'CATALOG_XML_ID' => $elem['CATALOG_XML_ID'],
        'PRODUCT_XML_ID' => $elem['EXTERNAL_ID'],
    ));
}

а функцию getInfoElement()

к виду

public static function getInfoElement($offerId)
{
    $elementInfo = CIBlockElement::GetByID($offerId)->fetch();
    $url = CAllIBlock::ReplaceDetailUrl($elementInfo['DETAIL_PAGE_URL'], $elementInfo, false, 'E');
    $info = array(
        'NAME' => $elementInfo['NAME'],
        'URL' => $url,
        'CATALOG_XML_ID' => $elementInfo['IBLOCK_EXTERNAL_ID'],
        'EXTERNAL_ID' => $elementInfo['EXTERNAL_ID'],
    );

    return $info;
}

Теперь моя радость не знает границ!

<Товар>
 <Ид>6022c0cc-4803-11e6-8000-20cf300b3885</Ид>
 <ИдКаталога>24a9808b-01c2-4f8d-8e87-3390ae2c7aea</ИдКаталога>
 <Наименование>ALPINE CDE 178 BT/автомагнитола 1 din,mp3,USB,BT,iPod,многоцвет. подсв. кнопок/</Наименование>

Один комментарий к “Пустые <ид> и <идкаталог> при обмене заказами, созданными через D7 API Bitrix”

  1. Спасибо, очень помогло!
    Столкнулись с той же проблемой при использовании D7 и ручном формировании заказов
    Опирался на https://mrcappuccino.ru/blog/post/work-with-order-bitrix-d7 и подобные инструкции, где не сказано, что нужно заполнять поля внешних идентификаторов.
    В документации к функции старого API CSaleBasket::Add
    https://dev.1c-bitrix.ru/api_help/sale/classes/csalebasket/csalebasket__add.php
    указано:
    PRODUCT_XML_ID — внешний код товара (необходим при обмене заказами с 1С);
    CATALOG_XML_ID — внешний код каталога (необходим при обмене заказами с 1С);

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *