понедельник, 22 апреля 2013 г.

Импорт скидок номенклатуры из 1С Предприятия в 1С Битрикс

Начну с цитаты

...если документом "Установка скидок номенклатуры" определены скидки на товары в зависимости от их количества в заказе, то данная информация поступит на сайт и скидка будет применяться и при продаже в Интернет-магазине.
Кроме этого, модуль на стороне 1С выгружает в CommerceML и другие типы скидок, но их автоматический импорт в 1С-Битрикс предлагается реализовать разработчикам интернет-магазина, поскольку их применение очень сильно зависит от особенностей ценообразования для каждого конкретного случая.

Цитата от сюда: https://1c.1c-bitrix.ru/ecommerce/v2.php

Вот об опыте импорта тех самых "других" типов скидок я и хочу рассказать в данной статье. В частности, об импорте скидок, которые применяются к определенному товару вне зависимости от каких-либо условий. (В сезон распродажи или на залежалый товар/размер).

Данную задачу мы (я и мой помощник Вадим Соловьев) решали для того же самого проекта, для которого я незадолго до этого подогнала импорт под готовую структуру инфоблоков (см. статью Как подогнать стандартный импорт из 1С под готовое решение из маркетплейс Битрикс). В этом проекте у нас уже был унаследован класс CIBlockCMLImport, был кастомизирован компонент catalog.import.1c для работы именно с этим классом.

class CIBlockCMLCustomImport extends CIBlockCMLImport{}

и была перегружена функция ImportElement

Этот же перегруженный метод  ImportElement мы и дополнили функционалом для импорта из 1С безусловных скидок на товар.

Информация о скидках приходила к нам из 1С Предприятия в следующем виде:
<СкидкиНаценки>
     <СкидкаНаценка>
      <Условие>Количество одного товара в документе превысило</Условие>
      <Процент>20</Процент>
      <Валюта>руб</Валюта>
      <Получатель>8a21ac94-2ac6-11e0-8e8a-00265abc1d64</Получатель>
     </СкидкаНаценка>
...
</СкидкиНаценки>
И торговые предложения, у которых в секции  СкидкиНаценки присутствовала скидка указанного вида нам нужно было интерпретировать как торговые предложения, на которые действует безусловная процентная скидка.

Думая о том, как организовать хранение этих скидок в Битрикс, я хотела дописывать торговые предложения, на которые действует скидка в условия для существующих в системе процентных скидок (желтая стрелочка на рисунке). Вадим предложил заводить отдельную скидку для каждого торгового предложения (зеленая стрелочка на рисунке). И я отдала предпочтение решению Вадима, так как оно предполагает меньшее количество запросов к БД при импорте ссылок (особенно в случаях когда в 1С удалена скидка на товар, к-я ранее была импортирована на сайт и которую нужно удалить и на сайте в процессе импорта), хотя результат и не так красиво смотрится в админке.

Итак, в нашем перегруженном методе ImportElement мы дописали следующее:

В самом начале метода мы смотрим, есть ли для указанного элемента безусловная процентная скидка. Если есть, пишем ее в переменную $discount_perc. Если нет - эта переменная остается равной 0.

$discount_perc = 0.0;
if(isset($arXMLElement[GetMessage("IBLOCK_XML2_DISCOUNTS")]))
{
    foreach($arXMLElement[GetMessage("IBLOCK_XML2_DISCOUNTS")] as $key=>$discount)
    {
        if(
            isset($discount[GetMessage("IBLOCK_XML2_DISCOUNT_CONDITION")])
            && $discount[GetMessage("IBLOCK_XML2_DISCOUNT_CONDITION")]===GetMessage("IBLOCK_XML2_DISCOUNT_COND_VOLUME")
        )
        {
            $discount_perc = $this->ToFloat($discount[GetMessage("IBLOCK_XML2_DISCOUNT_COND_PERCENT")]);
        }
    }
}
Далее, ниже секции, в которой в стандартном методе ImportElement определяются скидки на товары в зависимости от  их количества в заказе, мы вставили код, создающи/обновляющий/удаляющий наши безусловные процентные скидки. В этом коде мы пошли на небольшую хитрость и ставим каждой новой скидке ID равный ID элемента, для которого данная скидка была создана.

$discount_id = intval($arElement["ID"]);
$arDiscount = array();
$arDiscount = CCatalogDiscount::GetByID($discount_id);
if ($discount_perc == 0.0)
{
    if($arDiscount) CCatalogDiscount::Delete($discount_id);
}
else
{
    if($arDiscount)
    {
        if($arDiscount["VALUE"] != $discount_perc)
        {
            $arDiscount["VALUE"] = $discount_perc;
            CCatalogDiscount::Update($discount_id, $arDiscount);
        }
    }
    else
    {
       
        if ($discount_perc>0){
        $arLogic = array (
            "CLASS_ID" => "CondGroup",
            "DATA" => array (
                "All" => "OR",
                "True" => "True",
                ),
            "CHILDREN" => array (
                "0" => array (
                    "CLASS_ID" => "CondIBElement",
                    "DATA" => array (
                        "logic" => "Equal",
                        "value" => $discount_id,
                        ),
                ),
            ),
        );

        $arDiscount = array (
            "ID" => $discount_id,
            "SITE_ID" => "s1",
            "ACTIVE" => "Y",
            "NAME" => strval($discount_id),
            "MAX_USES" => 0,
            "COUNT_USES" => 0,
            "COUPON" => "",
            "SORT" => 100,
            "MAX_DISCOUNT" => 0.0000,
            "VALUE_TYPE" => "P",
            "VALUE" => $discount_perc,
            "CURRENCY" => "RUB",
            "MIN_ORDER_SUM" => 0.0000,
            "NOTES" => "",
            "RENEWAL" => "N",
            "ACTIVE_FROM" => "",
            "ACTIVE_TO" => "",
            "PRIORITY" => 1,
            "LAST_DISCOUNT" => "Y",
            "CONDITIONS" => serialize($arLogic),
        );
       
        CCatalogDiscount::Add($arDiscount);
       
        }
    }
}
И безусловные скидки на товары были успешно импортированы из 1С Предприятия в Битрикс.
Решение не претендует на идеальность, но оно имеет место быть, успешно внедрено и не перегружает достаточно стандартную виртуальную хостинговую площадку.

1 комментарий:

Ruslan Rylov комментирует...
Этот комментарий был удален автором.