Розробка підбору розміру за параметрами на 1С-Бітрікс
Конвертер розмірів допомагає тим, хто вже знає свій розмір в одній системі. Підбір за параметрами вирішує інше завдання: покупець знає свої мірки — зріст, вагу, обхват грудей, довжину стопи, — але не знає, який розмір йому підійде у конкретному бренді. Або знає, що у різних виробників він носить різні розміри, і хоче отримати рекомендацію саме для даного товару.
Це найрозумніший із інструментів розмірної навігації — і найскладніший у реалізації.
У чому складність
Підбір за параметрами вимагає зв'язку між трьома наборами даних:
- Мірки покупця — зріст, вага, обхват грудей/талії/стегон, довжина стопи
- Розмірна сітка товару — відповідність розмірних позначень фізичним міркам (з урахуванням допусків на посадку: облягаючий або вільний крій)
- Залишки — рекомендований розмір може бути відсутній на складі, потрібно пропонувати альтернативу
І якщо для одягу підбір відносно прямолінійний (груди → розмір), то для взуття включається питання повноти (широка стопа вимагає іншої колодки), а для спортивного інвентарю — технічні характеристики (довжина ключки за зростом і стилем гри).
Архітектура даних
Розширюємо структуру з таблиці розмірів додатковими параметрами допусків:
CREATE TABLE b_size_fit_rules (
ID SERIAL PRIMARY KEY,
CHART_ID INT NOT NULL REFERENCES b_size_charts(ID),
SIZE_RU VARCHAR(10),
-- Діапазони мірок для цього розміру
CHEST_MIN NUMERIC(5,1), CHEST_MAX NUMERIC(5,1),
WAIST_MIN NUMERIC(5,1), WAIST_MAX NUMERIC(5,1),
HIPS_MIN NUMERIC(5,1), HIPS_MAX NUMERIC(5,1),
HEIGHT_MIN SMALLINT, HEIGHT_MAX SMALLINT,
WEIGHT_MIN SMALLINT, WEIGHT_MAX SMALLINT,
-- Тип посадки (впливає на допуск)
FIT_TYPE VARCHAR(20) -- 'slim', 'regular', 'oversized'
);
Ключовий момент — діапазони мірок, а не точні значення. Розмір 46 підходить для грудей 88–92 см, а не строго для 90 см. Ширина діапазону залежить від типу посадки: slim fit — вузький діапазон, oversized — широкий.
Алгоритм підбору
// SizeFitAdvisor.php
class SizeFitAdvisor {
public function recommend(array $measurements, int $chartId, string $fitType = 'regular'): array {
$rules = SizeFitRulesTable::getList([
'filter' => ['=CHART_ID' => $chartId, '=FIT_TYPE' => $fitType],
'order' => ['SIZE_RU' => 'ASC'],
])->fetchAll();
$scores = [];
foreach ($rules as $rule) {
$score = 0;
$matched = 0;
// Для кожної переданої мірки перевіряємо попадання в діапазон
foreach (['CHEST', 'WAIST', 'HIPS'] as $param) {
if (!isset($measurements[$param])) continue;
$val = (float) $measurements[$param];
$min = (float) $rule[$param . '_MIN'];
$max = (float) $rule[$param . '_MAX'];
if ($val >= $min && $val <= $max) {
$score++;
} elseif ($val < $min) {
$score -= ($min - $val) / 10; // штраф за відхилення
} else {
$score -= ($val - $max) / 10;
}
$matched++;
}
if ($matched > 0) {
$scores[$rule['SIZE_RU']] = $score / $matched;
}
}
arsort($scores); // сортуємо за спаданням очок
$best = array_key_first($scores);
$next = array_keys($scores)[1] ?? null; // другий варіант на випадок відсутності
return ['primary' => $best, 'alternative' => $next, 'scores' => $scores];
}
}
Алгоритм повертає не один розмір, а основну рекомендацію і альтернативу. Це важливо: якщо основний розмір недоступний, показуємо альтернативу з поміткою «якщо 46 немає, візьміть 48 — підійде при вашій статурі».
Перевірка доступності рекомендованого розміру
Після отримання рекомендації — негайна перевірка залишків:
public function checkAvailability(string $sizeRu, int $productId): array {
// Шукаємо торгові пропозиції з даним розміром
$offers = \Bitrix\Iblock\ElementTable::getList([
'filter' => [
'=IBLOCK_ID' => OFFERS_IBLOCK_ID,
'=PROPERTY_CML2_LINK' => $productId,
'=PROPERTY_SIZE_VALUE' => $sizeRu,
'=ACTIVE' => 'Y',
],
'select' => ['ID', 'PROPERTY_QUANTITY'],
])->fetchAll();
$available = array_filter($offers, fn($o) => (int)$o['PROPERTY_QUANTITY_VALUE'] > 0);
return [
'available' => count($available) > 0,
'offers' => $available,
];
}
Форма підбору на картці товару
UX-паттерн: посилання «Підібрати розмір» під вибором розмірів відкриває модальне вікно або розгортає форму.
Одноетапна форма (всі мірки одразу) — для досвідчених покупців:
<form class="size-advisor-form">
<div class="form-row">
<label>Зріст (см): <input type="number" name="height" min="140" max="220"></label>
<label>Вага (кг): <input type="number" name="weight" min="40" max="200"></label>
</div>
<div class="form-row">
<label>Обхват грудей (см): <input type="number" name="chest" min="60" max="160"></label>
<label>Обхват талії (см): <input type="number" name="waist" min="50" max="150"></label>
<label>Обхват стегон (см): <input type="number" name="hips" min="70" max="170"></label>
</div>
<label>Посадка:
<select name="fit_type">
<option value="slim">Облягаюча</option>
<option value="regular" selected>Стандартна</option>
<option value="oversized">Вільна</option>
</select>
</label>
<button type="submit">Підібрати розмір</button>
</form>
Покроковий опитувальник — для тих, хто не звик до таких форм. Одне поле на екрані, з прогрес-баром. Менше когнітивного навантаження, але довший процес.
AJAX-запит до PHP-контролера
Форма відправляє дані на сервер, а не обробляється на JS, тому що:
- Алгоритм підбору на сервері — дані недоступні конкурентам
- Сервер одразу перевіряє залишки та повертає фінальну відповідь
- Результат можна персоналізувати (зберегти мірки для авторизованого користувача)
// SizeAdvisorController.php — дія AJAX
public function recommendAction(): array {
$measurements = [
'CHEST' => (float) $this->request->getPost('chest'),
'WAIST' => (float) $this->request->getPost('waist'),
'HIPS' => (float) $this->request->getPost('hips'),
];
$fitType = $this->request->getPost('fit_type', 'regular');
$productId = (int) $this->request->getPost('product_id');
$chartId = $this->getChartForProduct($productId);
$advisor = new SizeFitAdvisor();
$result = $advisor->recommend($measurements, $chartId, $fitType);
$availability = $advisor->checkAvailability($result['primary'], $productId);
// Зберігаємо мірки авторизованого користувача
if (is_object(global_user()) && !global_user()->IsGuest()) {
UserMeasurementsTable::saveForUser(global_user()->GetID(), $measurements);
}
return [
'recommended_size' => $result['primary'],
'alternative_size' => $result['alternative'],
'available' => $availability['available'],
'offers' => $availability['offers'],
];
}
Збереження мірок в особистому кабінеті
Якщо користувач авторизований, мірки зберігаються і підставляються при наступному зверненні до порадника — навіть на іншому товарі:
CREATE TABLE b_user_measurements (
USER_ID INT PRIMARY KEY REFERENCES b_user(ID),
HEIGHT_CM SMALLINT,
WEIGHT_KG SMALLINT,
CHEST_CM NUMERIC(5,1),
WAIST_CM NUMERIC(5,1),
HIPS_CM NUMERIC(5,1),
FOOT_MM INT,
DATE_UPDATE TIMESTAMP DEFAULT NOW()
);
В особистому кабінеті — розділ «Мої мірки» для ручного редагування.
Строки
| Варіант | Що входить | Строк |
|---|---|---|
| Базовий порадник (JS + таблиця даних) | Форма, алгоритм, результат | 1–2 тижні |
| З перевіркою залишків і альтернативами | + інтеграція з ТП, залишки | 2–3 тижні |
| + ОК з мірками, історія рекомендацій | + збереження профілю | +1 тиждень |
Порадник з розміру на основі мірок дає найточнішу рекомендацію і максимально знижує ймовірність повернення. З усіх розмірних інструментів — найтрудомісткіший, але й найефективніший.







