פיתוח מערכת הזמנת שירותים על 1C-Bitrix

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

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

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1466
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1019
  • פיתוח מבוסס Bitrix, Bitrix24, 1C לחברה פיתוח ווידג'ט להזמנת תורים אונליין למרכז רפואי
    פיתוח מבוסס Bitrix, Bitrix24, 1C לחברה פיתוח ווידג'ט להזמנת תורים אונליין למרכז רפואי
    764
  • פיתוח על בסיס 1C Enterprise עבור MIRSANBEL
    פיתוח על בסיס 1C Enterprise עבור MIRSANBEL
    882
  • פיתוח אתר על CRM Bitrix24 עבור DOLBIMBY
    פיתוח אתר על CRM Bitrix24 עבור DOLBIMBY
    811
  • פיתוח על בסיס Bitrix24 עבור חברת TECHNOTORGKOMPLEKS
    פיתוח על בסיס Bitrix24 עבור חברת TECHNOTORGKOMPLEKS
    1167

פיתוח מערכת הזמנת שירותים על 1C-Bitrix

תארו לעצמכם: לקוח מבקר באתר שלכם, בוחר מומחה, רואה זמנים פנויים, מזמין — ורק לאחר התשלום מגלה שהמשבצת כבר תפוסה על ידי מישהו אחר. ב-Bitrix אין פונקציונליות מובנית לשירותים עם משבצות זמן. מודול המסחר האלקטרוני עוסק במוצרים לפי כמות. שירותים דורשים לוגיקה שונה: משך, מומחים, לוחות זמנים. ללא טיפול בכך, מקבלים תנאי מרוץ (race conditions), הזמנות כפולות ולקוחות אבודים. תכננו ארכיטקטורה שפותר את הבעיות הללו עם ערבויות לשלמות נתונים. נבחן את הפרויקט שלכם תוך יום אחד — צרו קשר לייעוץ.

מדוע מודול מסחר אלקטרוני רגיל לא עובד להזמנת שירותים

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

מודל נתונים: לוח זמנים ומשבצות

הליבה של המערכת היא אינפובלוק לוח זמנים. אנו משתמשים בשני אינפובלוקים וטבלת הזמנות מקשרת. אינפובלוק "שירותים" (SERVICES_IBLOCK_ID):

  • מאפיינים: DURATION (משך בדקות), PRICE, MAX_CAPACITY (מפגשים קבוצתיים עד 20 איש), SPECIALIST_ID (קישור למומחה)

אינפובלוק "לוח זמנים" (SCHEDULE_IBLOCK_ID):

  • SERVICE_ID, SPECIALIST_ID, DATE_FROM, DATE_TO (מאפייני תאריך/שעה), STATUS (free/booked/blocked), BOOKING_ID

טבלת הזמנות (highload-block):

CREATE TABLE bookings ( ID INT AUTO_INCREMENT PRIMARY KEY, SLOT_ID INT NOT NULL, USER_ID INT, CLIENT_NAME VARCHAR(255), CLIENT_PHONE VARCHAR(20), CLIENT_EMAIL VARCHAR(255), STATUS ENUM('pending','confirmed','cancelled','completed') DEFAULT 'pending', COMMENT TEXT, CREATED_AT DATETIME, UPDATED_AT DATETIME, INDEX (SLOT_ID), INDEX (STATUS) ); 

כיצד נוצרות משבצות?

משבצות נוצרות על בסיס תבניות שעות העבודה של המומחה. אנו שומרים לוח זמנים שבועי ומייצרים משבצות אוטומטית ל-4–8 שבועות קדימה. אנו מעבדים עד 10,000 משבצות בריצת סוכן אחת.

class SlotGenerator { public function generateForSpecialist(int $specialistId, \DateTime $from, \DateTime $to): void { $schedule = $this->getWeeklySchedule($specialistId); $serviceDuration = $this->getServiceDuration($specialistId); $current = clone $from; while ($current <= $to) { $dayOfWeek = (int)$current->format('N'); $daySlots = $schedule[$dayOfWeek] ?? []; foreach ($daySlots as $timeRange) { [$start, $end] = explode('-', $timeRange); $this->createSlotsBetween($specialistId, $current, $start, $end, $serviceDuration); } $current->modify('+1 day'); } } } 

