Найти в Дзене

Простейшая интеграция Битрикс-интернет-магазина и 1С

Одним из важных навыков специалиста по внедрению, сопровождению и доработке информационных систем в том числе в веб-среде является интеграция сопровождаемой и внешней системы. Естественно не всегда стандартными способами. Однажды мне поступил заказ на синхронизацию остатков и цен между интернет-магазином и 1С, где источником информация была 1С 8.3. Естественно, мы знаем, что существуют стандартные интеграции - в 1С есть модуль, Битрикс предлагает свой модуль. Это все понятно, но были причины, по которым они не подошли. Если вкратце, то клиент часть информации хранил в 1С (остатки), часть в интернет-магазине (описания, фото, некоторые свойства). При стандартном обмене информация в интернет-магазине затиралась, потому что ее не было в xml-файле. Было принято решение написать свой обмен, состоящий из двух частей. Со стороны 1С выгрузка каталога и вызов скрипта на сервере. Причем нам понадобилось только название товара для визуального человеческого контроля, артикул товара, по которому про

Одним из важных навыков специалиста по внедрению, сопровождению и доработке информационных систем в том числе в веб-среде является интеграция сопровождаемой и внешней системы. Естественно не всегда стандартными способами.

Однажды мне поступил заказ на синхронизацию остатков и цен между интернет-магазином и 1С, где источником информация была 1С 8.3.

Естественно, мы знаем, что существуют стандартные интеграции - в 1С есть модуль, Битрикс предлагает свой модуль. Это все понятно, но были причины, по которым они не подошли.

Если вкратце, то клиент часть информации хранил в 1С (остатки), часть в интернет-магазине (описания, фото, некоторые свойства). При стандартном обмене информация в интернет-магазине затиралась, потому что ее не было в xml-файле.

Было принято решение написать свой обмен, состоящий из двух частей. Со стороны 1С выгрузка каталога и вызов скрипта на сервере. Причем нам понадобилось только название товара для визуального человеческого контроля, артикул товара, по которому производилась идентификация товара, цена и остаток товара.

Для обмена нам необходимо передавать xml-файл с этими полями в теле POST-запроса. Также необходимо каким-либо образом передать логин и пароль пользователя Битрикса с правами на редактирования каталога для его авторизации. Это можно сделать в заголовках запроса или в этом же xml-файле.

Приведу фрагменты серверного скрипта, может быть кому-то будет полезно.

Получим файл с потока ввода:

$str=file_get_contents("php://input");

Обращу внимание, что в массивах $_POST или $_FILES скорее всего ничего не будет.

Полученный XML выглядит примерно так

<?xml version="1.0" encoding="UTF-8"?>
<Товары>
<Товар>
<Наименование>Кофе растворимый</Наименование>
<Артикул>25020</Артикул>
<Остаток>0</Остаток>
<Цена>920</Цена>
</Товар>
</Товары>

Воспользуемся библиотекой SimpleXML

$xml=simplexml_load_string($str);

Обойдем в цикле каждый товар

foreach ($xml->Товар as $item)
{
//тело цикло
}

Приведу тело цикла

Выделим элементы XML

$art=trim((string)$item->Артикул);
$name=trim((string)$item->Наименование);
$count=trim((string)$item->Остаток);
$price=trim((string)$item->Цена);

Будем искать товары в базе Битрикса по артикулу или по наименованию. При отсутствии того и другого перейдем к обработке следующего узла

if ($art!="") $filter=array("IBLOCK_ID"=>$iblock,"PROPERTY_ARTNUMBER"=>$art); elseif ($name!="") $filter=array("IBLOCK_ID"=>$iblock,"NAME"=>$name); else continue;

Обратимся к API для поиска товара по фильтру

$res=CIBlockElement::GetList(array(),$filter,false,false,array("ID","IBLOCK_ID","QUANTITY"));
if ($arItem=$res->GetNext())
{
//обработка элемента
}

В обработке элемента используем следующий код

получим ID товара

$id=$arItem["ID"];

- для добавления количества без складского учета старым API

$amountField=array("ID"=>$id,"QUANTITY"=>$count);
CCatalogProduct::Add($amountField);

- для добавления количества без складского учета с использованием D7

\Bitrix\Catalog\ProductTable::update($id, array('QUANTITY'=>$count, 'AVAILABLE'=>\Bitrix\Catalog\ProductTable::calculateAvailable($product),));

- если есть складской учет, все чуть сложнее

найдем ID записи, которую необходимо изменить. $store - id склада

$arFilterStore = Array("PRODUCT_ID"=>$id,"STORE_ID"=>$store);
$rsStoreAmount = CCatalogStoreProduct::GetList(Array(),$arFilterStore);
if($arStoreAmount = $rsStoreAmount->Fetch())
{
$sid=$arStoreAmount["ID"];
// можем внести изменения
$amountField=array("PRODUCT_ID"=>$id,"STORE_ID"=>$store,"AMOUNT"=>$count);
$r=CCatalogStoreProduct::Update($sid,$amountField);
}
//если запись не нашли
else
{
$r=CCatalogStoreProduct::Add($amountField);
}

Установим цену

CPrice::SetBasePrice($id,$price,$currency);

Конец обработки элемента

Пишите в комментариях, если будут вопросы