אתר מלון על 1C-Bitrix: הזמנות אונליין ושילוב PMS

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

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

שאלות נפוצות

אתר מלון שונה מקטלוג רגיל בכך שהמבקרים בוחרים משבצת זמן, לא מוצר. החדר עצמו הוא קבוצת מאפיינים (שטח, קיבולת, נוף). אבל בלי תאריכים זמינים, זה כרטיס מת. כל הפרויקט סובב סביב לוח הזמינות ומנגנון ההזמנה, לא סביב עיצוב יפה. הבעיה: המבקרים רואים תמונות יפות, אבל כשהם מנסים להזמין — לוח השנה לא מעודכן או שהמחיר לא תואם לעונה. או שאין אינטגרציה עם Booking.com, והמלון מקבל הזמנות כפולות. אנחנו פותרים את הבעיות האלה ברמת הארכיטקטורה: מנוע הזמנה על Highload-blocks, תעריפים עונתיים, סנכרון PMS.

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

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

אחסון הזמינות — Highload-block RoomInventory. כל שורה היא לילה אחד לחדר פיזי אחד.

שדה סוג תיאור
UF_DATE date תאריך (לדוגמה, 2025-07-15 — לילה מ-15 ביולי עד 16 ביולי)
UF_ROOM_ID integer מזהה החדר הפיזי
UF_ROOM_TYPE_ID integer מזהה סוג החדר
UF_STATUS integer 0 = פנוי, 1 = מוזמן, 2 = חסום, 3 = מאוכלס
UF_BOOKING_ID integer מזהה הזמנה (ממודול sale)
UF_RATE float תעריף ללילה זה (כולל התאמה עונתית)

Highload-block הוא מעטפת ORM מעל טבלה עם API אוטומטי. עם 100 חדרים ואופק של 365 יום — 36,500 שורות. אינדקסים נדרשים: מורכבים על (UF_DATE, UF_ROOM_TYPE_ID, UF_STATUS) ו-(UF_BOOKING_ID).

אלגוריתם לבדיקת זמינות. האורח מזין check_in, check_out, guests. המערכת מוצאת סוגי חדרים עם לפחות חדר פיזי אחד פנוי לכל הלילות.

public function getAvailableRoomTypes( \Bitrix\Main\Type\Date $checkIn, \Bitrix\Main\Type\Date $checkOut, int $guests ): array {
    $nights = $checkOut->getDiff($checkIn)->days;
    $dates = [];
    for ($i = 0; $i < $nights; $i++) {
        $d = clone $checkIn;
        $d->add(new \DateInterval("P{$i}D"));
        $dates[] = $d->format('Y-m-d');
    }
    // Находим номера, занятые хотя бы в одну из ночей
    $busyRooms = RoomInventoryTable::getList([
        'select' => ['UF_ROOM_ID'],
        'filter' => [
            'UF_DATE' => $dates,
            '!UF_STATUS' => 0,
        ],
        'group' => ['UF_ROOM_ID'],
    ])->fetchAll();
    $busyRoomIds = array_column($busyRooms, 'UF_ROOM_ID');
    // Далее — исключаем занятые номера и фильтруем по вместимости
}

