Разработка кастомной PIM-системы для 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка кастомной PIM-системы для 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • 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С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка кастомной PIM-системы для 1С-Битрикс

Коммерческие PIM-системы (Akeneo, Pimcore, Salsify) решают задачу управления контентом, но создают зависимость от стороннего продукта и добавляют сложность в архитектуру. Кастомная PIM на базе Битрикс — это когда Битрикс сам становится мастер-системой для продуктовых данных: с кастомным административным интерфейсом, логикой валидации атрибутов и возможностью синдикации на несколько каналов.

Когда нужна кастомная PIM

Кастомная PIM оправдана, когда:

  • Команда работает только в экосистеме Битрикс и не хочет учить новую систему
  • Бюджет не позволяет лицензию Akeneo Enterprise ($25 000+/год)
  • Требования специфичны настолько, что готовая PIM всё равно требует обширной кастомизации
  • Каталог до 50 000–100 000 SKU (для большего объёма стоит рассмотреть специализированный PIM)

Архитектура данных

Стандартный инфоблок Битрикс хранит свойства в b_iblock_element_property по модели EAV. При большом количестве атрибутов (50+) и высоком трафике это создаёт проблемы производительности. Для кастомной PIM используем гибридный подход:

Фиксированные атрибуты (название, описание, изображения) — в полях инфоблока и свойствах с MULTIPLE = 'N'.

Динамические атрибуты (специфичные для категории: для телефонов — RAM/ROM, для одежды — состав ткани) — в кастомных таблицах:

CREATE TABLE b_pim_attribute (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    IBLOCK_SECTION_ID INT,          -- к какой категории привязан атрибут
    CODE VARCHAR(100) NOT NULL,
    NAME VARCHAR(255) NOT NULL,
    TYPE ENUM('string','number','boolean','list','multilist') DEFAULT 'string',
    IS_REQUIRED TINYINT(1) DEFAULT 0,
    IS_FILTERABLE TINYINT(1) DEFAULT 0,
    SORT INT DEFAULT 100,
    INDEX idx_section (IBLOCK_SECTION_ID)
);

CREATE TABLE b_pim_attribute_value (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    PRODUCT_ID INT NOT NULL,          -- ID элемента инфоблока
    ATTRIBUTE_ID INT NOT NULL,
    VALUE_STRING VARCHAR(1000),
    VALUE_NUMBER DECIMAL(15,4),
    VALUE_BOOLEAN TINYINT(1),
    INDEX idx_product_attr (PRODUCT_ID, ATTRIBUTE_ID)
);

CREATE TABLE b_pim_attribute_option (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    ATTRIBUTE_ID INT NOT NULL,
    VALUE VARCHAR(500) NOT NULL,
    SORT INT DEFAULT 100
);

Такой подход позволяет задавать атрибуты на уровне категории без изменения схемы инфоблока.

Административный интерфейс редактирования атрибутов

Кастомный административный раздел на базе компонента bitrix:main.ui.grid:

// /local/modules/company.pim/admin/attributes.php
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_before.php';

$APPLICATION->SetTitle('PIM: Управление атрибутами');

// Список атрибутов для выбранной категории
$sectionId = (int)$_GET['section_id'];
$connection = \Bitrix\Main\Application::getConnection();
$attributes = $connection->query(
    "SELECT * FROM b_pim_attribute WHERE IBLOCK_SECTION_ID = {$sectionId} ORDER BY SORT"
);

Интерфейс позволяет менеджеру:

  • Добавлять атрибуты к категории (без изменения структуры БД)
  • Задавать тип, обязательность, возможность фильтрации
  • Сортировать атрибуты перетаскиванием
  • Копировать набор атрибутов в дочернюю категорию

Форма редактирования товара с динамическими атрибутами

В административном редакторе товара (sale.admin.order.edit или кастомная страница) нужно отображать и сохранять атрибуты текущей категории:

