Інтеграція 1С-Бітрікс з медичною інформаційною системою (МІС)
Сайт приватної клініки приймає онлайн-записи до лікарів. МІС (медична інформаційна система) — це операційна система клініки: розклад лікарів, історія хвороби, електронна медкарта, облік послуг, каса. Завдання: запис із сайту має автоматично потрапляти до розкладу МІС, а дані про вільні слоти — відображатися на сайті в реальному часі.
Ринок МІС неоднорідний: Інфоклініка, 1С:Медицина, qMS, Medesk, Ренесанс-М, ArchiMed+, Medods — у кожної свій API (або його відсутність). Архітектура інтеграції залежить від конкретної МІС.
Типові сценарії інтеграції
Сценарій A: МІС надає REST/SOAP API. Сайт безпосередньо звертається до API МІС для отримання розкладу та запису пацієнта. Найчистіший варіант, але не всі МІС його підтримують.
Сценарій B: Проміжний брокер. МІС публікує розклад у проміжній базі (PostgreSQL або MySQL), сайт читає звідти. Запис на сайті створює заявку в проміжній таблиці, МІС забирає її за cron.
Сценарій C: Інтеграційна шина. Для великих клінік із кількома МІС та безліччю систем — окремий інтеграційний сервіс (наприклад, на базі RabbitMQ або Apache Kafka), що синхронізує дані між системами.
Для однієї клініки з однією МІС — сценарій A або B.
Інтеграція через REST API МІС (на прикладі Medesk)
class MedeskApiClient
{
private string $apiKey;
private string $baseUrl = 'https://api.medesk.net/api/v2';
public function getDoctorSchedule(int $doctorId, string $dateFrom, string $dateTo): array
{
return $this->request('GET', '/schedules', [
'doctor_id' => $doctorId,
'from' => $dateFrom, // Y-m-d
'to' => $dateTo,
'include' => 'free_slots',
]);
}
public function createAppointment(array $patientData, int $slotId): array
{
return $this->request('POST', '/appointments', [
'slot_id' => $slotId,
'patient' => [
'first_name' => $patientData['name'],
'last_name' => $patientData['surname'],
'phone' => $patientData['phone'],
'email' => $patientData['email'],
'birth_date' => $patientData['birth_date'],
],
'comment' => $patientData['comment'] ?? '',
'source' => 'website',
]);
}
public function cancelAppointment(int $appointmentId, string $reason = ''): array
{
return $this->request('DELETE', "/appointments/{$appointmentId}", [
'reason' => $reason,
]);
}
private function request(string $method, string $path, array $data = []): array
{
$url = $this->baseUrl . $path;
if ($method === 'GET' && $data) {
$url .= '?' . http_build_query($data);
}
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"Authorization: Bearer {$this->apiKey}",
],
CURLOPT_POSTFIELDS => in_array($method, ['POST', 'PUT', 'PATCH'])
? json_encode($data) : null,
]);
$response = json_decode(curl_exec($ch), true);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
\Bitrix\Main\Diag\Debug::writeToFile(
"MIS API Error {$httpCode}: " . json_encode($response),
'MIS',
'/local/logs/mis-integration.log'
);
throw new \RuntimeException("MIS API error: {$httpCode}");
}
return $response ?? [];
}
}
Кешування розкладу
Пряме звернення до API МІС при кожному відвідуванні сторінки лікаря — погана ідея: МІС може бути повільною або мати обмеження на кількість запитів. Кешуємо розклад:
class DoctorScheduleService
{
private MedeskApiClient $mis;
public function getAvailableSlots(int $doctorId, string $date): array
{
$cacheKey = "doctor_slots_{$doctorId}_{$date}";
$cacheTtl = 180; // 3 хвилини — баланс актуальності та навантаження
$cache = \Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache($cacheTtl, $cacheKey, '/mis/slots/')) {
return $cache->getVars()['slots'];
}
$schedule = $this->mis->getDoctorSchedule($doctorId, $date, $date);
$slots = $this->formatSlots($schedule);
$cache->startDataCache();
$cache->endDataCache(['slots' => $slots]);
return $slots;
}
public function bookSlot(int $slotId, array $patientData): array
{
$result = $this->mis->createAppointment($patientData, $slotId);
// Інвалідуємо кеш розкладу для цього лікаря
$date = date('Y-m-d'); // або дата слоту
$doctorId = $this->getSlotDoctorId($slotId);
\Bitrix\Main\Data\Cache::clearByTag("doctor_slots_{$doctorId}_{$date}");
// Зберігаємо запис у 1С-Бітрікс
$this->saveAppointmentInBitrix($result, $patientData);
return $result;
}
}
Зберігання записів у 1С-Бітрікс
Записи дублюємо в 1С-Бітрікс — для історії, сповіщень та роботи без МІС при її недоступності:
class AppointmentTable extends \Bitrix\Main\ORM\Data\DataManager
{
public static function getTableName(): string { return 'local_mis_appointments'; }
public static function getMap(): array
{
return [
new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
new \Bitrix\Main\ORM\Fields\IntegerField('USER_ID'),
new \Bitrix\Main\ORM\Fields\IntegerField('MIS_APPOINTMENT_ID'),
new \Bitrix\Main\ORM\Fields\IntegerField('DOCTOR_ID'),
new \Bitrix\Main\ORM\Fields\DatetimeField('APPOINTMENT_TIME'),
new \Bitrix\Main\ORM\Fields\StringField('STATUS'), // booked|confirmed|cancelled|completed
new \Bitrix\Main\ORM\Fields\StringField('SERVICE_NAME'),
new \Bitrix\Main\ORM\Fields\StringField('PATIENT_PHONE'),
new \Bitrix\Main\ORM\Fields\DatetimeField('CREATED_AT'),
];
}
}
Сповіщення пацієнту
Після запису — SMS та email-підтвердження через 1С-Бітрікс. За 24 години та за 2 години до прийому — нагадування. Нагадування реалізуються через агент 1С-Бітрікс, що щогодини перевіряє записи:
function SendMisAppointmentReminders(): string
{
$now = new \Bitrix\Main\Type\DateTime();
$in24h = (new \DateTime())->modify('+24 hours');
$in2h = (new \DateTime())->modify('+2 hours');
// Записи через 24 години без надісланого нагадування
$appointments = AppointmentTable::getList([
'filter' => [
'STATUS' => 'booked',
'>=APPOINTMENT_TIME' => \Bitrix\Main\Type\DateTime::createFromTimestamp($in2h->getTimestamp()),
'<=APPOINTMENT_TIME' => \Bitrix\Main\Type\DateTime::createFromTimestamp($in24h->getTimestamp()),
'REMINDER_24H_SENT' => 'N',
],
]);
while ($row = $appointments->fetch()) {
SmsService::send($row['PATIENT_PHONE'],
"Нагадуємо про запис до лікаря " . date('d.m.Y H:i', strtotime($row['APPOINTMENT_TIME']))
);
AppointmentTable::update($row['ID'], ['REMINDER_24H_SENT' => 'Y']);
}
return __FUNCTION__ . '();';
}
Обробка помилок МІС
МІС може бути недоступна (технічні роботи, проблеми з сервером). Стратегія: якщо МІС недоступна — зберігаємо заявку в таблицю local_mis_pending_appointments зі статусом pending, відображаємо пацієнту «Запис прийнято, ми зв'яжемося з вами для підтвердження». Агент раз на 5 хвилин намагається відправити pending-записи в МІС.
Склад робіт
- Аналіз API конкретної МІС (різний для кожного вендора)
- PHP-клієнт API МІС з обробкою помилок
- Кешування розкладу, інвалідація при записі
- Компонент онлайн-запису на сайті
- Таблиця записів у 1С-Бітрікс, SMS/email сповіщення
- Черга pending-записів при недоступності МІС
Терміни: 5–8 тижнів за наявності задокументованого API МІС. 8–14 тижнів при інтеграції через проміжну базу або розробці API на стороні МІС.







