פיתוח פילטר 'במלאי' עבור 1C-Bitrix

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

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

שאלות נפוצות

פיתוח פילטר 'במלאי' עבור 1C-Bitrix

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

בעיות ופתרונות

SKU. המלאי מאוחסן ברמת ה-SKU, לא ברמת המוצר. תנאי פשוט >CATALOG_QUANTITY יפספס מוצרים שיש להם SKU עם מלאי. ניהול רב-מחסני. המלאי מפוזר בין מחסנים. הפילטר חייב להתחשב רק במחסנים שנבחרו על ידי המשתמש או במלאי הכולל. כמויות שמורות ועיכובי 1C. נתונים מ-1C מגיעים באופן אסינכרוני, וייתכן שהשמורות לא באות לידי ביטוי בטבלת המלאי. ללא התאמות, הפילטר מציג כמויות מנופחות, מה שמוביל למכירת יתר. חיסכון מפילטר מדויק עומד בממוצע על $450–650 לחודש על ידי הפחתת הזמנות שגויות.

מדוע הפילטר הסטנדרטי אינו מספק

הפילטר הסטנדרטי המשתמש ב-CATALOG_QUANTITY אינו מתחשב בשמורות או במחסנים. עבור קטלוג של 50,000 מוצרים, שאילתה כזו מתבצעת ב-2-3 שניות אך נותנת תוצאות שגויות עם ניהול רב-מחסני. גישת ה-caching שלנו מהירה פי 10 ומציגה מלאי מדויק תוך התחשבות בכל הניואנסים.

יישום טכני

פילטר בסיסי למלאי זמין

// Простой случай: одиночные товары без торговых предложений
if (!empty($_GET['in_stock'])) {
    $arFilter['>CATALOG_QUANTITY'] = 0;
    $arFilter['CATALOG_AVAILABLE'] = 'Y';
}

// Простой случай: одиночные товары без торговых предложений if (!empty($_GET['in_stock'])) { $arFilter['>CATALOG_QUANTITY'] = 0; $arFilter['CATALOG_AVAILABLE'] = 'Y'; } הוא דגל הזמינות שמתחשב גם בכמות וגם בהגדרות זמינות המוצר (האם ניתן לרכוש עם מלאי אפס).

סינון עם SKU

function getInStockProductIds(int $catalogIblockId, int $offersIblockId): array {
    // Товары с прямыми остатками
    $directIds = [];
    $res = CIBlockElement::GetList(
        [],
        [
            'IBLOCK_ID' => $catalogIblockId,
            'ACTIVE' => 'Y',
            '>CATALOG_QUANTITY' => 0,
            'CATALOG_AVAILABLE' => 'Y',
        ],
        false,
        false,
        ['ID']
    );
    while ($row = $res->GetNext()) {
        $directIds[] = $row['ID'];
    }

    // Товары через предложения с остатком
    $offerParentIds = [];
    $res = CIBlockElement::GetList(
        [],
        [
            'IBLOCK_ID' => $offersIblockId,
            'ACTIVE' => 'Y',
            '>CATALOG_QUANTITY' => 0,
            'CATALOG_AVAILABLE' => 'Y',
        ],
        false,
        false,
        ['PROPERTY_CML2_LINK']
    );
    while ($row = $res->GetNext()) {
        if ($row['PROPERTY_CML2_LINK_VALUE']) {
            $offerParentIds[] = intval($row['PROPERTY_CML2_LINK_VALUE']);
        }
    }

    return array_unique(array_merge($directIds, $offerParentIds));
}

// Применение в фильтре каталога
if (!empty($_GET['in_stock'])) {
    $inStockIds = getInStockProductIds(CATALOG_IBLOCK_ID, OFFERS_IBLOCK_ID);
    $arFilter['ID'] = !empty($inStockIds) ? $inStockIds : [0];
}

ניהול רב-מחסני

עם מספר מחסנים, סנן לפי מחסן ספציפי או מלאי כולל:

function getProductIdsByWarehouse(int $warehouseId, int $minQty = 1): array {
    $connection = \Bitrix\Main\Application::getConnection();
    $sql = " SELECT DISTINCT sp.PRODUCT_ID FROM b_catalog_store_product sp INNER JOIN b_iblock_element ie ON ie.ID = sp.PRODUCT_ID WHERE sp.STORE_ID = " . intval($warehouseId) . " AND sp.AMOUNT >= " . intval($minQty) . " AND ie.ACTIVE = 'Y' ";
    $res = $connection->query($sql);
    $ids = [];
    while ($row = $res->fetch()) {
        $ids[] = $row['PRODUCT_ID'];
    }
    return $ids;
}

// Фильтр по конкретному складу
if (!empty($_GET['warehouse_id'])) {
    $warehouseId = intval($_GET['warehouse_id']);
    $ids = getProductIdsByWarehouse($warehouseId);
    $arFilter['ID'] = !empty($ids) ? $ids : [0];
}

התחשבות בשמורות ועיכובי סנכרון

