Розроблення модуля імпорту замовлення з файлу для 1С-Bitrix
На B2B-проектах менеджери закупівлі працюють із прайс-листами. У них є Excel-файл з артикулами та кількістю, і вони хочуть завантажити його в корзину, а не клікати по каталогу. Стандартний Bitrix це не вміє — потрібен окремий модуль.
Підтримувані формати файлів
Практика показує три основні формати від клієнтів:
-
XLSX / XLS — найпоширеніший. Парсинг через
PhpSpreadsheet(встановлюється вlocal/vendor/через composer). - CSV — простий варіант, часто використовується в автоматизованих виявленнях з 1С.
- XML — рідше, але зустрічається на проектах з EDI-інтеграцією.
Завантаження PDF не підтримується — надійно не можливо видобути дані таблиці.
Структура модуля
Модуль зареєстрований у local/modules/vendor.orderimport/. Основні компоненти:
-
lib/FileParser/XlsxParser.php— парсер XLSX -
lib/FileParser/CsvParser.php— парсер CSV -
lib/ProductMatcher.php— пошук товарів за артикулом -
lib/CartFiller.php— заповнення корзини -
components/vendor/orderimport.form/— компонент форми завантаження
Парсинг файлу
Завантажений файл збережений у тимчасовій директорії, тип визначено за розширенням та MIME-типом, потім запущений відповідний парсер. Парсер повертає масив рядків:
// Результат парсингу: масив позицій
[
['sku' => 'ART-1234', 'qty' => 5, 'row' => 2],
['sku' => 'ART-5678', 'qty' => 10, 'row' => 3],
// ...
]
Парсер пропускає рядки заголовка (перший рядок або рядок, де в колонці артикулу текст замість числа). Гнучка налаштування: номери колонок для артикулу та кількості задаються в налаштуваннях модуля або визначаються автоматично за заголовками.
Пошук товарів за артикулом
Артикул у Bitrix зберігається у кількох місцях: поле XML_ID елемента інфоблока, властивість ARTICLE (якщо використовується), поле ARTICLE у таблиці b_catalog_product. Пошук проводиться послідовно:
// 1. Пошук за b_catalog_product.ARTICLE
$product = \Bitrix\Catalog\ProductTable::getList([
'filter' => ['=ARTICLE' => $sku],
'select' => ['ID', 'ARTICLE'],
])->fetch();
// 2. Якщо не знайдено — пошук за XML_ID елемента інфоблока
if (!$product) {
$element = \CIBlockElement::GetList([], ['=XML_ID' => $sku, 'IBLOCK_ID' => $catalogIblockId], false, false, ['ID', 'XML_ID'])->Fetch();
}
Результат пошуку для кожного рядка — статус: found, not_found, multiple (знайдено кілька з одним артикулом — неоднозначність).
Передпросмотр перед додаванням у корзину
Користувач завантажує файл → бачить таблицю з результатом парсингу: для кожного рядка показується знайдений товар (назва, фото, ціна, доступний залишок), кількість з файлу та статус. Рядки зі статусом not_found підсвічуються — користувач може вручну вказати товар з каталогу.
Лише після підтвердження користувачем дані надісилаються в корзину. Це захищає від випадкових помилок у файлі.
Заповнення корзини
$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), SITE_ID);
foreach ($confirmedItems as $item) {
$basketItem = $basket->getExistsItem('catalog', $item['product_id']);
if ($basketItem) {
$basketItem->setField('QUANTITY', $basketItem->getQuantity() + $item['qty']);
} else {
$newItem = $basket->createItem('catalog', $item['product_id']);
$newItem->setFields([
'QUANTITY' => $item['qty'],
'PRODUCT_PROVIDER_CLASS' => \CCatalogProductProvider::class,
'LID' => SITE_ID,
'CURRENCY' => \Bitrix\Currency\CurrencyManager::getBaseCurrency(),
]);
}
}
$basket->save();
Шаблон файлу для завантаження
На сторінці завантаження відображається посилання для завантаження шаблону — готовий XLSX-файл із заголовками колонок («Артикул», «Кількість», «Примітка») та прикладом даних. Шаблон генерується через PhpSpreadsheet на кожен запит або видається як статичний файл.
Логування завантажень
Усі спроби завантаження записані в таблицю b_orderimport_log:
| Поле | Тип | Призначення |
|---|---|---|
| ID | int auto_increment | — |
| USER_ID | int | Хто завантажував |
| FILE_NAME | varchar(255) | Оригінальна назва файлу |
| ROWS_TOTAL | int | Рядків у файлі |
| ROWS_FOUND | int | Знайдено товарів |
| ROWS_ADDED | int | Додано в корзину |
| STATUS | enum | SUCCESS, PARTIAL, FAILED |
| CREATED_AT | datetime | — |
Терміни розроблення
| Обсяг | Склад | Тривалість |
|---|---|---|
| Базовий | Парсинг XLSX/CSV, пошук за артикулом, додавання в корзину | 5–7 днів |
| Стандартний | + Передпросмотр, ручне сопоставлення ненайденних, шаблон | 9–12 днів |
| Розширений | + XML, логування, підтримка кількох цінових колонок, перевірка залишків | 14–18 днів |







