Розробка калькулятора будматеріалів на 1С-Бітрікс
Калькулятор будматеріалів — це інструмент, який переводить параметри об'єкта (площа, тип конструкції, кількість кімнат) у конкретний список матеріалів з кількістю та ціною. Для клієнта це відповідь на питання «скільки мені потрібно і скільки це коштує». Для магазину — готовий кошик, який залишається лише оформити.
Типи калькуляторів будматеріалів
Залежно від ніші магазину калькулятор рахує різні речі:
- Цегла та блоки — за площею стіни, з урахуванням товщини кладки, вирахуванням прорізів
- Покрівельні матеріали — площа покрівлі за кутом нахилу, нахлест, карнизи
- Підлогові покриття — площа приміщення + запас на підрізку (зазвичай 5–15%)
- Фарба та штукатурка — площа, кількість шарів, витрата на м²
- Утеплювач — площа, товщина шару, щільність упаковки
Кожен тип має свої формули та свої складності.
Архітектура: норми витрати в базі даних
Норми витрати матеріалів — це довідкові дані, які змінюються при появі нових продуктів. Зберігати їх у коді не можна. HL-блок MaterialNorms:
| Поле | Тип | Опис |
|---|---|---|
UF_MATERIAL_ID |
Int | ID товару в каталозі |
UF_MATERIAL_NAME |
String | Назва (для відображення) |
UF_UNIT |
Enum | Одиниця розрахунку (м², м³, пог.м.) |
UF_CONSUMPTION_RATE |
Float | Норма витрати на одиницю |
UF_WASTE_FACTOR |
Float | Коефіцієнт відходів (1.05–1.15) |
UF_PACKAGE_SIZE |
Float | Одиниця продажу (шт., рулон, мішок) |
UF_PACKAGE_UNIT |
String | Одиниця упаковки |
PHP: логіка розрахунку цегляної кладки
namespace MyProject\Services\Calculators;
class BrickCalculator
{
// Витрата цегли в штуках на м² залежно від товщини кладки
private const CONSUMPTION_BY_THICKNESS = [
120 => ['full' => 51, 'half' => 26], // кладка в півцегли та в цеглу
250 => ['full' => 102, 'half' => 51],
380 => ['full' => 153, 'half' => 77],
510 => ['full' => 204, 'half' => 102],
];
public static function calculate(
float $wallLength,
float $wallHeight,
array $openings, // [{width, height}, ...] — прорізи
int $thicknessMm, // товщина стіни в мм
float $wasteFactor = 1.05 // запас 5%
): array {
$wallArea = $wallLength * $wallHeight;
$openingsArea = array_sum(array_map(fn($o) => $o['width'] * $o['height'], $openings));
$netArea = $wallArea - $openingsArea;
$consumption = self::CONSUMPTION_BY_THICKNESS[$thicknessMm]['full'] ?? 102;
$brickCount = ceil($netArea * $consumption * $wasteFactor);
// Переведення в палети (зазвичай 480 штук на палеті)
$palletsNeeded = ceil($brickCount / 480);
return [
'wall_area' => round($netArea, 2),
'openings_area' => round($openingsArea, 2),
'brick_count' => $brickCount,
'pallets' => $palletsNeeded,
'waste_count' => ceil($netArea * $consumption * ($wasteFactor - 1)),
];
}
}
PHP: універсальна база для різних матеріалів
class MaterialCalculator
{
public static function calculate(string $materialType, array $params): array
{
$norm = self::getNorm($materialType);
if (!$norm) {
throw new \InvalidArgumentException("Невідомий тип матеріалу: {$materialType}");
}
$area = $params['area'] ?? 0;
// Кількість в одиницях витрати
$rawQuantity = $area * $norm['UF_CONSUMPTION_RATE'] * $norm['UF_WASTE_FACTOR'];
// Переведення в упаковки (округлюємо вгору)
$packages = ceil($rawQuantity / $norm['UF_PACKAGE_SIZE']);
$quantity = $packages * $norm['UF_PACKAGE_SIZE'];
// Отримуємо актуальну ціну з каталогу Бітрікс
$price = self::getPrice($norm['UF_MATERIAL_ID']);
return [
'material_id' => $norm['UF_MATERIAL_ID'],
'name' => $norm['UF_MATERIAL_NAME'],
'quantity' => $quantity,
'packages' => $packages,
'package_unit' => $norm['UF_PACKAGE_UNIT'],
'price' => $price,
'total' => round($packages * $price, 2),
];
}
private static function getPrice(int $productId): float
{
$price = \CPrice::GetBasePrice($productId);
return (float)($price['PRICE'] ?? 0);
}
}
Готовий кошик з результатів розрахунку
Ключова конкурентна перевага — прямий перехід «додати все в кошик»:
// Після розрахунку — додаємо всі матеріали в кошик Бітрікс
public function addToCart(array $calculationResult): \Bitrix\Main\Result
{
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(
\Bitrix\Sale\Fuser::getId(),
\Bitrix\Main\Context::getCurrent()->getSite()
);
foreach ($calculationResult['materials'] as $material) {
$item = $basket->createItem('catalog', $material['material_id']);
$item->setField('QUANTITY', $material['packages']);
}
return $basket->save();
}
Складності та типові помилки
Не враховані одиниці виміру. Норма витрати в л/м², а продається у відрах по 5 літрів — помилка в розрахунку пачок.
Ігнорується геометрія. Покрівля 45° має площу в 1.41 рази більше горизонтальної проєкції. Якщо не врахувати кут, розрахунок помилковий на 41%.
Немає запасу на підрізку. Для плитки, ламінату, шпалер — обов'язковий коефіцієнт 1.05–1.15. Без нього клієнт докуповує пізніше за іншою ціною.
Терміни
| Завдання | Термін |
|---|---|
| Калькулятор одного типу матеріалу з формою заявки | 4–7 днів |
| Мультиматеріальний калькулятор з нормами в HL-блоці та додаванням у кошик | 2–3 тижні |
| Повний калькулятор ремонту (кілька категорій, кошторис PDF, історія) | 4–7 тижнів |
Калькулятор будматеріалів, який рахує точно та пропонує додати результат у кошик, скорочує шлях від задуму до покупки. Клієнт не йде «порахувати» — він рахує прямо тут і тут же оформлює замовлення.







