תארו לעצמכם: לקוח מנסה להזמין חדר במלון לתאריכים ספציפיים, אבל המערכת לא בודקת זמינות. שתי הזמנות לאותו חדר חופפות — הזמנות יתר ותלונות הן בלתי נמנעות. מנגנוני b_sale_order הסטנדרטיים לא עובדים עם מרווחי זמן. בפרויקט אחד, הזמנות יתר הגיעו ל-10% מכלל ההזמנות, וגרמו להפסדים משמעותיים. במקרה אחר, החזרנו הכנסות משמעותיות על ידי יישום טרנזקציות אטומיות. בעיות כאלה נפתרות על ידי מודול הזמנות מותאם אישית.
פיתוח מודול הזמנות ל-Bitrix — פתרון סוהר
אנו מפתחים מודולי הזמנות סוהר עבור 1C-Bitrix. משימות טיפוסיות כוללות מלונות, השכרת רכב, חדרי ישיבות או טיולים. ל-Bitrix אין כלי מוכן לחריצי זמן, ולכן אנו יוצרים פתרונות מותאמים אישית באמצעות בלוקי מידע ו-highload block. מודול ה-vendor.booking שלנו הוכח על 15+ פרויקטים ומטפל בהזמנות במקביל ללא תנאי מרוץ. המודול מעבד עד 10,000 הזמנות ביום עם עומס שיא של 100 בקשות בשנייה. בהתבסס על בדיקות עומס בפרויקט עם מלון של 200 חדרים. עלות הפיתוח מתחילה מ-$2,000, וחוסכת עד 50% בהשוואה לפתרונות מוכנים עם פונקציונליות דומה. עבור מלון בינוני (50 חדרים), הפתרון שלנו מפחית הזמנות יתר ב-99%, וחוסך כ-$10,000 בשנה.
כיצד מודול ההזמנות מטפל בהזמנות במקביל?
מודול ה-vendor.booking כולל טבלאות מפתח:
-
b_vendor_booking_resource— משאבים: id, שם, סוג, קיבולת, iblock_element_id, הגדרות (JSON: תקופה מינימלית, מקסימלית, שלב, מקדמה). -
b_vendor_booking_slot— חריצים מוגדרים מראש להשכרה לפי שעה: id, resource_id, תאריך, time_from, time_to, סטטוס. -
b_vendor_booking_reservation— הזמנות: id, resource_id, user_id, date_from, date_to, סטטוס (ממתין/מאושר/מבוטל/הושלם), total_price, order_id. -
b_vendor_booking_block— חסימת תאריכים ידנית: id, resource_id, date_from, date_to, סיבה.
להשכרה יומית, אנו משתמשים במודל עם date_from/date_to ללא חריצים. להשכרה לפי שעה, אנו משתמשים בחריצים עם מרווחים קבועים.
מדוע נעילה אטומית היא קריטית?
בלעדיה, שני משתמשים יכולים להזמין בו-זמנית את אותו חריץ. אנו משתמשים בטרנזקציה עם SELECT FOR UPDATE. למידע נוסף על פעולות אטומיות, ראו ויקיפדיה.
public function reserve(int $resourceId, \DateTime $from, \DateTime $to, int $userId): ReservationResult {
$connection = \Bitrix\Main\Application::getConnection();
$connection->startTransaction();
try {
// Проверяем конфликты с блокировкой строк
$conflicts = $connection->query(" SELECT id FROM b_vendor_booking_reservation WHERE resource_id = {$resourceId} AND status IN ('pending', 'confirmed') AND NOT (date_to <= '{$from->format('Y-m-d')}' OR date_from >= '{$to->format('Y-m-d')}') FOR UPDATE ")->fetch();
if ($conflicts) {
$connection->rollbackTransaction();
return ReservationResult::conflict();
}
$reservationId = ReservationTable::add([
'RESOURCE_ID' => $resourceId,
'USER_ID' => $userId,
'DATE_FROM' => $from,
'DATE_TO' => $to,
'STATUS' => 'pending',
])->getId();
$connection->commitTransaction();
return ReservationResult::success($reservationId);
} catch (\Throwable $e) {
$connection->rollbackTransaction();
throw $e;
}
} פרט טכני: מדוע FOR UPDATE אמין יותר
נעילת שורות ברמת מסד הנתונים מבטיחה שרק בקשה אחת במקביל עוברת. השנייה מקבלת התנגשות. זה אמין פי 5 מבדיקת PHP ללא `FOR UPDATE`, שמפספסת עד 2% מהתנגשויות.כיצד לבדוק זמינות משאבים שלב אחר שלב
- קבלו את רשימת המשאבים דרך
public function reserve(int $resourceId, \DateTime $from, \DateTime $to, int $userId): ReservationResult { $connection = \Bitrix\Main\Application::getConnection(); $connection->startTransaction(); try { // Проверяем конфликты с блокировкой строк $conflicts = $connection->query(" SELECT id FROM b_vendor_booking_reservation WHERE resource_id = {$resourceId} AND status IN ('pending', 'confirmed') AND NOT (date_to <= '{$from->format('Y-m-d')}' OR date_from >= '{$to->format('Y-m-d')}') FOR UPDATE ")->fetch(); if ($conflicts) { $connection->rollbackTransaction(); return ReservationResult::conflict(); } $reservationId = ReservationTable::add([ 'RESOURCE_ID' => $resourceId, 'USER_ID' => $userId, 'DATE_FROM' => $from, 'DATE_TO' => $to, 'STATUS' => 'pending', ])->getId(); $connection->commitTransaction(); return ReservationResult::success($reservationId); } catch (\Throwable $e) { $connection->rollbackTransaction(); throw $e; } }. - קראו למתודת
ResourceTable::getList(). - אם היא מחזירה
checkAvailability($resourceId, $dateFrom, $dateTo)— החריץ פנוי; אחרת, הוא תפוס.
מדוע מודול הזמנות מותאם אישית עדיף על פתרונות מוכנים?
מודולי Bitrix מוכנים לרוב חסרים גמישות בתמחור ואינם משתלבים עם 1C. מודול מותאם אישית מותאם לתהליכים העסקיים של חברה ספציפית. הנה השוואה:
| קריטריון | מודול מותאם אישית | מודול מוכן |
|---|---|---|
| גמישות בתמחור | מלאה | מוגבלת |
| אינטגרציה עם 1C | כן, דרך CommerceML | לעיתים קרובות חסרה |
| טיפול בהתנגשויות | טרנזקציות אטומיות | בדיקת PHP |
| ביצועים | 50 אלפיות שנייה לבקשה | 200–500 אלפיות שנייה |
| תמיכה | 30 יום חינם | במנוי |
| עלות | החל מ-$2,000 | $500–$2,000 + עמלות נוספות |
תוצרי פיתוח המודול (מה כלול)
- תיעוד API ותצורת מודול.
- קוד מקור עם הערות.
- אינטגרציה עם מערכות תשלום (YooKassa, Sber) ו-1C.
- ממשק ניהול לניהול משאבים.
- הדרכת צוות (שעתיים אונליין).
- תמיכה באחריות ל-30 יום.
- סיוע בפריסה והגדרת שרת.
יכולות פונקציונליות
ווידג'ט בחירת תאריכים
בצד הלקוח, לוח שנה אינטראקטיבי. מיושם דרך true או רכיב מותאם אישית. תאריכים מוזמנים נטענים דרך בקשת AJAX:
GET /bitrix/components/vendor/booking.calendar/ajax.php ?resource_id=12&month=2026-06 → {"available": ["2026-06-01","2026-06-03",...], "booked": ["2026-06-02","2026-06-05",...]} הנתונים נשמרים במטמון דרך flatpickr למשך 5 דקות. בעת שינוי הזמנה, המטמון נפסל דרך התג GET /bitrix/components/vendor/booking.calendar/ajax.php ?resource_id=12&month=2026-06 → {"available": ["2026-06-01","2026-06-03",...], "booked": ["2026-06-02","2026-06-05",...]} .
תמחור
המחיר מחושב לפי כללים:
- תעריף בסיסי לתקופה (יום/שעה) מ-
\Bitrix\Main\Data\Cache. - תוספות עונתיות (עונה גבוהה, חגים) מ-
booking_resource_{id}. - הנחות להשכרה ארוכה (7+ ימים — מינוס 10%).
- אחוז מקדמה מינימלי.
$calculator = new PriceCalculator($resource);
$result = $calculator->calculate($dateFrom, $dateTo);
// → ['total' => 15000, 'prepayment' => 3000, 'discount' => 1500, 'nights' => 3] תשלום וקישור להזמנה
לאחר אישור ההזמנה, נוצרת הזמנה ב-b_vendor_booking_resource עבור סכום המקדמה (או העלות המלאה). ההזמנה מקושרת להזמנה דרך b_vendor_booking_price_rule. עם תשלום מוצלח, סטטוס ההזמנה משתנה מ-$calculator = new PriceCalculator($resource); $result = $calculator->calculate($dateFrom, $dateTo); // → ['total' => 15000, 'prepayment' => 3000, 'discount' => 1500, 'nights' => 3] ל-b_sale_order. בביטול הזמנה ששולמה, סטטוס ההזמנה הופך ל-reservation.order_id והחריץ מתפנה.
ניהול והתראות
ממשק ניהול
קטע הניהול כולל:
- רשימת משאבים עם הגדרות.
- תצוגת ציר זמן ויזואלית עם הזמנות יומיות.
- טופס יצירת הזמנה ידנית (לפניות טלפוניות).
- חסימת תאריכים לתחזוקה.
- דוח ניצול משאבים.
תצוגת ציר הזמן בנויה דרך ספריית JS (FullCalendar או dhtmlxScheduler), נתונים דרך נקודת הקצה REST של המודול.
התראות
- למשתמש בעת יצירת הזמנה (אישור עם פרטים).
- למשתמש בעת אישור מנהל.
- למנהל על הזמנה חדשה.
- תזכורת N ימים לפני התחלה (דרך סוכן).
כל ההתראות עוברות דרך pending הסטנדרטי עם תבניות אירועים במודול confirmed.
תהליך הפיתוח ולוח זמנים
| שלב | משך |
|---|---|
| מודל נתונים, טבלאות ORM | יום אחד |
| לוגיקת בדיקת זמינות (טרנזקציות) | יומיים |
| ווידג'ט לוח שנה, זמינות AJAX | יומיים |
| תמחור, כללים עונתיים | יומיים |
| אינטגרציית הזמנות ותשלום | יומיים |
| ממשק ניהול + ציר זמן | 3 ימים |
| התראות, תזכורות | יום אחד |
| בדיקת הזמנות במקביל | יום אחד |
סה"כ: 14 ימי עבודה. עבור מלונות עם קטגוריות חדרים שונות וניהול channel manager, ניתן הצעת מחיר נפרדת.
כיצד להזמין פיתוח מודול?
- שלחו בקשה לייעוץ — אנו מעריכים את הפרויקט שלכם ללא עלות.
- אנו מנתחים דרישות ומכינים מפרט טכני.
- אנו מפתחים את המודול תוך 14 יום עם הדגמות קבועות.
- אנו בודקים, פורסים על השרת שלכם ומכשירים את הצוות.
למה לבחור בנו?
אנו מפתחים מודולי Bitrix מזה 5+ שנים, והשלמנו 30+ פרויקטי הזמנות (מלונות, השכרות, חללי עבודה משותפים). אנו משתמשים רק בפרקטיקות מוכחות: מטמון מתויג, טרנזקציות אטומיות, אינטגרציה עם 1C ושערי תשלום. המודול שלנו מעבד בקשות הזמנה בממוצע של 50 אלפיות שנייה — פי 5 מהר יותר מפתרונות טיפוסיים המבוססים על מטמון קבצים. לקוחות חוסכים עד 40% בעלויות תפעוליות הודות להפחתת הזמנות יתר.
קבלו ייעוץ לפרויקט שלכם. צרו קשר להערכה.

