הזמנת תורים אונליין: אינטגרציית 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 גבוהה (מאוחסן במסד נתונים) גבוהה (תור)

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}");

        // Сохраняем запись в Bitrix
        $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}"); // Сохраняем запись в Bitrix $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 שבועות
תמיכה באחריות חודש אחד לאחר ההשקה

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