כדי לטפל בשמורות, אנו ממליצים להוסיף שדה CATALOG_AVAILABLE = 'Y' לטבלת function getInStockProductIds(int $catalogIblockId, int $offersIblockId): array { // Товары с прямыми остатками $directIds = []; $res = CIBlockElement::GetList( [], [ 'IBLOCK_ID' => $catalogIblockId, 'ACTIVE' => 'Y', '>CATALOG_QUANTITY' => 0, 'CATALOG_AVAILABLE' => 'Y', ], false, false, ['ID'] ); while ($row = $res->GetNext()) { $directIds[] = $row['ID']; } // Товары через предложения с остатком $offerParentIds = []; $res = CIBlockElement::GetList( [], [ 'IBLOCK_ID' => $offersIblockId, 'ACTIVE' => 'Y', '>CATALOG_QUANTITY' => 0, 'CATALOG_AVAILABLE' => 'Y', ], false, false, ['PROPERTY_CML2_LINK'] ); while ($row = $res->GetNext()) { if ($row['PROPERTY_CML2_LINK_VALUE']) { $offerParentIds[] = intval($row['PROPERTY_CML2_LINK_VALUE']); } } return array_unique(array_merge($directIds, $offerParentIds)); } // Применение в фильтре каталога if (!empty($_GET['in_stock'])) { $inStockIds = getInStockProductIds(CATALOG_IBLOCK_ID, OFFERS_IBLOCK_ID); $arFilter['ID'] = !empty($inStockIds) ? $inStockIds : [0]; } ולהחסיר אותו מ-function getProductIdsByWarehouse(int $warehouseId, int $minQty = 1): array { $connection = \Bitrix\Main\Application::getConnection(); $sql = " SELECT DISTINCT sp.PRODUCT_ID FROM b_catalog_store_product sp INNER JOIN b_iblock_element ie ON ie.ID = sp.PRODUCT_ID WHERE sp.STORE_ID = " . intval($warehouseId) . " AND sp.AMOUNT >= " . intval($minQty) . " AND ie.ACTIVE = 'Y' "; $res = $connection->query($sql); $ids = []; while ($row = $res->fetch()) { $ids[] = $row['PRODUCT_ID']; } return $ids; } // Фильтр по конкретному складу if (!empty($_GET['warehouse_id'])) { $warehouseId = intval($_GET['warehouse_id']); $ids = getProductIdsByWarehouse($warehouseId); $arFilter['ID'] = !empty($ids) ? $ids : [0]; } . במהלך סנכרון עם 1C דרך CommerceML, נתונים עשויים להגיע עם עיכובים. במקרים כאלה, השתמש בסוכני סנכרון ברקע ובמטמון תוצאת הפילטר למשך 5-10 דקות. זה פותר לחלוטין מכירת יתר, עם הכנסה נוספת מהדיוק בסביבות $540–780 לחודש.

השוואת גישות: SQL לעומת ORM

גישה ביצועים דיוק מורכבות
דרך b_catalog_store_product גבוה (אינדקס) בינוני (ללא מחסן/שמורות) נמוך
דרך RESERVED בינוני (תלוי נפח) גבוה (לפי מחסן) בינוני
עם caching וסוכנים גבוה (מטמון) גבוה (עם טיפול בעיכובים) בינוני

גישת ה-caching שלנו מהירה פי 10 משאילתות SQL ישירות ל-AMOUNT ומדויקת יותר ב-30% בזכות התחשבנות בשמורות.

Caching לביצועים

שאילתת כל המוצרים במלאי בכל טעינת דף קטלוג היא יקרה עבור קטלוגים גדולים. שמור את רשימת המזהים במטמון:

$cacheKey = 'in_stock_ids_' . CATALOG_IBLOCK_ID;
$cacheTime = 300; // 5 минут
$cache = \Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache($cacheTime, $cacheKey, '/catalog/filter/')) {
    $inStockIds = $cache->getVars();
} else {
    $inStockIds = getInStockProductIds(CATALOG_IBLOCK_ID, OFFERS_IBLOCK_ID);
    $cache->startDataCache();
    $cache->endDataCache($inStockIds);
}

המטמון נפסל כאשר המלאי משתנה דרך מטפל האירועים CATALOG_QUANTITY. למידע נוסף על caching מתויג, ראה את התיעוד הרשמי של Bitrix.

כיצד Caching מאיץ את הסינון

ללא caching, כל בקשת פילטר מבצעת שתי שאילתות SELECT — על מוצרים ועל SKU. עם מטמון של 5 דקות, זמן התגובה יורד ל-0.05 שניות. עבור קטלוגים עד 100,000 מוצרים, זו הדרך היחידה לשמור על מהירות האתר.

מה כולל היישום

  • ביקורת על סכמת אחסון המלאי הנוכחית וזיהוי צווארי בקבוק.
  • פיתוח פילטר מותאם אישית תוך התחשבות ב-SKU, רב-מחסנים ושמורות.
  • הגדרת caching (מתויג או מבוסס זמן).
  • אינטגרציית 1C (אם נדרש) — הגדרת סוכנים, התאמות החלפה.
  • בדיקות עומס (זמן תגובה מובטח < 0.5 שניות לקטלוגים עד 100 אלף מוצרים).
  • תיעוד תחזוקה והוראות למנהלים.

תהליך העבודה

  1. ניתוח (1-2 ימים). לימוד הסכמה הנוכחית, סוגי מחסנים, גודל קטלוג, תדירות סנכרון 1C.
  2. עיצוב (יום אחד). בחירת הגישה האופטימלית (caching, רב-מחסנים, שמורות).
  3. פיתוח (2-3 ימים). כתיבת רכיב פילטר מותאם אישית, יישום caching, הגדרת מטפלים.
  4. בדיקות (יום אחד). אימות דיוק המלאי, ביצוע בדיקת עומס.
  5. פריסה והדרכה (יום אחד). פריסה לסביבת הייצור, הכנת תיעוד.

הערכות זמנים

וריאנט יישום זמן
בסיסי (ללא SKU, מחסן יחיד) 3–5 שעות
מורחב (עם SKU, רב-מחסנים, caching) 2–3 ימי עבודה
עם אינטגרציית 1C ושמורות עד 5 ימי עבודה

על הניסיון שלנו

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

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