Разные цены для складов в многоскладовости. Доработка 1С-Битрикс

    Были интернет-магазин и b2b платформа у одной компании на системе 1с-Битрикс. Компания росла и появились свои склады и добавились еще склады партнеров которые нужно было отображать. Возникла необходимость отображения остатков по нескольким складам.

    И что нам говорит Битрикс: Пожалуйста переходите на редакцию «Бизнес» и будет всё замечательно и сразу. На редакцию перешли и оказалось, что многоценновость и многоскладовость в 1С-Битрикс живут отдельной жизнью. Первая нужна для отображения разных цен для разных групп пользователей, а второе для отображения остатков на разных складах.

    Нам нужно было выводить остатки со своей ценой по каждому складу, так как цена у партнеров и у нас может отличаться на одну и ту же позицию. Штатного такого функционала оказалось, что нет.

    Тут и пришла в голову идея переделать стандартные шаблоны и на стороне сайта сделать связку склад-цена.

    Первое что пришлось сделать это переделать шаблоны catalog.section и catalog.element. В них был вставлен компонент catalog.store.amount:

    1. Для карточки товара был выведен список складов с ценами

    Фрагмент кода
    if ($arResult['CATALOG_QUANTITY']!=0){ //не отображать если не на одном складе нет остатков
          $APPLICATION->IncludeComponent("bitrix:catalog.store.amount","finnit_buy",
              array("ELEMENT_ID"  => $arResult["ID"] //фильтрация по ID элемента


    2. Для списка товаров через компонент сделана выборка всего одной цены (или самая низкая цена или минимальный срок доставки).

    Фрагмент кода
    $APPLICATION->IncludeComponent( "bitrix:catalog.store.amount", "finnit_1sk",
    	 array( "ELEMENT_ID"   => $arElement["ID"]//фильтрация по ID элемента


    Так для каждого вида был создан свой шаблон, по мимо этого было создано еще несколько шаблонов. К примеру шаблон для быстрой покупки в котором выводится оптимальный склад с ценой для совершения покупки.

    Работы по компоненту catalog.store.amount шли в 3 этапа.

    1. Ручное сопоставление в коде склад — цена (удобно при малом количестве складов). В данном случае в коде пишется указание типа цены для определенного склада.

    Фрагмент кода
    if ($arProperty['ID'] == 29){// Идентификатор склада
                            $db_res = CPrice::GetList( array(),  array("PRODUCT_ID" => $arParams['ELEMENT_ID'],"CATALOG_GROUP_ID" => '28')); // 28 - это идентификатор необходимого типа цены
                            if ($ar_res = $db_res->Fetch()){
                                if($min_price > (ceil(($ar_res["PRICE"] + ($ar_res["PRICE"]/100))/10)* 10))
                                    $min_price = ceil(($ar_res["PRICE"] + ($ar_res["PRICE"]/100))/10)* 10; // получаем минимальную цену по всем складам по данному товару и округляем
                                $amount = $arProperty["AMOUNT"]; // получаем количество по складу
                                $title = $arProperty["ID"]; // изначально передалось Наименование в переменную, но при смене наименования в 1С при обмене склад переименовывался и на сайте - по этому привязку сделали по ID, а название переменной не трогали.
                            }


    2. После того как стали подключаться еще склады первый вариант оказался непригодным и было принято решение вести связки склад- цена в отдельном инфоблоке.

    скриншот


    Фрагмент кода
    <?// запрос инфоблока со списком сопоставления
                                    $arSelectEquals = Array("ID", "IBLOCK_ID");
                                    $arFilterEquals = Array("IBLOCK_ID"=>18); //ID инфоблока сопоставления
                                    $equals = CIBlockElement::GetList(Array(), $arFilterEquals, false, Array(), $arSelectEquals);
                                    while($equal = $equals->GetNextElement()){
                                        $arPropsEquals = $equal->GetProperties();
                                        if ($arProperty["ID"] == $arPropsEquals["SKLAD_ID"]["VALUE"]){// если склад сопоставлен
                                            $db_res = CPrice::GetList(
                                                array(),  array("PRODUCT_ID" => $arParams['ELEMENT_ID'],"CATALOG_GROUP_ID" => $arPropsEquals["PRICE_ID"]["VALUE"]));
                                            if ($ar_res = $db_res->Fetch()){
                                                if (!isset($ar_res["PRICE"])){
                                                    echo GetMessage('FINN_PRICE_MANAGER');//вывод сообщения если нет цены
                                                }else{ // если цена есть по сопоставленным данным
                                                        $pricen = ceil( $ar_res["PRICE"] );// получение данных для дальнейшего заказа
                                                        $price_id = $ar_res["CATALOG_GROUP_ID"];// получение данных для дальнейшего заказа
                                                        $price_name = $ar_res["CATALOG_GROUP_NAME"];// получение данных для дальнейшего заказа
                                                    }
                                                    //echo number_format( $pricen, 0, ',', ' ' );
                                                    $torgId  = $ar_res["ID"]; // получение данных для дальнейшего заказа
                                                    $torgGId = $ar_res["CATALOG_GROUP_ID"];// получение данных для дальнейшего заказа
                                                }
                                            } else{}}
                                    }
                                    ?>


    Таким образом уже можно вести достаточно большой объем складов.

    3. Использование пользовательских полей непосредственно в складах для сопоставления с типами цен.

    Этот вариант изначально не рассматривался. И только после того как открылся магазин по мимо Челябинска еще и в Санкт-Петербурге понадобилось указывать срок поставки товара в зависимости от склада, для этих целей как раз и использовали пользовательские поля в складах.

    Скриншот


    Считаю данный вариант самый оптимальный. И на данный момент уже несколько шаблонов переведены на этот же вариант сопоставления складов и цен.

    P.S. Если Вы знаете более подходящий вариант — пишите в комментариях, буду благодарен.

    P.P.S. Если есть замечания или вопросы пишите — отвечу.
    • –9
    • 1,6k
    • 3
    Поделиться публикацией

    Комментарии 3

      +1
      Раз уж Вы просили замечания и комментарии, то у меня есть несколько.
      1. Фрагменты кода оформлены ужасно. Операции по условиям обрываются. Отступы нечитаемые. Особенно третий.
      2. Много ошибок в тексте: «если не на одном складе нет остатков», «Штатного такого функционала оказалось, что нет.», «после того как открылся магазин по мимо Челябинска», пунктуация.
      3. Скриншот с суперсекретными замазанными названиями складов/городов, и это при условии, что Вы все равно засветили адрес сайта. А в следующем скриншоте Вы их всё-таки не замазали.
      4. Слишком узкое повествование. Перечисление кодов компонентов без их названий только добавляет путаницы. Тот, кто с Битриксом не работает, вообще читать после этого перестанет.

      Я знаком с Битриксом, но и для меня статья в текущем виде имеет спорную ценность.
      Спасибо, что поделились своим опытом, возможно, Вам удастся реабилитировать Вашу статью. Я оценок статье не ставил, но все-таки думаю, что её бы лучше приняли на более узком Битрикс-ресурсе.
        0
        Спасибо за комментарий, обязательно учту. Попытаюсь или дополнить и исправить данную статью или в дальнейшем буду делать аккуратнее.
        1. Фрагмент кода был скопирован из Php Storm — не подправил отступы, для удобства пользователей Хабр.
        2. Получилось так, что русский в школе практически не учил. Так как выходец из одной из бывших республик СССР. Сейчас подтягиваю знания, в том числе и через критику. Спасибо.
        3. Замазаны были названия складов в которых указывалось название или аббревиатуры организаций, а города не являются секретом.
        4. Попытаюсь изложить более развернуто.
        0

        Прям пособие, как не надо делать сторонний функционал

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое