Автонаповнення залишків і цін з прайс-листів постачальників 1С-Бітрікс
Прайс-лист постачальника — Excel або CSV, який надсилають за розкладом на пошту або викладають на FTP. На відміну від API, прайс не оновлюється в реальному часі, але для більшості B2B-магазинів оновлення раз на день-два цілком достатньо. Завдання: витягти ціни та залишки з нестандартного файлу та оновити b_catalog_price і b_catalog_store_product.
Отримання прайс-листа
Email з вкладенням — найчастіший сценарій. Підключаємося до поштової скриньки через IMAP, шукаємо листи від постачальника, завантажуємо вкладення:
$imap = imap_open('{mail.example.com:993/imap/ssl}INBOX', $user, $pass);
$emails = imap_search($imap, 'FROM "[email protected]" UNSEEN');
foreach ($emails as $num) {
$structure = imap_fetchstructure($imap, $num);
// витягуємо вкладення
}
FTP/SFTP — регулярно завантажуємо файл, порівнюємо дату змін з попереднім запуском. Якщо файл не змінився — пропускаємо.
HTTP URL — постачальник публікує прайс за посиланням, іноді з Basic Auth.
Читання Excel/CSV
Для Excel використовуємо PhpSpreadsheet (наступник PHPExcel):
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($filePath);
$sheet = $spreadsheet->getActiveSheet();
$rows = $sheet->toArray();
Проблема: у кожного постачальника свій формат. Стовпці з артикулом, ціною та залишком знаходяться на різних позиціях, перші рядки можуть бути заголовками різної довжини.
Рішення: конфігурований маппінг колонок, який зберігається в базі:
supplier_id: 42
sku_column: B # артикул у стовпці B
price_column: D # ціна у стовпці D
qty_column: F # залишок у стовпці F
header_rows: 3 # перші 3 рядки — шапка
Оновлення цін
Ціни в 1С-Бітрікс зберігаються в b_catalog_price. Кожен тип ціни — окремий запис:
$priceType = CCatalogPriceType::GetList([], ['NAME' => 'Закупівельна'])->Fetch();
CCatalogProduct::SetPrice($elementId, $priceType['ID'], $price, 'UAH');
Якщо у постачальника кілька типів цін (роздрібна, оптова, спеціальна) — створюємо відповідні типи в 1С-Бітрікс та оновлюємо кожен окремо.
Націнка при імпорті: часто потрібно імпортувати закупівельну ціну і автоматично розраховувати роздрібну. Коефіцієнт націнки зберігається в налаштуваннях постачальника та застосовується при записі:
$retailPrice = $supplierPrice * $supplier->getMarkupCoefficient();
Оновлення залишків
b_catalog_store_product — таблиця залишків по складах. Якщо склади не використовуються, оновлюємо QUANTITY напряму через CCatalogProduct::Update().
При використанні складів:
CCatalogStoreProduct::Update($storeProductId, ['AMOUNT' => $qty]);
// або додаємо запис якщо не існує
CCatalogStoreProduct::Add([
'PRODUCT_ID' => $elementId,
'STORE_ID' => $storeId,
'AMOUNT' => $qty,
]);
Ідентифікація товарів за артикулом
Прайс містить артикули постачальника, в 1С-Бітрікс зберігаються власні коди. Потрібен словник відповідностей. Варіанти зберігання:
- Властивість
SUPPLIER_SKUв інфоблоці — простий варіант - Highload-блок
SupplierMappingз парами(supplier_id, supplier_sku, element_id)— масштабований
Для 50 000+ SKU будуємо зворотний індекс у пам'яті при запуску воркера: завантажуємо всі пари в масив PHP один раз, використовуємо для маппінгу без запитів до БД.
Таймлайн робіт
| Етап | Термін |
|---|---|
| Налаштування отримання файлу (email/FTP/HTTP) | 4–8 годин |
| Читання та парсинг Excel/CSV з конфігурованим маппінгом | 1–2 дні |
| Оновлення цін і залишків у 1С-Бітрікс | 1 день |
| Логіка ідентифікації товарів, словник артикулів | 4–8 годин |
| Обробка помилок, логування, розклад | 4–6 годин |
Разом: 4–6 робочих днів на одного постачальника. При кількох постачальниках — конфігурований маппінг окупається з третього підключення.







