הזמנת תורים מקוונת: שילוב Bitrix ו-MIS – מ-5,000$

העברה ידנית של תורים מהאתר למערכת הרפואית גוזלת זמן ומובילה לאובדן מטופלים. אנו מפתחים אינטגרציה של 1C-Bitrix עם ה-MIS שלך כך שתזמון והזמנה מקוונת פועלים באופן סינכרוני. הצוות שלנו מספק את הפרויקט במפתח מלא—מבחירת התרחיש ועד ליישום ותמיכה מתמשכת.
השירותים שאנו מציעים
מציג 1 מתוך 1כל 1626 השירותים
הזמנת תורים מקוונת: שילוב Bitrix ו-MIS – מ-5,000$
בינוני
~1-2 שבועות

הכישורים שלנו:

שאלות נפוצות

הזמנת תורים מקוונת: סנכרון Bitrix ו-MIS

אתר המרפאה הפרטית שלך מקבל הזמנות תורים מקוונות מרופאים. ה-MIS — מערכת המידע הרפואי — היא מערכת ההפעלה של המרפאה: לוחות זמנים של רופאים, היסטוריה רפואית, רשומות בריאות אלקטרוניות, חשבונאות שירותים, קופה. MIS — מערכת מידע רפואי. האתגר: הזמנות מהאתר חייבות להופיע אוטומטית בלוח הזמנים של ה-MIS, ומשבצות פנויות חייבות להיות מוצגות באתר בזמן אמת. כל שעת השבתה או העברת נתונים ידנית עולה עד 30% מהמטופלים האבודים — ראינו זאת שוב ושוב.

שוק ה-MIS מגוון: Infoclinic, 1C:Medicine, qMS, Medesk, Renaissance-M, ArchiMed+, Medods — לכל אחת יש API משלה (או אין). ארכיטקטורת האינטגרציה של 1C-Bitrix עם ה-MIS תלויה במערכת הספציפית. אנו מבטיחים בחירת התרחיש האופטימלי ויישום מפתח-ביד עם בדיקות מלאות.

תרחישי אינטגרציה אופייניים

תרחיש A: ה-MIS מספק REST/SOAP API. האתר קורא ישירות ל-API של ה-MIS כדי לקבל לוחות זמנים ולהזמין מטופל. זו האפשרות הנקייה ביותר, אך לא כל מערכות ה-MIS תומכות בה.

תרחיש B: מתווך ביניים. ה-MIS מפרסם את לוח הזמנים למסד נתונים ביניים (PostgreSQL או MySQL), והאתר קורא משם. הזמנה באתר יוצרת בקשה בטבלת ביניים, וה-MIS אוסף אותה באמצעות cron.

תרחיש C: אוטובוס אינטגרציה. למרפאות גדולות עם מספר מערכות MIS ומערכות רבות — שירות אינטגרציה ייעודי (למשל, מבוסס על RabbitMQ או Apache Kafka) שמסנכרן נתונים בין מערכות.

באיזה תרחיש אינטגרציה לבחור?

בחירת התרחיש נקבעת על ידי תקציב, מספר מערכות ודרישות השהיה. להלן השוואה של פרמטרים מרכזיים.

פרמטר REST API מסד נתונים ביניים אוטובוס אינטגרציה
זמן יישום 5–8 שבועות 8–14 שבועות מ-12 שבועות
השהיית נתונים זמן אמת 1–5 דקות זמן אמת
עומס על MIS גבוה נמוך (קריאה בלבד) מאוזן
סבילות לתקלות תלוי ב-MIS גבוהה (מטמון ב-DB) גבוהה (תור)

REST API מהיר פי 2–3 ליישום מאשר מסד נתונים ביניים ומספק נתונים בזמן אמת, אך דורש נקודת קצה יציבה. מסד הנתונים הביניים מתאים ל-MIS ללא API או עם מגבלות קפדניות. אוטובוס האינטגרציה מיועד לנופים מורכבים.

מדוע אינטגרציית REST API היא אופטימלית?

REST API היא שיטת האינטגרציה המהירה והשקופה ביותר. ב-90% מהמקרים אנו משתמשים בה: הלקוח מקבל נתונים בזמן אמת, וקוד הבסיס נשאר נקי. להלן דוגמת יישום עבור Medesk — אחת ממערכות ה-MIS הפופולריות.

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,
            '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 של ה-MIS בכל ביקור בדף רופא היא רעיון רע: ה-MIS יכול להיות איטי או בעל מגבלות בקשות (למשל, 100 בקשות לדקה). שמירת מטמון מפחיתה את העומס על ה-MIS פי 10–20 ומאיצה את טעינת העמוד ל-200 אלפיות השנייה. פרטי יישום:

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}");
        // Сохраняем запись в Битрикс
        $this->saveAppointmentInBitrix($result, $patientData);
        return $result;
    }
}