הגישה באמצעות public function getAvailableRoomTypes( \Bitrix\Main\Type\Date $checkIn, \Bitrix\Main\Type\Date $checkOut, int $guests ): array { $nights = $checkOut->getDiff($checkIn)->days; $dates = []; for ($i = 0; $i < $nights; $i++) { $d = clone $checkIn; $d->add(new \DateInterval("P{$i}D")); $dates[] = $d->format('Y-m-d'); } // Находим номера, занятые хотя бы в одну из ночей $busyRooms = RoomInventoryTable::getList([ 'select' => ['UF_ROOM_ID'], 'filter' => [ 'UF_DATE' => $dates, '!UF_STATUS' => 0, ], 'group' => ['UF_ROOM_ID'], ])->fetchAll(); $busyRoomIds = array_column($busyRooms, 'UF_ROOM_ID'); // Далее — исключаем занятые номера и фильтруем по вместимости } נכונה יותר:

שאילתת SQL לבדיקת זמינות
SELECT UF_ROOM_ID, UF_ROOM_TYPE_ID
FROM hl_room_inventory
WHERE UF_DATE IN ('2025-07-15','2025-07-16','2025-07-17')
  AND UF_STATUS = 0
GROUP BY UF_ROOM_ID, UF_ROOM_TYPE_ID
HAVING COUNT(*) = 3

לוח זמינות בחזית. שני שדות — צ'ק-אין וצ'ק-אאוט. יישום עם flatpickr במצב HAVING COUNT(*) = {$nights}. בעת פתיחה — בקשת AJAX למטריצת זמינות: מערך תאריכים עם דגל "יש חדרים פנויים". נקודת הקצה מחזירה JSON:

{
  "2025-07": {
    "15": {"available": true, "min_rate": 4500},
    "16": {"available": true, "min_rate": 4500},
    "17": {"available": false, "min_rate": null},
    "18": {"available": true, "min_rate": 6200}
  }
}

תאריכים לא זמינים נחסמים בלוח השנה (SELECT UF_ROOM_ID, UF_ROOM_TYPE_ID FROM hl_room_inventory WHERE UF_DATE IN ('2025-07-15','2025-07-16','2025-07-17') AND UF_STATUS = 0 GROUP BY UF_ROOM_ID, UF_ROOM_TYPE_ID HAVING COUNT(*) = 3 ). תעריף מינימלי — בריחוף. שאילתות נשמרות במטמון דרך range עם מפתח { "2025-07": { "15": {"available": true, "min_rate": 4500}, "16": {"available": true, "min_rate": 4500}, "17": {"available": false, "min_rate": null}, "18": {"available": true, "min_rate": 6200} } } .

למה תמחור עונתי מגדיל רווח?

Highload-block disable:

שדה סוג
UF_ROOM_TYPE_ID integer
UF_DATE_FROM date
UF_DATE_TO date
UF_WEEKDAY_RATE float
UF_WEEKEND_RATE float
UF_PRIORITY integer

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

ארכיטקטורת מלאי החדרים

כל סוג חדר הוא אלמנט אינפובלוק "מלאי חדרים". חשוב להפריד בין הסוג (לדוגמה, "זוגי סטנדרטי") לבין חדרים פיזיים (20 חדרים). זו החלטה ארכיטקטונית מרכזית.

מבנה האינפובלוק:

מאפיין סוג מטרה
CAPACITY N (מספר) קיבולת (מיטות עיקריות)
CAPACITY_EXTRA N מיטות נוספות (מתקפלות, עריסה)
AREA N שטח, מ"ר
AMENITIES L (רשימה, מרובה) שירותים: Wi-Fi, מיזוג אוויר, מיני בר, כספת
BED_TYPE L (רשימה) סוג מיטה: זוגית, טווין, קינג
VIEW L (רשימה) נוף: ים, עיר, גן, חצר
FLOOR_RANGE S (מחרוזת) קומות: "3-5"
GALLERY F (קובץ, מרובה) גלריית תמונות של החדר
PANORAMA_URL S קישור לפנורמת 360
ROOM_COUNT N מספר החדרים הפיזיים מסוג זה
MIN_STAY N מספר לילות מינימלי
BASE_RATE N תעריף בסיס ללילה (ללא תוספות עונתיות)

שירותים (AMENITIES) — מאפיין מרובה מסוג "רשימה". לא Highload-block, כי הסט קבוע (30-50 פריטים). בחזית, הערכים ממופים לאייקונים דרך קונפיג.

גלריית תמונות וסיור וירטואלי. מאפיין מרובה מסוג "קובץ". עיבוד — Swiper.js עם טעינה עצלה, תצוגה מקדימה דרך Bitrix\Main\Data\Cache ב-600x400 עם availability_{month}_{year}. לפנורמת 360 — Pannellum.js: הספרייה לוקחת תמונה אקווירקטית ומציגה תצוגה אינטראקטיבית. אחסון — מאפיין מחרוזת RatePlan. Pannellum מאותחל בצד הלקוח:

pannellum.viewer('panorama-container', {
  type: 'equirectangular',
  panorama: roomData.panoramaUrl,
  autoLoad: true,
  compass: true,
  hotSpots: [
    {
      pitch: -5,
      yaw: 120,
      type: 'info',
      text: 'Ванная комната'
    },
    {
      pitch: 0,
      yaw: 240,
      type: 'info',
      text: 'Балкон с видом на море'
    }
  ]
});

נקודות חמות מוגדרות במאפיין JSON באינפובלוק או ב-Highload-block אם יש צורך בפאנל ניהול.

איך סנכרון iCal מונע הזמנות כפולות?

המלון מוכר חדרים באתר ודרך OTAs (Booking.com, Expedia). בלי סנכרון — הזמנות כפולות. Channel Manager מסנכרן זמינות ותעריפים בין PMS, האתר והערוצים.

סנכרון iCal — האפשרות הפשוטה ביותר. Booking.com ו-Airbnb מספקים קבצי CFile::ResizeImageGet(). סוכן Bitrix רץ כל 15 דקות:

  1. מוריד BX_RESIZE_IMAGE_PROPORTIONAL דרך URL (PANORAMA_URL או cURL)
  2. מנתח pannellum.viewer('panorama-container', { type: 'equirectangular', panorama: roomData.panoramaUrl, autoLoad: true, compass: true, hotSpots: [ { pitch: -5, yaw: 120, type: 'info', text: 'Ванная комната' }, { pitch: 0, yaw: 240, type: 'info', text: 'Балкон с видом на море' } ] }); — מחלץ .ics, .ics, file_get_contents
  3. מעדכן VEVENT: DTSTART (חסום)
  4. מייצר DTEND יוצא עם הזמנות מהאתר

מגבלת iCal: אין תעריפים, עד 15 דקות עיכוב. ל-100+ חדרים, יש צורך במחבר API. XML Push / API — דרך REST או SOAP (Booking.com Connectivity API). סנכרון iCal פשוט פי 10 מאינטגרציית API, אבל פחות גמיש.

אינטגרציית PMS. 1C:Hotel — החלפה דרך שירות HTTP. Opera / Fidelio — SOAP עם WSDL. אנחנו מיישמים מחלקת עטיפה מעל SUMMARY עם רישום לוג.

תשלום מקוון ומקדמה. הזמנה דרך מודול RoomInventory. הזמנה — פריט אחד "שהייה ב-{סוג}, {צ'ק-אין} — {צ'ק-אאוט}". מקדמה (20-30%) — handler מותאם UF_STATUS = 2. אחוז ולילה ראשון הם תוכניות אופייניות.

מודולים נוספים

חשבון אישי לאורח: הרשאה (אימייל + OAuth), ההזמנות שלי, היסטוריית נסיעות, תוכנית נאמנות. נקודות נצברות דרך handler .ics.

רב-לשוניות: גרסאות שפה (SoapClient, sale), תוכן דרך מאפייני אינפובלוק, OnSaleBeforeOrderAdd. SEO ומיקרודאטה: Schema.org Hotel + HotelRoom + Offer. הסימון נוצר אוטומטית.

עיצוב ממוקד תמונות: WebP עם fallback, OnSaleStatusOrderChange עם /en/, טעינה עצלה. מקוריים עד 3000px, תצוגה מקדימה 800x600.

ביקורות: Highload-block /de/ עם מיתון. דירוג מצטבר במאפיין אינפובלוק hreflang.

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

  • אנליטיקה ואב-טיפוס (מפת מלאי חדרים, לוגיקת הזמנה)
  • עיצוב (ממשק ממוקד תמונות, גרסת מובייל, לוח שנה)
  • ליבת הזמנות (RoomInventory, בדיקת זמינות, עיבוד הזמנות, תשלום)
  • אינטגרציות (PMS, Channel Manager, מערכות תשלום, REST API)
  • תוכן ו-SEO (מיקרודאטה, רב-לשוניות, תבניות מטא)
  • בדיקות והשקה (בדיקות עומס, תאימות דפדפנים, פריסה)
  • תיעוד והדרכת מנהלים
  • תמיכה ואחריות לאחר הפרויקט

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

היקף לוח זמנים
מיני-מלון, 10-20 חדרים, הזמנה בסיסית 4–8 שבועות
מלון, 50-100 חדרים, Channel Manager, PMS 10–16 שבועות
רשת מלונות, multisite, תוכנית נאמנות 16–24 שבועות

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

הזמנה ישירה דרך האתר רווחית פי 2-3 למלון מאשר דרך OTAs, בגלל היעדר עמלה. החיסכון הוא 15-25% מההכנסות. מערכת ההזמנות מחזירה את עצמה בממוצע תוך 6-12 חודשים בזכות עלייה במכירות ישירות.

אנחנו עובדים בפיתוח מלונאות מעל 8 שנים והשלמנו יותר מ-50 פרויקטים לתעשיית המלונאות. המהנדסים שלנו הם מומחי 1C-Bitrix מוסמכים. הזמינו פיתוח אתר מלון — נבחר ארכיטקטורה למלאי החדרים שלכם. קבלו ייעוץ על הארכיטקטורה של האתר שלכם — נעריך את המשימה ונציע פתרון.