1C-Bitrix Appointment Booking Module Development
Appointment booking is a simplified version of resource booking tied to a specific specialist and time slot. Medical clinics, hair salons, auto repair shops, legal consultations. The scheme is the same everywhere: the client selects a service, a specialist, a date and time, and receives a confirmation.
Difference from Resource Booking
In resource booking, an object is reserved (a room, a car). In appointment booking — the time of a specific specialist. The specialist is a Bitrix user with an attached schedule. One specialist can see multiple clients on the same day at different hours. The schedule changes: days off, vacations, rescheduling.
Data Structure
The vendor.appointment module:
-
b_vendor_appt_staff— specialists: id, user_id (→b_user), name, photo_file_id, services (JSON array of service IDs), is_active -
b_vendor_appt_service— services: id, name, duration_minutes, iblock_element_id, is_active -
b_vendor_appt_schedule— working schedule: id, staff_id, day_of_week (0–6), time_from, time_to, slot_duration_minutes -
b_vendor_appt_exception— schedule exceptions: id, staff_id, date, type (day_off/custom), custom_from, custom_to -
b_vendor_appt_appointment— appointments: id, staff_id, service_id, user_id, date, time_from, time_to, status, notes, created_at
Available Slot Generation
Slots are generated on the fly — storing them in the database is impractical. When availability is requested:
public function getAvailableSlots(int $staffId, string $date): array
{
$dayOfWeek = (int) (new \DateTime($date))->format('N') % 7;
$schedule = StaffScheduleTable::getList([
'filter' => ['=STAFF_ID' => $staffId, '=DAY_OF_WEEK' => $dayOfWeek],
])->fetch();
if (!$schedule) return [];
// Check exceptions
$exception = ExceptionTable::getList([
'filter' => ['=STAFF_ID' => $staffId, '=DATE' => $date],
])->fetch();
if ($exception && $exception['TYPE'] === 'day_off') return [];
$slots = $this->generateSlots(
$exception['CUSTOM_FROM'] ?? $schedule['TIME_FROM'],
$exception['CUSTOM_TO'] ?? $schedule['TIME_TO'],
(int) $schedule['SLOT_DURATION_MINUTES']
);
// Subtract booked slots
$booked = AppointmentTable::getList([
'filter' => ['=STAFF_ID' => $staffId, '=DATE' => $date, '!STATUS' => 'cancelled'],
'select' => ['TIME_FROM', 'TIME_TO'],
])->fetchAll();
return $this->subtractBooked($slots, $booked);
}
Single-Flow Booking
On the frontend — a three-step widget:
- Service selection (cards or list from an info block)
- Specialist + date + time selection (AJAX slot update on date change)
- Contact details + confirmation
Each step is an AJAX request; data is stored in the session until final confirmation. After confirmation, a record is created in b_vendor_appt_appointment and notifications are sent.
Double-Booking Prevention
Between "the user selected a slot" and "the user confirmed" some time passes. During this time another user may book the same slot. Solution — a temporary lock:
// When a slot is selected — soft lock for 10 minutes
$lockKey = "appt_lock_{$staffId}_{$date}_{$timeFrom}";
\Bitrix\Main\Application::getInstance()->getManagedCache()->set($lockKey, $userId, 600);
At final save the following is verified: the lock belongs to the current user, plus a transactional check in the database.
CRM Integration
Optionally: when an appointment is created, a lead or contact is automatically created in CRM. If the user already exists in CRM (search by email/phone), the appointment is linked to the existing contact via b_crm_contact. CRM record:
$crmContactId = $this->findOrCreateCrmContact($appointmentData);
\Bitrix\Crm\Activity\Entity\PhoneCallTable::add([
'OWNER_TYPE_ID' => \CCrmOwnerType::Contact,
'OWNER_ID' => $crmContactId,
'SUBJECT' => 'Appointment: ' . $service['NAME'],
'START_TIME' => new DateTime($date . ' ' . $timeFrom),
'END_TIME' => new DateTime($date . ' ' . $timeTo),
'RESPONSIBLE_ID'=> $staff['USER_ID'],
]);
Schedule Management
The specialist can manage their schedule via the personal account or administrative section:
- Change working hours for a specific day
- Close a day entirely (vacation, sick leave)
- View the list of their appointments for the day/week
- Cancel or reschedule an appointment with client notification
Administrative section for managers: consolidated calendar for all specialists, manual appointment creation (for phone inquiries), utilisation statistics.
Notifications
- SMS via gateway (configured in the module) upon creation and one hour before the appointment
- Email with appointment details and a cancellation link
- Notification to the specialist in Bitrix24 (if in use) or by email
Development Timeline
| Stage | Duration |
|---|---|
| Data model, schedules, exceptions | 2 days |
| Slot generation, occupancy check | 2 days |
| Three-step booking widget | 3 days |
| Double-booking prevention | 1 day |
| Specialist personal account | 2 days |
| CRM integration (optional) | 1 day |
| Notifications (email + SMS) | 1 day |
| Testing | 1 day |
Total: 13 working days. SMS gateway is connected separately depending on the provider.







