Телеграм: @camouf_ru Почта: mihail@bazarow.ru

Установить цену товара из свойства инфоблока

Установить цену товара из свойства инфоблока

На одном из проектов, нужно было единоразово заполнить цены товаров из свойства инфоблока. Сделать это можно через API, методами CPrice::Update и CPrice::Add

Реализация

Итак: имеем инфоблок, в котором, у каждого элемента заполнено свойство типа срока и называется "Минимальная цена" c кодом "ATT_PRICE". Нам нужно заполнить этим свойством, базовую цену. По сути, скопировать значение этого свойства в цену элемента.

Сначала идем в настройки инфоблока и помечаем инфоблок как "Торговый каталог"

Дальше, создаем в корне сайта файл addprice.php и добавляем внего код:


require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
Cmodule::IncludeModule('iblock');
Cmodule::IncludeModule('catalog');
$getProps = CIBlockElement::GetList (
Array("ID" => "ASC"),
Array("IBLOCK_ID" => 5), //Инфоблок с которым работаем
		false,
		false,
			Array(
			'ID', //Получили ID элемента
			'PROPERTY_ATT_PRICE' //Получили значение свойства с ценой
			)
);
while($ar_fields = $getProps->GetNext())
{
    $arFields = Array(
        "PRODUCT_ID" => $ar_fields['ID'], //ID типа цены, которую заполняем
        "CATALOG_GROUP_ID" => "1",
        "PRICE" => $ar_fields['PROPERTY_ATT_PRICE_VALUE'], //Заполнили цену свойством
        "CURRENCY" => "RUB", //Указали валюту
    );
    $res = CPrice::GetList(
        array(),
        array(
            "PRODUCT_ID" => $PRODUCT_ID,
            "CATALOG_GROUP_ID" => $PRICE_TYPE_ID
        )
    );
    if ($arr = $res->Fetch())
    {
        CPrice::Update($arFields); //Обновили цену
    }
    else
    {
        CPrice::Add($arFields); //Или добавили
    }

Открываем в браузере и ждем выполнения. Если нужно, для красоты, можно сделать пошаговое выполнение с отображением процесса- но это лишняя "свистоперделка".

Дополнительно:

Если нужно заполнить цену несколькими свойствами, например в зависимости от количества покупки, указать цену от-до. Можно модифицировать код, дополнив таким образом.


$arFields = Array(
    "PRODUCT_ID" => $ar_fields['ID'],
    "CATALOG_GROUP_ID" => $PRICE_TYPE_ID,
    "PRICE" => $ar_fields['PROPERTY_ATT_PRICE_VALUE'], //Заполнили цену свойством
    "CURRENCY" => "RUB",
    "QUANTITY_FROM" => 1, //От этого
    "QUANTITY_TO" => 10 //До этого количества
);

$res = CPrice::GetList(
        array(),
        array(
                "PRODUCT_ID" => $PRODUCT_ID,
                "CATALOG_GROUP_ID" => $PRICE_TYPE_ID
            )
    );

if ($arr = $res->Fetch())
{
    CPrice::Update($arr["ID"], $arFields);
}
else
{
    CPrice::Add($arFields);
}

Постоянное обновление цены из свойства. Cron задание.

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

Можно создать скрипт обновления и запускать его по cron. В директории /bitrix/php_interface/include/ создаем файл cron_price_refresher.php и добавляем в него:


$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/../../..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];

define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true);

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
@set_time_limit(0);

define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS", true);

Cmodule::IncludeModule('iblock');
Cmodule::IncludeModule('catalog');
$getProps = CIBlockElement::GetList (
Array("ID" => "ASC"),
Array("IBLOCK_ID" => 5),
        false,
        false,
            Array(
            'ID',
            'PROPERTY_ATT_PRICE'
            )
);
while($ar_fields = $getProps->GetNext())
{
    $arFields = Array(
        "PRODUCT_ID" => $ar_fields['ID'],
        "CATALOG_GROUP_ID" => "1",
        "PRICE" => $ar_fields['PROPERTY_ATT_PRICE_VALUE'],
        "CURRENCY" => "RUB",
    );
    $res = CPrice::GetList(
        array(),
        array(
            "PRODUCT_ID" => $PRODUCT_ID,
            "CATALOG_GROUP_ID" => $PRICE_TYPE_ID
        )
    );
    if ($arr = $res->Fetch())
    {
        CPrice::Update($arFields);
    }
    else
    {
        CPrice::Add($arFields);
    }
}

Здесь мы, подключили ядро битрикс, без шаблона и отключили статистику с проверкой прав. Делаем этот файл исполняемым chmod +x cron_price_refresher.php И добавляем в cron (в примере, каждое утро в 7 часов). /usr/bin/php72/bin/php -f - путь к интерпритатору php


0 7 * * * /usr/bin/php72/bin/php -f /sites/carrie-sex.shop/bitrix/php_interface/include/cron_price_refresher.php

PS: Понятное дело, можно добавить обработчик в init.php - но это не всегда подходит. Обновление цен с параллельной загрузкой каталога- ресурсоемкая процедура. На больших каталогах, потребуется либо мощный, дорогой сервер. Либо сэкономить на нем, способом выше!

Сергей Петрухин03.08.2019
Вместо
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");

пишем
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

И наслаждаемся
Михаил Базаров03.08.2019
Цитата
Сергей Петрухин написал:
Вместо
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");

пишем
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

И наслаждаемся
Да, если не нужно отображение шаблона- можно и так. Или для cron задания
Guest01.11.2021
А если в обратном порядке, базовую цену поместить в свойство.
Михаил Базаров01.11.2021
Цитата
Guest написал:
А если в обратном порядке, базовую цену поместить в свойство.
С помощью метода CPrice::GetByID получить цену товара
С помощью CIBlockElement::Update и CIBlockElement::SetPropertyValues установить значение нужному свойству

Случайные заметки

Основные функции вывода в шаблонах Битрикс

Просмотров: 149677 Комментариев: 70
Знаю, что все их знают. Но иногда не бывает лишним собрать все самое используемое в одну кучку. Ведь у каждого бывают моменты тупости, когда забываетс...