Development of a 1C-Bitrix booking module

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    745
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

1C-Bitrix Booking Module Development

Booking is the reservation of a resource for a time interval with conflict prevention. The resource can be anything: a hotel room, a rental car, a meeting room, a tourist tour, a sports facility. The underlying logic is the same — show availability, accept the reservation, and block the slot for others.

Bitrix has no ready-made tool for this. The task is sometimes attempted using online store orders, but b_sale_order is not designed for time intervals — there is no concept of "period", no conflict checking, and no occupancy visualization.

Data Model

The vendor.booking module with key tables:

  • b_vendor_booking_resource — resources: id, name, type, capacity, iblock_element_id (link to an info block element), settings (JSON: minimum period, maximum period, step, prepayment)
  • b_vendor_booking_slot — predefined slots (for hourly rental): id, resource_id, date, time_from, time_to, status
  • b_vendor_booking_reservation — reservations: id, resource_id, user_id, date_from, date_to, status (pending/confirmed/cancelled/completed), total_price, order_id
  • b_vendor_booking_block — manual date blocking: id, resource_id, date_from, date_to, reason

For daily rental the model uses date_from/date_to without slots. For hourly rental — slots with fixed intervals.

Availability Check

The key operation is an atomic check and reservation. Without a transaction, a race condition is inevitable under concurrent requests:

public function reserve(int $resourceId, \DateTime $from, \DateTime $to, int $userId): ReservationResult
{
    $connection = \Bitrix\Main\Application::getConnection();
    $connection->startTransaction();

    try {
        // Check for conflicts with row locking
        $conflicts = $connection->query("
            SELECT id FROM b_vendor_booking_reservation
            WHERE resource_id = {$resourceId}
              AND status IN ('pending', 'confirmed')
              AND NOT (date_to <= '{$from->format('Y-m-d')}' OR date_from >= '{$to->format('Y-m-d')}')
            FOR UPDATE
        ")->fetch();

        if ($conflicts) {
            $connection->rollbackTransaction();
            return ReservationResult::conflict();
        }

        $reservationId = ReservationTable::add([
            'RESOURCE_ID' => $resourceId,
            'USER_ID'     => $userId,
            'DATE_FROM'   => $from,
            'DATE_TO'     => $to,
            'STATUS'      => 'pending',
        ])->getId();

        $connection->commitTransaction();
        return ReservationResult::success($reservationId);

    } catch (\Throwable $e) {
        $connection->rollbackTransaction();
        throw $e;
    }
}

Date Selection Widget

On the frontend — an interactive calendar. Implemented via flatpickr or a custom component. Available dates are fetched via AJAX:

GET /bitrix/components/vendor/booking.calendar/ajax.php
    ?resource_id=12&month=2024-06

→ {"available": ["2024-06-01","2024-06-03",...], "booked": ["2024-06-02","2024-06-05",...]}

Data is cached via \Bitrix\Main\Data\Cache for 5 minutes. When a reservation changes, the cache is invalidated via the tag booking_resource_{id}.

Pricing

The cost is calculated according to the following rules:

  • Base rate per period (day/hour) from b_vendor_booking_resource
  • Seasonal surcharges (high season, public holidays) from b_vendor_booking_price_rule
  • Long-term rental discounts (7+ days — minus 10%)
  • Minimum prepayment percentage
$calculator = new PriceCalculator($resource);
$result = $calculator->calculate($dateFrom, $dateTo);
// → ['total' => 15000, 'prepayment' => 3000, 'discount' => 1500, 'nights' => 3]

Payment and Order Link

After a reservation is confirmed, an order is created in b_sale_order for the prepayment amount (or the full amount). The reservation is linked to the order via reservation.order_id. After successful payment the reservation status changes from pending to confirmed.

When a paid order is cancelled — reservation status becomes cancelled and the slot is released.

Administrative Interface

The administrator section includes:

  • Resource list with settings
  • Visual schedule (timeline view) with reservations by day
  • Manual reservation creation form (for telephone inquiries)
  • Date blocking for maintenance
  • Resource utilisation report

The timeline view is built via a JS library (FullCalendar or dhtmlxScheduler), data provided through the module's REST endpoint.

Notifications

  • To the user upon booking creation (confirmation with details)
  • To the user upon manager confirmation
  • To the administrator upon a new booking
  • Reminder N days before the start (via agent)

All notifications via the standard \Bitrix\Main\Mail\Event::send() with event templates in the main module.

Development Timeline

Stage Duration
Data model, ORM tables 1 day
Availability check logic (transactions) 2 days
Calendar widget, availability AJAX 2 days
Pricing, seasonal rules 2 days
Order and payment integration 2 days
Administrative interface + timeline 3 days
Notifications, reminders 1 day
Concurrent reservation testing 1 day

Total: 14 working days. For hotels with multiple room categories and channel manager integration — separate estimate required.