אחסון הזמנות ב-Bitrix

אנו משכפלים הזמנות ב-Bitrix — להיסטוריה, הודעות ותפעול ללא ה-MIS כשהוא לא זמין:

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 ואימייל דרך Bitrix. תזכורות 24 שעות ושעתיים לפני התור. התזכורות מיושמות באמצעות סוכן Bitrix שבודק הזמנות כל שעה:

function SendMisAppointmentReminders(): string {
    $now = new \Bitrix\Main\Type\DateTime();
    $in24h = (new \DateTime())->modify('+24 hours');
    $in2h = (new \DateTime())->modify('+2 hours');
    $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__ . '();';
}

טיפול בשגיאות MIS

ה-MIS עלול להיות לא זמין (תחזוקה, בעיות שרת). האסטרטגיה שלנו: אם ה-MIS לא נגיש, אנו שומרים את הבקשה בטבלת 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, '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 ?? []; } } עם סטטוס 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}"); // Сохраняем запись в Битрикс $this->saveAppointmentInBitrix($result, $patientData); return $result; } } , ומציגים למטופל "ההזמנה התקבלה, ניצור קשר לאישור." סוכן מנסה לשלוח רשומות ממתינות ל-MIS כל 5 דקות. לאחר כשלונות חוזרים, הרשומה מסומנת 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'), ]; } } — נציג יוצר קשר עם המטופל. אנו מיישמים מנגנון זה בכל פרויקט ומבטיחים אפס אובדן בקשות.

כיצד להבטיח אפס בקשות אבודות?

אם ה-MIS לא זמין, הבקשה נשמרת בטבלת function SendMisAppointmentReminders(): string { $now = new \Bitrix\Main\Type\DateTime(); $in24h = (new \DateTime())->modify('+24 hours'); $in2h = (new \DateTime())->modify('+2 hours'); $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. סוכן מנסה שוב כל 5 דקות. לאחר 10 ניסיונות כושלים, הסטטוס משתנה ל-pending, ונציג יוצר קשר עם המטופל. תכנית זו עובדת בכל הפרויקטים ומבטלת אובדן בקשות.

מה כלול בעבודה

  • ניתוח תיעוד ה-API הספציפי של ה-MIS ובחירת תרחיש
  • פיתוח לקוח PHP API עם טיפול בשגיאות וניסיונות חוזרים
  • שמירת מטמון לוח זמנים עם פסילה בעת הזמנה
  • רכיב הזמנת תורים מותאם אישית באתר (מותאם לעיצוב המרפאה)
  • טבלת הזמנות ב-Bitrix עם סנכרון סטטוסים
  • הגדרת הודעות SMS/אימייל (אישור + תזכורות)
  • ארגון תור ממתין לבקשות כשה-MIS לא זמין
  • בדיקות עומס וסבילות לתקלות
  • תיעוד תפעולי והדרכת מנהלים

כיצד אנו משלבים MIS ב-5 שלבים

  1. ניתוח API של ה-MIS והסכמת תרחיש (1–2 שבועות).
  2. פיתוח API ללקוח ואחסון גיבוי (3–6 שבועות).
  3. שילוב רכיב ההזמנה באתר (1–2 שבועות).
  4. הגדרת הודעות ותור שגיאות (שבוע אחד).
  5. בדיקות עומס והדרכת צוות (1–2 שבועות).

לוחות זמנים: מ-5 עד 14 שבועות בהתאם למורכבות. עלויות האינטגרציה מתחילות ב-$5,000; פרויקטים אופייניים נעים בין $5,000–$15,000. מרפאות חוסכות עד 30% מזמן הניהול ומבטלות שגיאות הזנת נתונים ידניות. הזמינו אינטגרציה עם אחריות לאפס אובדן — המומחים המוסמכים שלנו עם 10 שנות ניסיון יבחרו את הפתרון הנכון.

שלב משך
ניתוח ועיצוב 1–2 שבועות
פיתוח ובדיקות 3–6 שבועות
יישום והדרכה 1–2 שבועות
תמיכה באחריות חודש אחד לאחר ההשקה

קבלו ייעוץ והערכת פרויקט — נבחר את תרחיש האינטגרציה האופטימלי ונציע לוחות זמנים.