Создание обмена скидками между 1С УТ 10.3 и Битрикс CMS

«Главное мыслить системно»

Накидаем общий план. Нам надо передать «Скидку» из 1С в Битрикс. Это прям очень в общем. Но план хорош.

Я начал как мне кажется с начала и отправился в Админскую часть битрикса искать как же там делаются скидки.

Этого меню может не быть, тут дело в настройках битрикса. Но это гуглится.

Вбил тестовую скидку - работает, отображается как надо.

Разберемся как создать то же самое, но программно. Для этого у нас есть класс CCatalogDiscount.

Нужные нам методы это CCatalogDiscount::GetList для получения скидок, CCatalogDiscount::Update для обноления существующей скидки, CCatalogDiscount::Delete для удаления и CCatalogDiscount::Add для создания новой скидки.

В документации все очень подробно описанно, но все же приведу небольшой пример.


if( CModule::IncludeModule( "catalog" ) ) {
    $ID = 777; //ID товара
    $NAME = "Плюшка подушка"; //имя товара
    $SITE = "s1"; //id сайта
    $NEWPrice = 100; // цена со скидкой
    //Получим все скидки товара
    $arDiscounts = CCatalogDiscount::GetList(
        [ "SORT" => "ASC" ],
        [
            "+PRODUCT_ID" => (int)$ID,
            "SITE_ID"     => $SITE,
        ],
        FALSE,
        FALSE,
        [
            "ID", "ACTIVE",
        ]
    );
    $haveDiscounts = $arDiscounts->SelectedRowsCount() > 0;
    $arFields = [
        "SITE_ID"            => $SITE,
        "ACTIVE"             => "Y",
        "LAST_DISCOUNT"      => "Y",
        "NAME"               => $NAME,
        "COUPON"             => "",
        "SORT"               => "1",
        "CATALOG_GROUP_IDS " => [ 2 ],
        "VALUE_TYPE"         => "S", //тип скидки (P - в процентах, F - фиксированная величина, S - фиксированная цена);
        "VALUE"              => $NEWPrice,
        "CURRENCY"           => "RUB",
        "RENEWAL"            => "N",
        "CONDITIONS"         => [
            "CLASS_ID" => "CondGroup",
            "DATA"     => [
                "All"  => "AND",
                "True" => "True",
            ],
            "CHILDREN" => [
                [ "CLASS_ID" => "CondIBElement",
                  "DATA"     => [
                      "logic" => "Equal",
                      "value" => [ $ID ],
                  ],
                ],
            ],
        ],
    ];

    if( $haveDiscounts ) {
        //Скидки уже есть. Обновим только первую остальные удалим.
        $first = TRUE;
        while( $discount = $arDiscounts->Fetch() ) {
            if( $first ) {
                $first = FALSE;
                CCatalogDiscount::Update( (int)$discount["ID"], $arFields );
            } else {
                CCatalogDiscount::Delete( (int)$discount["ID"] );
            }
        }
    } else {
        //Скидок нет. Создадим новую
        $ID = CCatalogDiscount::Add( $arFields );
        $res = $ID > 0;
        if( !$res ) {
            $ex = $APPLICATION->GetException();
        }
    }
}

Теперь отлучимся ненадолго от Битрикса и быстренько допилим обмен на стороне 1С. Как — тут уже у каждого случай индивидуалный. В моем случае я добавил два доп рекивизита в 1С

Вернемся к сайту.

В языковой файл /bitrix/modules/iblock/lang/ru/classes/general/cml2.php добавим 


$MESS["IBLOCK_XML2_OLDPrice"] = "СтараяЦена";
$MESS["IBLOCK_XML2_NEWPrice"] = "НоваяЦена";
$MESS["IBLOCK_XML2_CreateDisc"] = "СоздатьСкидку";

Они нам понадобятся что бы при обходе доп. реквизитов найти нужные.

Теперь что касаемо обмена. Нас интересует класс CIBlockCMLImport в /bitrix/modules/iblock/classes/general/cml2.php.

Унаследуем его и переназначим функцую ImportElement

Тут нас интересует обход


 if( isset( $arXMLElement[$this->mess["IBLOCK_XML2_TRAITS_VALUES"]] ) ) {
   $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TRAITS"]] = [];
   foreach( $arXMLElement[$this->mess["IBLOCK_XML2_TRAITS_VALUES"]] as $value ) {

И ловим в цикле


if( $value[$this->mess["IBLOCK_XML2_NAME"]] == $this->mess["IBLOCK_XML2_OLDPrice"] ) {
    $OLDPrice = $value[$this->mess["IBLOCK_XML2_VALUE"]];
} elseif( $value[$this->mess["IBLOCK_XML2_NAME"]] == $this->mess["IBLOCK_XML2_NEWPrice"] ) {
    $NEWPrice = $value[$this->mess["IBLOCK_XML2_VALUE"]];
} elseif( $value[$this->mess["IBLOCK_XML2_NAME"]] == $this->mess["IBLOCK_XML2_CreateDisc"] ) {
    $CreateDisc = $value[$this->mess["IBLOCK_XML2_VALUE"]] === "true";
}

Наши доп. реквизиты

А далее все как в примере выше.