כל משבצת היא אלמנט אינפובלוק עם סטטוס CREATE TABLE bookings ( ID INT AUTO_INCREMENT PRIMARY KEY, SLOT_ID INT NOT NULL, USER_ID INT, CLIENT_NAME VARCHAR(255), CLIENT_PHONE VARCHAR(20), CLIENT_EMAIL VARCHAR(255), STATUS ENUM('pending','confirmed','cancelled','completed') DEFAULT 'pending', COMMENT TEXT, CREATED_AT DATETIME, UPDATED_AT DATETIME, INDEX (SLOT_ID), INDEX (STATUS) ); . בעת הזמנה, הוא משתנה ל-class SlotGenerator { public function generateForSpecialist(int $specialistId, \DateTime $from, \DateTime $to): void { $schedule = $this->getWeeklySchedule($specialistId); $serviceDuration = $this->getServiceDuration($specialistId); $current = clone $from; while ($current <= $to) { $dayOfWeek = (int)$current->format('N'); $daySlots = $schedule[$dayOfWeek] ?? []; foreach ($daySlots as $timeRange) { [$start, $end] = explode('-', $timeRange); $this->createSlotsBetween($specialistId, $current, $start, $end, $serviceDuration); } $current->modify('+1 day'); } } } ; בעת ביטול, חוזר ל-free. עבור שירותים קבוצתיים, הקיבולת מנוהלת בנפרד: אם booked > 1, המשבצת יכולה להיות מוזמנת חלקית.

ווידג'ט בחירת זמן: לוגיקת צד לקוח

המשתמש בוחר שירות → מומחה → תאריך → שעה. כל שלב הוא בקשת AJAX לבקר:

class BookingController extends \CBitrixComponent { public function getAvailableSlots(int $specialistId, string $date): array { $dateFrom = new \Bitrix\Main\Type\DateTime($date . ' 00:00:00'); $dateTo = new \Bitrix\Main\Type\DateTime($date . ' 23:59:59'); $result = \Bitrix\Iblock\ElementTable::getList([ 'filter' => [ 'IBLOCK_ID' => SCHEDULE_IBLOCK_ID, '=PROPERTY_SPECIALIST_ID' => $specialistId, '>=PROPERTY_DATE_FROM' => $dateFrom, '<=PROPERTY_DATE_FROM' => $dateTo, '=PROPERTY_STATUS' => 'free', '=ACTIVE' => 'Y', ], 'select' => ['ID', 'PROPERTY_DATE_FROM', 'PROPERTY_DATE_TO'], 'order' => ['PROPERTY_DATE_FROM' => 'ASC'], ]); } } 

בצד הלקוח — לוח שנה (FullCalendar או React מותאם) המדגיש ימים פנויים. משבצות הזמן מתעדכנות דינמית ללא טעינת עמוד מחדש.

כיצד להימנע מתנאי מרוץ במהלך ההזמנה?

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

public function bookSlot(int $slotId, array $clientData): BookingResult { $connection = \Bitrix\Main\Application::getConnection(); $connection->startTransaction(); try { $slot = $connection->query( "SELECT * FROM b_iblock_element_property WHERE IBLOCK_ELEMENT_ID = {$slotId} AND IBLOCK_PROPERTY_ID = " . STATUS_PROP_ID . " FOR UPDATE" )->fetch(); if ($slot['VALUE'] !== 'free') { $connection->rollbackTransaction(); return BookingResult::slotTaken(); } $this->updateSlotStatus($slotId, 'booked'); $bookingId = $this->createBooking($slotId, $clientData); $connection->commitTransaction(); return BookingResult::success($bookingId); } catch (\Exception $e) { $connection->rollbackTransaction(); throw $e; } } 

גישה זו אמינה פי 3 מאשר בדיקת סטטוס ברמת PHP ללא נעילה. נעילה אופטימית היא תבנית סטנדרטית להתמודדות עם תנאי מרוץ במערכות בעומס גבוה. אנו מבטיחים שגם בעומסי שיא, לא תאבדו אף הזמנה אחת.

הודעות ותזכורות

מיד לאחר ההזמנה — הודעה ללקוח ולמומחה. ב-24 ושעתיים — תזכורות. סוכנים:

\CAgent::AddAgent( '\BookingModule\ReminderAgent::send(' . $bookingId . ');', 'my_booking_module', 'N', 0, '', 'Y', ConvertTimeStamp($bookingDateTs - 86400, 'FULL') ); 

ערוצים: דוא"ל (באמצעות free), SMS, בוט טלגרם. תמיכה בכל השירותים הפופולריים: ספקי SMS דרך HTTP, Telegram Bot API.

שילוב תשלומים (אופציונלי)

