Настройка массового обновления цен 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка массового обновления цен 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    745
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка массового обновления цен 1С-Битрикс

Поставщик прислал прайс с новыми закупочными ценами — 3000 позиций. Розничная наценка 40%. Нужно обновить розничные цены к утру. Вручную — нереально. Импорт через 1С — не всегда есть связка. Прямое обновление через API Битрикса — решение за несколько часов настройки.

Таблица цен и типы цен

Цены хранятся в b_catalog_price. Ключевые поля: PRODUCT_ID, CATALOG_GROUP_ID (тип цены), PRICE, CURRENCY, QUANTITY_FROM, QUANTITY_TO (для ценовых диапазонов).

Типы цен — b_catalog_group: BASE — базовая, остальные — дополнительные (розничная, оптовая, закупочная). CATALOG_GROUP_ID = 1 обычно — базовая цена, но это зависит от конкретной установки.

Получить ID типа цены по названию:

$priceType = \Bitrix\Catalog\GroupTable::getList([
    'filter' => ['NAME' => 'Розничная'],
    'select' => ['ID'],
])->fetch();
$priceTypeId = $priceType['ID'];

Массовое обновление через D7

Обновление цены одного товара:

// Проверить, существует ли цена
$existing = \Bitrix\Catalog\PriceTable::getList([
    'filter' => ['PRODUCT_ID' => $productId, 'CATALOG_GROUP_ID' => $priceTypeId],
    'select' => ['ID'],
])->fetch();

if ($existing) {
    \Bitrix\Catalog\PriceTable::update($existing['ID'], [
        'PRICE'    => $newPrice,
        'CURRENCY' => 'BYN',
    ]);
} else {
    \Bitrix\Catalog\PriceTable::add([
        'PRODUCT_ID'       => $productId,
        'CATALOG_GROUP_ID' => $priceTypeId,
        'PRICE'            => $newPrice,
        'CURRENCY'         => 'BYN',
    ]);
}

Для массового обновления — цикл с батчингом. При 3000 позиций рекомендуется батч по 100 с паузой 50ms, чтобы не создавать пиков нагрузки на MySQL.

Расчёт цены по наценке

При загрузке закупочных цен розничная рассчитывается автоматически:

function calcRetailPrice(float $purchasePrice, float $markup): float {
    return round($purchasePrice * (1 + $markup / 100), 2);
}

foreach ($newPrices as $item) {
    $retail = calcRetailPrice($item['purchase_price'], 40.0);

    updatePrice($item['product_id'], RETAIL_PRICE_TYPE_ID, $retail);
    updatePrice($item['product_id'], PURCHASE_PRICE_TYPE_ID, $item['purchase_price']);
}

Загрузка из Excel/CSV

Прайс от поставщика чаще всего приходит в Excel или CSV. Для парсинга Excel используется PhpSpreadsheet:

$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('/path/to/price.xlsx');
$sheet = $spreadsheet->getActiveSheet();

foreach ($sheet->getRowIterator(2) as $row) { // со второй строки (пропускаем заголовок)
    $cells = $row->getCellIterator();
    $cells->setIterateOnlyExistingCells(false);

    $rowData = [];
    foreach ($cells as $cell) {
        $rowData[] = $cell->getValue();
    }

    $articul     = $rowData[0]; // A: артикул
    $newPurchase = (float)$rowData[3]; // D: закупочная цена

    // Найти товар по артикулу
    $productId = findProductByArticul($articul);
    if ($productId) {
        updatePrice($productId, PURCHASE_PRICE_TYPE_ID, $newPurchase);
        updatePrice($productId, RETAIL_PRICE_TYPE_ID, calcRetailPrice($newPurchase, 40.0));
    }
}

Инвалидация кэша после обновления

После массового обновления цен страницы каталога показывают старые цены из кэша. Сброс кэша для всего каталога:

// Удалить кэш компонентов каталога
\Bitrix\Main\Application::getInstance()->getTaggedCache()->clearByTag('catalog');

// Или сброс по инфоблоку
\Bitrix\Main\Application::getInstance()->getTaggedCache()->clearByTag('iblock_id_' . $iblockId);

Альтернатива — не сбрасывать кэш массово, а дождаться естественного устаревания (TTL). Но если цены изменились на акционные с конкретным сроком, дожидаться нельзя — сброс обязателен.

Лог изменений цен

Для аудита рекомендуется перед обновлением сохранять старые цены в кастомную таблицу catalog_price_history с полями (product_id, price_type_id, old_price, new_price, changed_by, changed_at). Это позволяет откатить ошибочное обновление и анализировать динамику цен.