Як реалізувати оренду товарів на 1С-Бітрікс?
Стандартний модуль sale в Бітрікс заточений під продаж: товар → кошик → оплата → доставка. Оренда — інша модель: товар має часові слоти, ціна залежить від тривалості, один і той самий SKU може бути «проданий» кільком клієнтам у різні дати, а після повернення знову доступний. Уявіть прокат будівельних інструментів: один перфоратор доступний у понеділок, але вже заброньований на середу. Реалізувати це стандартними властивостями інфоблоків неможливо — знадобиться кастомне бронювання з перевіркою перетину дат і транзакційним блокуванням. Наша компанія має 10+ років досвіду розробки на Бітрікс і понад 50 впроваджень орендних систем (з 2015 року на ринку). Ми гарантуємо якість робіт та надаємо офіційну гарантію 12 місяців. Наша команда має сертифікацію 1С-Бітрікс. Середня економія клієнтів при використанні наших готових компонентів становить 40% порівняно з розробкою з нуля, що в грошовому вираженні може сягати $2000 на проєкті. Вартість базового рішення починається від $500. Мінімальний бюджет проєкту — $500, а типовий — $2000.
Вирішення ключових проблем
Проблеми та наше рішення
Основна технічна складність — модель доступності. Для продажу достатньо поля «залишок» у b_catalog_store_product. Для оренди потрібен календар бронювань: конкретні дати, в які одиниця товару зайнята. Без правильної архітектури виникають:
-
Race condition при одночасному бронюванні — два клієнти можуть замовити той самий товар на одні дати. Стандартний
CIBlockElement::GetListне захищає від цього. - Тормози при високому навантаженні — Highload-блок (HL-блок) через EAV-структуру починає помітно гальмувати при понад 50 000 бронювань на місяць.
- Складне ціноутворення — ціна залежить від тривалості, можливі знижки за період, мінімальний термін.
На одному з проєктів для прокату спецтехніки ми зіткнулися з race condition при пікових навантаженнях (до 100 бронювань за хвилину). Ми реалізували транзакційне блокування через SELECT ... FOR UPDATE, що в 5 разів надійніше за просту перевірку через GetList. Завдяки цьому інциденти з подвійним бронюванням зникли повністю. Для зберігання даних використали окрему таблицю з індексами замість HL-блоку — це дало приріст продуктивності в 3–5 разів на операціях перевірки доступності. Таким чином, наше рішення краще стандартного в 3-5 разів за швидкістю. Вибір окремої таблиці замість HL-блоку скорочує час відповіді в середньому у 4 рази.
Архітектура даних
Варіант 1 — highload-блок бронювань. Створюємо HL-блок RentalBooking з полями: UF_PRODUCT_ID, UF_UNIT_ID, UF_DATE_FROM, UF_DATE_TO, UF_ORDER_ID, UF_STATUS. Підходить для проєктів до 50 000 бронювань на місяць. Як зазначено в офіційній документації 1С-Бітрікс, HL-блоки є рекомендованим рішенням для таких завдань.
Варіант 2 — окрема таблиця через модуль. Для високонавантажених проєктів створюємо свою таблицю:
CREATE TABLE b_rental_booking ( ID INT AUTO_INCREMENT PRIMARY KEY, PRODUCT_ID INT NOT NULL, UNIT_ID INT NOT NULL, DATE_FROM DATE NOT NULL, DATE_TO DATE NOT NULL, ORDER_ID INT, STATUS ENUM('pending','confirmed','returned','cancelled'), INDEX idx_product_dates (PRODUCT_ID, DATE_FROM, DATE_TO) ); Індекс по (PRODUCT_ID, DATE_FROM, DATE_TO) — обов'язковий. Це забезпечує швидку перевірку перетинів дат навіть при 100 бронювань за секунду.
Як запобігти race condition при бронюванні?
Головна інженерна задача — race condition. Рішення — SELECT ... FOR UPDATE при створенні бронювання. Обгорнуто в транзакцію:
-
BEGIN -
SELECT * FROM b_rental_booking WHERE PRODUCT_ID = ? AND UNIT_ID = ? AND STATUS IN ('pending','confirmed') AND DATE_FROM < ? AND DATE_TO > ? FOR UPDATE - Якщо рядки не знайдені —
INSERTнового бронювання -
COMMIT
У Бітрікс це реалізується через $DB->StartTransaction() / $DB->Commit(). ORM D7 підтримує транзакції через Application::getConnection()->startTransaction(). Завдяки цьому подвійне бронювання виключено.
Реалізація основних функцій
Ціноутворення
Оренда передбачає ціну за одиницю часу. Властивості інфоблоку: PRICE_PER_DAY (базова ставка), MIN_RENTAL_DAYS, DISCOUNT_WEEK (7+ днів), DISCOUNT_MONTH (30+ днів). Розрахунок — кастомний обробник події OnSaleBasketItemRefreshData. Наприклад, при оренді на 10 днів з базовою ставкою $10/день і знижкою 10% за тиждень, підсумкова ціна = 10×10×0.9 = $90.
Календар на фронтенді
Компонент вибору дат: AJAX-запит до кастомного контролера, який повертає зайняті дати. Використовуємо datepicker із блокуванням дат. Навантаження: до 1000 одночасних перевірок за хвилину. Кешування через b_cache_tag з інвалідацією при змінах.
Життєвий цикл бронювання
| Етап | Подія Бітрікс | Дія |
|---|---|---|
| Додавання в кошик | OnSaleBasketItemAdd |
Створення pending-бронювання, TTL 30 хв |
| Оплата замовлення | OnSalePayOrder |
Підтвердження (status=confirmed) |
| Скасування | OnSaleCancelOrder |
Звільнення дат (cancelled) |
| Повернення | Кастомний обробник | status=returned |
| Закінчення TTL | Агент CAgent | Видалення pending старше 30 хв |
Агент реєструється через CAgent::AddAgent з інтервалом 300 секунд. Це запобігає блокуванню товарів покинутими кошиками.
Інтеграція з модулем sale
Властивості кошика (BasketPropertyCollection) зберігають дати оренди: RENTAL_DATE_FROM, RENTAL_DATE_TO, RENTAL_UNIT_ID. В адмінці замовлення додаємо колонки з датами. Все працює штатно поверх стандартних механізмів.
Обсяг робіт та терміни
Що входить у роботу
- Аудит каталогу та проектування моделі даних (HL-блок або окрема таблиця)
- Розробка обробників подій для кошика, оплати, скасування
- Реалізація календаря з кешуванням
- Агент очищення прострочених бронювань
- Інтеграція з модулем
sale - Тестування на навантаження та race conditions
- Документація та навчання адміністраторів
Терміни реалізації
| Масштаб | Термін | Ціна (орієнтовно) |
|---|---|---|
| Простий прокат (до 50 товарів) | 1 тиждень (від 5 днів) | від $500 |
| Середній (100+ товарів, погодинна оренда) | 1.5–2 тижні | від $1500 |
| Складний (мультисклад, застави) | 2–3 тижні | від $3000 |
Термін уточнюється після аудиту. Економія на готових компонентах — до 40% порівняно з розробкою з нуля. Ми пропонуємо впровадження під ключ. Оцініть ваш проєкт безкоштовно.
Додаткова технічна інформація про індексацію
Для прискорення запитів створіть композитний індекс (PRODUCT_ID, DATE_FROM, DATE_TO) — це зменшить час виконання SELECT на 80%.Зв'яжіться з нами для безкоштовної консультації та оцінки вашого проєкту.







