На одном из проектов, нужно было единоразово заполнить цены товаров из свойства инфоблока. Сделать это можно через 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 - но это не всегда подходит. Обновление цен с параллельной загрузкой каталога- ресурсоемкая процедура. На больших каталогах, потребуется либо мощный, дорогой сервер. Либо сэкономить на нем, способом выше!

require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
пишем
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
И наслаждаемся

Цитата |
---|
Сергей Петрухин написал: Вместо require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php"); пишем require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); И наслаждаемся |

Цитата |
---|
Guest написал: А если в обратном порядке, базовую цену поместить в свойство. |
С помощью CIBlockElement::Update и CIBlockElement::SetPropertyValues установить значение нужному свойству
Подскажите, на сайте товар уже заполнен проставлены цены и есть товар новый, который только залился, тут цена в собственном поле хранится. Когда пытаюсь воспользоваться вашим примером цена из свойства кастомного записывается в поле с Ценой, но начинают создаваться дубли товара, во всем каталоге.