לתשלום מראש, אנו יוצרים הזמנה בעגלה: מאתחלים MAX_CAPACITY, מוסיפים שורת פריט עם השירות, מקשרים את ההזמנה להזמנה דרך שדה class BookingController extends \CBitrixComponent { public function getAvailableSlots(int $specialistId, string $date): array { $dateFrom = new \Bitrix\Main\Type\DateTime($date . ' 00:00:00'); $dateTo = new \Bitrix\Main\Type\DateTime($date . ' 23:59:59'); $result = \Bitrix\Iblock\ElementTable::getList([ 'filter' => [ 'IBLOCK_ID' => SCHEDULE_IBLOCK_ID, '=PROPERTY_SPECIALIST_ID' => $specialistId, '>=PROPERTY_DATE_FROM' => $dateFrom, '<=PROPERTY_DATE_FROM' => $dateTo, '=PROPERTY_STATUS' => 'free', '=ACTIVE' => 'Y', ], 'select' => ['ID', 'PROPERTY_DATE_FROM', 'PROPERTY_DATE_TO'], 'order' => ['PROPERTY_DATE_FROM' => 'ASC'], ]); } } . לאחר התשלום, מטפל public function bookSlot(int $slotId, array $clientData): BookingResult { $connection = \Bitrix\Main\Application::getConnection(); $connection->startTransaction(); try { $slot = $connection->query( "SELECT * FROM b_iblock_element_property WHERE IBLOCK_ELEMENT_ID = {$slotId} AND IBLOCK_PROPERTY_ID = " . STATUS_PROP_ID . " FOR UPDATE" )->fetch(); if ($slot['VALUE'] !== 'free') { $connection->rollbackTransaction(); return BookingResult::slotTaken(); } $this->updateSlotStatus($slotId, 'booked'); $bookingId = $this->createBooking($slotId, $clientData); $connection->commitTransaction(); return BookingResult::success($bookingId); } catch (\Exception $e) { $connection->rollbackTransaction(); throw $e; } } מאשר את ההזמנה. זה מאפשר שימוש בתהליך התשלום הסטנדרטי של Bitrix ללא עקיפות מיותרות. נתמכים: YooKassa, Sber, ATOL Online.

ממשק ניהול

עמוד ב-\CAgent::AddAgent( '\BookingModule\ReminderAgent::send(' . $bookingId . ');', 'my_booking_module', 'N', 0, '', 'Y', ConvertTimeStamp($bookingDateTs - 86400, 'FULL') ); עם:

  • תצוגת לוח שנה של כל ההזמנות
  • חסימת משבצות ידנית (חופשה, הפסקת צהריים)
  • אישור/ביטול ידני עם הודעה ללקוח
  • ייצוא CSV

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

אנו מספקים לא רק קוד אלא גם סט מלא של תיעוד וכלים:

מה כלול פרטים
מודל נתונים ועיצוב אינפובלוקים, highload-block, תרחישים
מחולל משבצות סוכן, תבניות לוח זמנים
בקרי AJAX API לבחירת משבצות, הזמנה
ווידג'ט צד לקוח לוח שנה, בחירת מומחה/זמן
הודעות דוא"ל, SMS, טלגרם, תזכורות
פאנל ניהול ניהול לוח זמנים, צפייה בהזמנות
שילוב תשלומים תשלום מראש דרך העגלה (אופציונלי)
תיעוד תיאור API, מדריך התקנה
הדרכה סמינר מקוון של שעתיים למנהלים
תמיכה טכנית 30 יום לאחר ההשקה

מדריך יישום שלב אחר שלב

  1. התקינו את המודול דרך Marketplace או הניחו ידנית את קבצי הרכיב.
  2. הגדירו אינפובלוקים של שירותים ולוח זמנים, ייבאו מומחים.
  3. צרו תבניות שעות עבודה והריצו את סוכן יצירת המשבצות.
  4. הניחו את רכיב CEvent::Send על העמוד עם פרמטרים.
  5. הגדירו אירועי דוא"ל להודעות וחברו שער SMS (אופציונלי).
  6. בצעו הזמנת בדיקה וודאו את עיבוד התשלום.

שלבים ולוח זמנים

שלב תיאור משך
עיצוב מודל נתונים, תרחישים 3–5 ימים
אינפובלוקים ומחולל מבנה, לוח זמנים שבוע
בקרי AJAX API שבוע
ווידג'ט צד לקוח לוח שנה 1–2 שבועות
הודעות דוא"ל, SMS, סוכנים 3–5 ימים
ממשק ניהול ניהול, צפייה שבוע
שילוב תשלומים אופציונלי שבוע

לוח הזמנים הכולל הוא בין 6 ל-10 שבועות בהתאם למורכבות. צרו קשר כדי לברר פרטי פרויקט ולקבל הערכה מדויקת. קבלו ייעוץ — נעזור לתכנן מערכת המותאמת לצרכים שלכם.