function renderPimFields(int $productId, int $sectionId): string
{
    $connection  = \Bitrix\Main\Application::getConnection();
    $attributes  = $connection->query(
        "SELECT a.*, v.VALUE_STRING, v.VALUE_NUMBER, v.VALUE_BOOLEAN
         FROM b_pim_attribute a
         LEFT JOIN b_pim_attribute_value v
             ON v.ATTRIBUTE_ID = a.ID AND v.PRODUCT_ID = {$productId}
         WHERE a.IBLOCK_SECTION_ID = {$sectionId}
         ORDER BY a.SORT"
    );

    $html = '<table class="pim-attributes">';
    while ($attr = $attributes->fetch()) {
        $html .= '<tr>';
        $html .= '<td><label>' . htmlspecialchars($attr['NAME'])
               . ($attr['IS_REQUIRED'] ? ' <span class="req">*</span>' : '')
               . '</label></td>';
        $html .= '<td>' . renderAttributeInput($attr) . '</td>';
        $html .= '</tr>';
    }
    $html .= '</table>';
    return $html;
}

function savePimFields(int $productId, array $postData): void
{
    $connection = \Bitrix\Main\Application::getConnection();

    foreach ($postData as $attrId => $value) {
        $attrId = (int)$attrId;
        $existing = $connection->query(
            "SELECT ID FROM b_pim_attribute_value
             WHERE PRODUCT_ID = {$productId} AND ATTRIBUTE_ID = {$attrId}"
        )->fetch();

        $attr = $connection->query(
            "SELECT TYPE FROM b_pim_attribute WHERE ID = {$attrId}"
        )->fetch();

        $field  = match($attr['TYPE']) {
            'number'  => 'VALUE_NUMBER',
            'boolean' => 'VALUE_BOOLEAN',
            default   => 'VALUE_STRING',
        };
        $safeVal = $connection->getSqlHelper()->forSql($value);

        if ($existing) {
            $connection->query(
                "UPDATE b_pim_attribute_value
                 SET {$field} = '{$safeVal}'
                 WHERE ID = {$existing['ID']}"
            );
        } else {
            $connection->query(
                "INSERT INTO b_pim_attribute_value
                 (PRODUCT_ID, ATTRIBUTE_ID, {$field})
                 VALUES ({$productId}, {$attrId}, '{$safeVal}')"
            );
        }
    }
}

Валидация атрибутов

Обязательные атрибуты проверяются при сохранении товара:

function validatePimAttributes(int $productId, int $sectionId): array
{
    $errors     = [];
    $connection = \Bitrix\Main\Application::getConnection();

    $required = $connection->query(
        "SELECT a.ID, a.NAME FROM b_pim_attribute a
         LEFT JOIN b_pim_attribute_value v
             ON v.ATTRIBUTE_ID = a.ID AND v.PRODUCT_ID = {$productId}
         WHERE a.IBLOCK_SECTION_ID = {$sectionId}
           AND a.IS_REQUIRED = 1
           AND v.ID IS NULL"
    );

    while ($row = $required->fetch()) {
        $errors[] = 'Не заполнен обязательный атрибут: ' . $row['NAME'];
    }

    return $errors;
}

Синдикация на несколько каналов

Кастомная PIM позволяет экспортировать данные в разные форматы для разных каналов:

  • Yandex.Market YML — генератор фида читает b_pim_attribute_value и маппит в стандартные элементы YML
  • OZON / Wildberries — JSON-шаблоны под каждый маркетплейс
  • Google Merchant — XML-фид с атрибутами g:brand, g:gtin и т.д.
function buildYmlOffer(int $productId): array
{
    $connection = \Bitrix\Main\Application::getConnection();
    $values     = $connection->query(
        "SELECT a.CODE, v.VALUE_STRING, v.VALUE_NUMBER
         FROM b_pim_attribute_value v
         JOIN b_pim_attribute a ON a.ID = v.ATTRIBUTE_ID
         WHERE v.PRODUCT_ID = {$productId}"
    );

    $params = [];
    while ($row = $values->fetch()) {
        $params[$row['CODE']] = $row['VALUE_STRING'] ?? $row['VALUE_NUMBER'];
    }

    return $params; // используется при генерации YML
}

Сроки реализации

Объём Состав Срок
Базовая PIM (динамические атрибуты, форма редактирования) Таблицы + форма + сохранение 2–3 недели
PIM с валидацией, UI сортировки, копированием атрибутов Полноценный admin UI + JS-сортировка 4–5 недель
PIM + синдикация (YML, маркетплейсы) + массовое редактирование Экспортёры + bulk edit таблица 6–8 недель

Кастомная PIM — правильный выбор для команд, уже работающих в Битрикс. Главный риск — чрезмерное усложнение: нужно чётко зафиксировать требования до начала разработки и не пытаться воспроизвести Akeneo внутри Битрикс.