Налаштування відображення паспортів безпеки товарів у 1С-Бітрікс
Паспорт безпеки (Safety Data Sheet, SDS / MSDS) — обов'язковий документ для хімічних речовин, лакофарбових матеріалів, мийних засобів, промислових газів та деяких інших категорій товарів. При продажу через інтернет-магазин на Бітрікс вимога проста: документ має бути доступний покупцеві до покупки. На практиці це означає PDF у картці товару з версійним контролем і можливістю завантажити.
Зберігання документів
Паспорти безпеки зберігаються у файловому сховищі Бітрікс (/upload/) через модуль main. Зв'язок документа з товаром — через властивість-файл інфоблоку:
Властивість SAFETY_DATA_SHEET (тип F — файл):
- Множинне: ні (один актуальний паспорт)
- Обов'язкове: ні (є не у всіх товарів)
- Підказка: «PDF паспорта безпеки (ДСТУ 30333-2007)»
Для версійного контролю — додаткова властивість SAFETY_DATA_SHEET_DATE (тип DateTime) — дата версії документа.
Завантаження при масовому оновленні
Паспорти часто надходять пачкою від постачальника у ZIP-архіві з іменами файлів за артикулом. Скрипт масового завантаження:
function importSdsDocuments(string $zipPath, int $iblockId): array
{
$zip = new \ZipArchive();
$zip->open($zipPath);
$results = ['ok' => 0, 'not_found' => [], 'error' => []];
for ($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
if (!str_ends_with(strtolower($filename), '.pdf')) continue;
// Витягуємо артикул з імені файлу (напр. "ART-12345_msds.pdf")
preg_match('/^([A-Z0-9\-]+)/i', $filename, $matches);
$article = $matches[1] ?? '';
$product = \CIBlockElement::GetList([], [
'IBLOCK_ID' => $iblockId,
'PROPERTY_ARTICLE' => $article,
], false, ['nPageSize' => 1], ['ID', 'NAME'])->GetNext();
if (!$product) {
$results['not_found'][] = $filename;
continue;
}
// Зберігаємо файл
$tmpPath = sys_get_temp_dir() . '/' . $filename;
file_put_contents($tmpPath, $zip->getFromIndex($i));
$fileId = \CFile::SaveFile([
'name' => $filename,
'tmp_name' => $tmpPath,
'type' => 'application/pdf',
], 'sds_documents');
if ($fileId) {
\CIBlockElement::SetPropertyValuesEx($product['ID'], $iblockId, [
'SAFETY_DATA_SHEET' => $fileId,
'SAFETY_DATA_SHEET_DATE' => date('d.m.Y'),
]);
$results['ok']++;
}
}
$zip->close();
return $results;
}
Відображення у картці товару
У шаблоні компонента bitrix:catalog.element додаємо блок паспорта безпеки:
<?php if (!empty($arResult['PROPERTIES']['SAFETY_DATA_SHEET']['VALUE'])): ?>
<?php $sdsFile = \CFile::GetFileArray($arResult['PROPERTIES']['SAFETY_DATA_SHEET']['VALUE']); ?>
<div class="product-sds">
<h4>Документація з безпеки</h4>
<a href="<?= \CFile::GetPath($arResult['PROPERTIES']['SAFETY_DATA_SHEET']['VALUE']) ?>"
download="<?= htmlspecialchars($sdsFile['ORIGINAL_NAME']) ?>"
class="sds-download-btn">
<span class="pdf-icon"></span>
Паспорт безпеки (PDF)
<?php if (!empty($arResult['PROPERTIES']['SAFETY_DATA_SHEET_DATE']['VALUE'])): ?>
<small>версія від <?= $arResult['PROPERTIES']['SAFETY_DATA_SHEET_DATE']['VALUE'] ?></small>
<?php endif; ?>
</a>
<p class="sds-note">Відповідно до ДСТУ 30333-2007</p>
</div>
<?php endif; ?>
Атрибут download забезпечує завантаження замість відкриття у браузері.
Перевірка наявності SDS при додаванні до каталогу
Для категорій, де SDS обов'язковий (наприклад, розділ «Хімія», «Лакофарбові матеріали»), налаштовуємо валідацію через обробник події OnBeforeIBlockElementAdd:
AddEventHandler('iblock', 'OnBeforeIBlockElementAdd', function(&$fields) {
$requiredSdsSections = \Bitrix\Main\Config\Option::get('sds_module', 'required_sections', '');
$requiredSectionIds = array_filter(explode(',', $requiredSdsSections));
if (in_array($fields['IBLOCK_SECTION_ID'], $requiredSectionIds)) {
if (empty($fields['PROPERTY_VALUES']['SAFETY_DATA_SHEET'])) {
// Попередження (не блокування — редактор може заповнити пізніше)
$GLOBALS['APPLICATION']->ThrowException(
'Увага: для цього розділу рекомендується прикріпити паспорт безпеки.',
'SDS_MISSING'
);
}
}
});
Звіт за товарами без SDS
Адміністративний звіт GET /bitrix/admin/sds_report.php: список товарів із «хімічних» розділів без прикріпленого паспорта безпеки з кнопкою швидкого завантаження файлу прямо з таблиці.
SELECT ie.ID, ie.NAME, s.NAME as section_name
FROM b_iblock_element ie
JOIN b_iblock_section s ON s.ID = ie.IBLOCK_SECTION_ID
LEFT JOIN b_iblock_element_property iep
ON iep.IBLOCK_ELEMENT_ID = ie.ID
AND iep.IBLOCK_PROPERTY_ID = (
SELECT ID FROM b_iblock_property
WHERE IBLOCK_ID = ie.IBLOCK_ID AND CODE = 'SAFETY_DATA_SHEET'
)
WHERE ie.IBLOCK_ID = ? AND ie.ACTIVE = 'Y'
AND s.ID IN (/* розділи з обов'язковим SDS */)
AND (iep.VALUE IS NULL OR iep.VALUE = '')
ORDER BY s.NAME, ie.NAME;
Терміни
| Етап | Термін |
|---|---|
| Налаштування властивостей інфоблоку | 0.5 дня |
| Скрипт масового завантаження з ZIP | 1 день |
| Шаблон відображення у картці | 1 день |
| Звіт за відсутніми документами | 1 день |
| Тестування | 0.5 дня |
| Разом | 4 дні |







