Для начала: в настройках магазина, создаем новый тип цены "Наценка для всех" и выставляем права на просмотр и покупку нужной группе пользователей (в моем случае для всех). Также, запрещаем всем пользователям просмотр и покупку по Базовой цене
Здесь же, в настройках магазина, создаем наценку: называем как удобно и выставляем процент наценки.
Запоминаем:
- ID типа цены, на которую нужно установить наценку: в моем случае 4
- ID наценки, которую нужно применить к этому типу цен: у меня 1
- ID инфоблока с которым работаем: у меня 5-ый
Применяем наценку методом CPrice::Update
Дальше все просто: нам нужно перебрать все товары каталога методом CIBlockElement::GetList и методом CPrice::Update обновить параметры нужного типа цен.
Запускаем выполнение вот этого кода:
Обратите внимание, в методе CIBlockElement::GetList используем Fetch, вместо GetNext - так как нужны только ID элементов (товаров). Fetch - отрабатывает быстрее.
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
Cmodule::IncludeModule('iblock');
Cmodule::IncludeModule('catalog');
$IBLOCK_ID = 5; // Инфоблок
$EXTRA_ID = "1"; // Наценка
$PRICE_ID = "4"; // Тип цены
$getElementId = CIBlockElement::GetList(
Array("ID" => "ASC"),
Array("IBLOCK_ID" => $IBLOCK_ID),
false, false,
Array('ID')
);
while ($arID = $getElementId->Fetch()) {
$arFields = Array(
"PRODUCT_ID" => $arID['ID'],
"CATALOG_GROUP_ID" => $PRICE_ID,
"EXTRA_ID" => $EXTRA_ID,
"CURRENCY" => "RUB",
);
$res = CPrice::GetList(
array(),
array(
"PRODUCT_ID" => $arID['ID'],
"CATALOG_GROUP_ID" => $PRICE_ID
)
);
if ($arr = $res->Fetch()) {
CPrice::Update($arr["ID"], $arFields);
} else {
CPrice::Add($arr["ID"], $arFields);
}
}
И проверяем результат, зайдя в любой товар. Должна установиться наценка на выбранный тип цены и расчитаться сама цена на основе базовой. При изменении цены товара, автоматически пересчитывается наша цена.
Если потребуется изменить величину наценки. Просто заходите в ее (наценки) настройки, меняете величину и ставите чекбокс на Пересчитать цены. Автоматически перезапишутся цены, с этой наценкой.
Таким образом, можно устанавливать наценки для разных типов цен. например: для разных групп пользователей или разных сайтов в системе.
Если нужно устанавливать наценку для новых товаров, которых не было до запуска скрипта, можно сделать обработчик в init.php срабатывающий на событие добавление элемента OnAfterIBlockElementAdd
Сделать наценку с помощью D7
Вариант кода с использованием более современного подхода, с использованием D7/ORM:
use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;
use Bitrix\Catalog\PriceTable;
Loader::includeModule('iblock');
Loader::includeModule('catalog');
$IBLOCK_ID = 11; // Инфоблок
$EXTRA_ID = 1; // Наценка
$PRICE_ID = 6; // Тип цены
$elements = ElementTable::getList([
'select' => ['ID'],
'filter' => ['IBLOCK_ID' => $IBLOCK_ID],
])->fetchAll();
foreach ($elements as $element) {
echo '';
print_r($element);
echo '';
$arFields = [
"PRODUCT_ID" => $element['ID'],
"CATALOG_GROUP_ID" => $PRICE_ID,
"EXTRA_ID" => $EXTRA_ID,
"CURRENCY" => "RUB",
];
// Проверяем наличие цены
$price = PriceTable::getList([
'filter' => [
"PRODUCT_ID" => $element['ID'],
"CATALOG_GROUP_ID" => $PRICE_ID
]
])->fetch();
if ($price) {
// Обновляем цену
PriceTable::update($price["ID"], $arFields);
} else {
// Добавляем новую цену
PriceTable::add($arFields);
}
}
Этот код более современный и соответствует стандартам D7, обеспечивая лучшую производительность и поддержку в будущем.