Example #1
0
 public static function isBarCodeValid($arParams)
 {
     $bResult = false;
     $arBasket = array();
     if (intval($arParams["basketItemId"]) > 0) {
         $dbBasket = CSaleBasket::GetList(array("ID" => "DESC"), array("ID" => $arParams["basketItemId"]), false, false, array("ID", "PRODUCT_ID", "PRODUCT_PROVIDER_CLASS", "MODULE", "BARCODE_MULTI"));
         $arBasket = $dbBasket->GetNext();
     } else {
         $arBasket = array("PRODUCT_PROVIDER_CLASS" => $arParams["productProvider"], "MODULE" => $arParams["moduleName"], "PRODUCT_ID" => $arParams["productId"], "BARCODE_MULTI" => $arParams["barcodeMult"]);
     }
     if (!empty($arBasket) && is_array($arBasket)) {
         /** @var $productProvider IBXSaleProductProvider */
         if ($productProvider = CSaleBasket::GetProductProvider($arBasket)) {
             $arCheckBarcodeFields = array("BARCODE" => $arParams["barcode"], "PRODUCT_ID" => $arBasket["PRODUCT_ID"], "ORDER_ID" => $arParams["orderId"]);
             if ($arBasket["BARCODE_MULTI"] == "Y") {
                 $arCheckBarcodeFields["STORE_ID"] = $arParams["storeId"];
             }
             $res = $productProvider::CheckProductBarcode($arCheckBarcodeFields);
             if ($res) {
                 $bResult = true;
             }
         }
     }
     return $bResult;
 }
Example #2
0
 /**
  * Wraps  Product Provider Class::GetProductData from module catalog.
  * @param int $productId Product Id.
  * @param int $quantity Product quantity.
  * @param string $siteId Site id.
  * @return array.
  * @throws \Bitrix\Main\SystemException
  */
 public static function getProductById($productId, $quantity, $siteId)
 {
     $result = array();
     if (\CModule::IncludeModule('catalog')) {
         if ($productProvider = \CSaleBasket::GetProductProvider(array("MODULE" => "catalog", "PRODUCT_PROVIDER_CLASS" => "CCatalogProductProvider"))) {
             global $USER;
             $bTmpUserCreated = false;
             if (!\CCatalog::IsUserExists()) {
                 $bTmpUserCreated = true;
                 if (isset($USER)) {
                     $USER_TMP = $USER;
                     unset($USER);
                 }
                 $USER = new \CUser();
             }
             $result = $productProvider::GetProductData(array("PRODUCT_ID" => $productId, "RENEWAL" => "N", "QUANTITY" => $quantity, "SITE_ID" => $siteId));
             $result["MODULE"] = "catalog";
             $result["PRODUCT_PROVIDER_CLASS"] = "CCatalogProductProvider";
             $dbIblockElement = \CIBlockElement::GetList(array(), array("ID" => $productId), false, false, array('XML_ID', 'IBLOCK_EXTERNAL_ID'));
             if ($IblockElement = $dbIblockElement->Fetch()) {
                 if (strlen($IblockElement["XML_ID"]) > 0) {
                     $result["PRODUCT_XML_ID"] = $IblockElement["XML_ID"];
                 }
                 if (strlen($IblockElement["IBLOCK_EXTERNAL_ID"]) > 0) {
                     $result["CATALOG_XML_ID"] = $IblockElement["IBLOCK_EXTERNAL_ID"];
                 }
             }
             if ($bTmpUserCreated) {
                 unset($USER);
                 if (isset($USER_TMP)) {
                     $USER = $USER_TMP;
                     unset($USER_TMP);
                 }
             }
         }
     } else {
         throw new \Bitrix\Main\SystemException("Can't include module \"Catalog\"!");
     }
     return $result;
 }
         $arPrice["PRICE"]["CURRENCY"] = $BASE_LANG_CURR;
     }
     $currentTotalPriceFormat = CurrencyFormatNumber($currentTotalPrice, $arPrice["PRICE"]["CURRENCY"]);
     $summaFormated = CurrencyFormatNumber($currentPrice * $QUANTITY, $arPrice["PRICE"]["CURRENCY"]);
 } else {
     $currentTotalPriceFormat = CurrencyFormatNumber($currentTotalPrice, $arPrice["PRICE"]["CURRENCY"]);
     $summaFormated = CurrencyFormatNumber($currentPrice * $QUANTITY, $arPrice["PRICE"]["CURRENCY"]);
 }
 $urlEdit = "/bitrix/admin/iblock_element_edit.php?ID=" . $arItems["ID"] . "&type=" . $arItems["IBLOCK_TYPE_ID"] . "&lang=" . LANG . "&IBLOCK_ID=" . $arItems["IBLOCK_ID"] . "&find_section_section=" . $arItems["IBLOCK_SECTION_ID"];
 $bCanBuy = true;
 if ($arCatalogProduct["CAN_BUY_ZERO"] != "Y" && ($arCatalogProduct["QUANTITY_TRACE"] == "Y" && doubleval($arCatalogProduct["QUANTITY"]) <= 0)) {
     $bCanBuy = false;
 }
 $arStores = array();
 /** @var $productProvider IBXSaleProductProvider */
 if ($productProvider = CSaleBasket::GetProductProvider(array("MODULE" => "catalog", "PRODUCT_PROVIDER_CLASS" => "CCatalogProductProvider"))) {
     $arStores = $productProvider::GetProductStores(array("PRODUCT_ID" => $arItems["ID"]));
 }
 if ($addDefault == "Y" || $bCanBuy && $addDefault == "N") {
     $arParams = "{'id' : '" . $arItems["ID"] . "',\n\t\t\t\t'name' : '" . CUtil::JSEscape($arItems["NAME"]) . "',\n\t\t\t\t'url' : '" . CUtil::JSEscape($URL) . "',\n\t\t\t\t'urlEdit' : '" . CUtil::JSEscape($urlEdit) . "',\n\t\t\t\t'urlImg' : '" . CUtil::JSEscape($ImgUrl) . "',\n\t\t\t\t'price' : '" . CUtil::JSEscape($currentPrice) . "',\n\t\t\t\t'priceFormated' : '" . CUtil::JSEscape(CurrencyFormatNumber($currentPrice, $arPrice["PRICE"]["CURRENCY"])) . "',\n\t\t\t\t'valutaFormat' : '" . CUtil::JSEscape($priceValutaFormat) . "',\n\t\t\t\t'priceDiscount' : '" . CUtil::JSEscape($currentDiscount) . "',\n\t\t\t\t'priceBase' : '" . CUtil::JSEscape($currentBasePrice) . "',\n\t\t\t\t'priceBaseFormat' : '" . CUtil::JSEscape(CurrencyFormatNumber($currentBasePrice, $arPrice["PRICE"]["CURRENCY"])) . "',\n\t\t\t\t'discountPercent' : '" . CUtil::JSEscape($discountPercent) . "',\n\t\t\t\t'summaFormated' : '" . CUtil::JSEscape($summaFormated) . "',\n\t\t\t\t'quantity' : '" . CUtil::JSEscape($QUANTITY) . "',\n\t\t\t\t'module' : 'catalog',\n\t\t\t\t'currency' : '" . CUtil::JSEscape($arPrice["PRICE"]["CURRENCY"]) . "',\n\t\t\t\t'weight' : '" . DoubleVal($arCatalogProduct["WEIGHT"]) . "',\n\t\t\t\t'vatRate' : '" . DoubleVal($vatRate) . "',\n\t\t\t\t'priceType' : '" . CUtil::JSEscape($PriceType) . "',\n\t\t\t\t'balance' : '" . CUtil::JSEscape($balance) . "',\n\t\t\t\t'catalogXmlID' : '" . CUtil::JSEscape($arIBlock["XML_ID"]) . "',\n\t\t\t\t'productXmlID' : '" . CUtil::JSEscape($arItems["XML_ID"]) . "',\n\t\t\t\t'barcodeMulti' : '" . CUtil::JSEscape($arCatalogProduct["BARCODE_MULTI"]) . "',\n\t\t\t\t'stores' : '" . CUtil::JSEscape(CUtil::PhpToJSObject($arStores)) . "',\n\t\t\t\t'orderCallback' : '', 'cancelCallback' : '', 'payCallback' : '', 'callback' : '','productProviderClass' : 'CCatalogProductProvider'}";
     // 'callback' : 'CatalogBasketCallback',
     // 'orderCallback' : 'CatalogBasketOrderCallback',
     // 'cancelCallback' : 'CatalogBasketCancelCallback',
     // 'payCallback' : 'CatalogPayOrderCallback',
     foreach (GetModuleEvents("sale", "OnProductSearchForm", true) as $arEvent) {
         $arParams = ExecuteModuleEventEx($arEvent, array($arItems["ID"], $arParams));
     }
     $arParams = "var el" . $arItems["ID"] . " = " . $arParams;
     $act = "<script>" . $arParams . "</script><input type='button' onClick=\"SelEl(el" . $arItems["ID"] . ", " . $arItems["ID"] . ")\" name='btn_select_" . $arItems["ID"] . "' id='btn_select_" . $arItems["ID"] . "' value='" . GetMessage("SPS_SELECT") . "' >";
     $countField = "<input type=\"text\" name=\"quantity_" . $arItems["ID"] . "\" id=\"quantity_" . $arItems["ID"] . "\" value=\"1\" size=\"3\" >";
     $active = GetMEssage('SPS_PRODUCT_ACTIVE');
Example #4
0
/**
 * @param int $PRODUCT_ID
 * @param float|int $QUANTITY
 * @param array $arRewriteFields
 * @param bool|array $arProductParams
 * @return bool|int
 */
function Add2BasketByProductID($PRODUCT_ID, $QUANTITY = 1, $arRewriteFields = array(), $arProductParams = false)
{
    global $APPLICATION;
    /* for old use */
    if ($arProductParams === false) {
        $arProductParams = $arRewriteFields;
        $arRewriteFields = array();
    }
    $boolRewrite = !empty($arRewriteFields) && is_array($arRewriteFields);
    if ($boolRewrite && isset($arRewriteFields['SUBSCRIBE']) && $arRewriteFields['SUBSCRIBE'] == 'Y') {
        return SubscribeProduct($PRODUCT_ID, $arRewriteFields, $arProductParams);
    }
    $PRODUCT_ID = (int) $PRODUCT_ID;
    if ($PRODUCT_ID <= 0) {
        $APPLICATION->ThrowException(Loc::getMessage('CATALOG_ERR_EMPTY_PRODUCT_ID'), "EMPTY_PRODUCT_ID");
        return false;
    }
    $QUANTITY = (double) $QUANTITY;
    if ($QUANTITY <= 0) {
        $QUANTITY = 1;
    }
    if (!Loader::includeModule("sale")) {
        $APPLICATION->ThrowException(Loc::getMessage('CATALOG_ERR_NO_SALE_MODULE'), "NO_SALE_MODULE");
        return false;
    }
    if (Loader::includeModule("statistic") && isset($_SESSION['SESS_SEARCHER_ID']) && (int) $_SESSION["SESS_SEARCHER_ID"] > 0) {
        $APPLICATION->ThrowException(Loc::getMessage('CATALOG_ERR_SESS_SEARCHER'), "SESS_SEARCHER");
        return false;
    }
    $rsProducts = CCatalogProduct::GetList(array(), array('ID' => $PRODUCT_ID), false, false, array('ID', 'CAN_BUY_ZERO', 'QUANTITY_TRACE', 'QUANTITY', 'WEIGHT', 'WIDTH', 'HEIGHT', 'LENGTH', 'TYPE', 'MEASURE'));
    if (!($arCatalogProduct = $rsProducts->Fetch())) {
        $APPLICATION->ThrowException(Loc::getMessage('CATALOG_ERR_NO_PRODUCT'), "NO_PRODUCT");
        return false;
    }
    $arCatalogProduct['MEASURE'] = (int) $arCatalogProduct['MEASURE'];
    $arCatalogProduct['MEASURE_NAME'] = '';
    $arCatalogProduct['MEASURE_CODE'] = 0;
    if ($arCatalogProduct['MEASURE'] <= 0) {
        $arMeasure = CCatalogMeasure::getDefaultMeasure(true, true);
        $arCatalogProduct['MEASURE_NAME'] = $arMeasure['~SYMBOL_RUS'];
        $arCatalogProduct['MEASURE_CODE'] = $arMeasure['CODE'];
    } else {
        $rsMeasures = CCatalogMeasure::getList(array(), array('ID' => $arCatalogProduct['MEASURE']), false, false, array('ID', 'SYMBOL_RUS', 'CODE'));
        if ($arMeasure = $rsMeasures->GetNext()) {
            $arCatalogProduct['MEASURE_NAME'] = $arMeasure['~SYMBOL_RUS'];
            $arCatalogProduct['MEASURE_CODE'] = $arMeasure['CODE'];
        }
    }
    $dblQuantity = (double) $arCatalogProduct["QUANTITY"];
    $intQuantity = (int) $arCatalogProduct["QUANTITY"];
    $boolQuantity = $arCatalogProduct["CAN_BUY_ZERO"] != 'Y' && $arCatalogProduct["QUANTITY_TRACE"] == 'Y';
    if ($boolQuantity && $dblQuantity <= 0) {
        $APPLICATION->ThrowException(Loc::getMessage('CATALOG_ERR_PRODUCT_RUN_OUT'), "PRODUCT_RUN_OUT");
        return false;
    }
    $rsItems = CIBlockElement::GetList(array(), array("ID" => $PRODUCT_ID, "ACTIVE" => "Y", "ACTIVE_DATE" => "Y", "CHECK_PERMISSIONS" => "Y", "MIN_PERMISSION" => "R"), false, false, array("ID", "IBLOCK_ID", "XML_ID", "NAME", "DETAIL_PAGE_URL"));
    if (!($arProduct = $rsItems->GetNext())) {
        $APPLICATION->ThrowException(Loc::getMessage('CATALOG_ERR_NO_IBLOCK_ELEMENT'), "NO_IBLOCK_ELEMENT");
        return false;
    }
    $strCallbackFunc = "";
    $strProductProviderClass = "CCatalogProductProvider";
    if ($boolRewrite) {
        if (isset($arRewriteFields['CALLBACK_FUNC'])) {
            $strCallbackFunc = $arRewriteFields['CALLBACK_FUNC'];
        }
        if (isset($arRewriteFields['PRODUCT_PROVIDER_CLASS'])) {
            $strProductProviderClass = $arRewriteFields['PRODUCT_PROVIDER_CLASS'];
        }
    }
    $arCallbackPrice = false;
    if (!empty($strProductProviderClass)) {
        if ($productProvider = CSaleBasket::GetProductProvider(array('MODULE' => 'catalog', 'PRODUCT_PROVIDER_CLASS' => $strProductProviderClass))) {
            $providerParams = array('PRODUCT_ID' => $PRODUCT_ID, 'QUANTITY' => $QUANTITY, 'RENEWAL' => 'N');
            $arCallbackPrice = $productProvider::GetProductData($providerParams);
            unset($providerParams);
        }
    } elseif (!empty($strCallbackFunc)) {
        $arCallbackPrice = CSaleBasket::ExecuteCallbackFunction($strCallbackFunc, 'catalog', $PRODUCT_ID, $QUANTITY, 'N');
    }
    if (empty($arCallbackPrice) || !is_array($arCallbackPrice)) {
        $APPLICATION->ThrowException(Loc::getMessage('CATALOG_PRODUCT_PRICE_NOT_FOUND'), "NO_PRODUCT_PRICE");
        return false;
    }
    $arProps = array();
    $strIBlockXmlID = (string) CIBlock::GetArrayByID($arProduct['IBLOCK_ID'], 'XML_ID');
    if ($strIBlockXmlID !== '') {
        $arProps[] = array('NAME' => 'Catalog XML_ID', 'CODE' => 'CATALOG.XML_ID', 'VALUE' => $strIBlockXmlID);
    }
    // add sku props
    $arParentSku = CCatalogSku::GetProductInfo($PRODUCT_ID, $arProduct['IBLOCK_ID']);
    if (!empty($arParentSku)) {
        if (strpos($arProduct["~XML_ID"], '#') === false) {
            $parentIterator = Iblock\ElementTable::getList(array('select' => array('ID', 'XML_ID'), 'filter' => array('ID' => $arParentSku['ID'])));
            if ($parent = $parentIterator->fetch()) {
                $arProduct["~XML_ID"] = $parent['XML_ID'] . '#' . $arProduct["~XML_ID"];
            }
            unset($parent, $parentIterator);
        }
    }
    if (!empty($arProductParams) && is_array($arProductParams)) {
        foreach ($arProductParams as &$arOneProductParams) {
            $arProps[] = array("NAME" => $arOneProductParams["NAME"], "CODE" => $arOneProductParams["CODE"], "VALUE" => $arOneProductParams["VALUE"], "SORT" => $arOneProductParams["SORT"]);
        }
        unset($arOneProductParams);
    }
    $arProps[] = array("NAME" => "Product XML_ID", "CODE" => "PRODUCT.XML_ID", "VALUE" => $arProduct["~XML_ID"]);
    $arFields = array("PRODUCT_ID" => $PRODUCT_ID, "PRODUCT_PRICE_ID" => $arCallbackPrice["PRODUCT_PRICE_ID"], "PRICE" => $arCallbackPrice["PRICE"], "CURRENCY" => $arCallbackPrice["CURRENCY"], "DISCOUNT_PRICE" => $arCallbackPrice["DISCOUNT_PRICE"], "WEIGHT" => $arCatalogProduct["WEIGHT"], "DIMENSIONS" => serialize(array("WIDTH" => $arCatalogProduct["WIDTH"], "HEIGHT" => $arCatalogProduct["HEIGHT"], "LENGTH" => $arCatalogProduct["LENGTH"])), "QUANTITY" => $boolQuantity && $dblQuantity < $QUANTITY ? $dblQuantity : $QUANTITY, "LID" => SITE_ID, "DELAY" => "N", "CAN_BUY" => "Y", "NAME" => $arProduct["~NAME"], "MODULE" => "catalog", "PRODUCT_PROVIDER_CLASS" => "CCatalogProductProvider", "NOTES" => $arCallbackPrice["NOTES"], "DETAIL_PAGE_URL" => $arProduct["~DETAIL_PAGE_URL"], "CATALOG_XML_ID" => $strIBlockXmlID, "PRODUCT_XML_ID" => $arProduct["~XML_ID"], "VAT_RATE" => $arCallbackPrice['VAT_RATE'], "PROPS" => $arProps, "TYPE" => $arCatalogProduct["TYPE"] == CCatalogProduct::TYPE_SET ? CCatalogProductSet::TYPE_SET : NULL, "MEASURE_NAME" => $arCatalogProduct['MEASURE_NAME'], "MEASURE_CODE" => $arCatalogProduct['MEASURE_CODE']);
    if ($boolRewrite) {
        $arFields = array_merge($arFields, $arRewriteFields);
    }
    $result = CSaleBasket::Add($arFields);
    if ($result) {
        if (Loader::includeModule("statistic")) {
            CStatistic::Set_Event("sale2basket", "catalog", $arFields["DETAIL_PAGE_URL"]);
        }
    }
    return $result;
}
Example #5
0
 protected function getProductById($productId, $quantity)
 {
     $arResult = array();
     if (CModule::IncludeModule('catalog')) {
         if ($productProvider = CSaleBasket::GetProductProvider(array("MODULE" => "catalog", "PRODUCT_PROVIDER_CLASS" => "CCatalogProductProvider"))) {
             $arResult = $productProvider::GetProductData(array("PRODUCT_ID" => $productId, "RENEWAL" => "N", "QUANTITY" => $quantity, "SITE_ID" => $this->siteId));
         }
     } else {
         $arResult = $this->processError(self::ERROR_STATUS_500, GetMessage("SALE_YMH_ERROR_CATALOG_NOT_INSTALLED"));
     }
     return $arResult;
 }
Example #6
0
 function UpdateBasketPrices($fuserID, $siteID)
 {
     $fuserID = (int) $fuserID;
     if ($fuserID <= 0) {
         return false;
     }
     $siteID = (string) $siteID;
     if ($siteID == '') {
         $siteID = SITE_ID;
     }
     $isOrderConverted = \Bitrix\Main\Config\Option::get("main", "~sale_converted_15", 'N');
     $dbBasketItems = CSaleBasket::GetList(array("ALL_PRICE" => "DESC"), array("FUSER_ID" => $fuserID, "LID" => $siteID, "ORDER_ID" => "NULL", "SUBSCRIBE" => "N"), false, false, array("ID", "MODULE", "PRODUCT_ID", "QUANTITY", "CALLBACK_FUNC", "PRODUCT_PROVIDER_CLASS", "CAN_BUY", "DELAY", "NOTES", "TYPE", "SET_PARENT_ID"));
     while ($arItem = $dbBasketItems->Fetch()) {
         if ($arItem['CAN_BUY'] != 'Y') {
             continue;
         }
         $arFields = false;
         $arItem['CALLBACK_FUNC'] = (string) $arItem['CALLBACK_FUNC'];
         $arItem['PRODUCT_PROVIDER_CLASS'] = (string) $arItem['PRODUCT_PROVIDER_CLASS'];
         if ('' != $arItem['PRODUCT_PROVIDER_CLASS'] || '' != $arItem['CALLBACK_FUNC']) {
             $arItem['MODULE'] = (string) $arItem['MODULE'];
             $arItem['PRODUCT_ID'] = (int) $arItem['PRODUCT_ID'];
             $arItem['QUANTITY'] = (double) $arItem['QUANTITY'];
             if ($productProvider = CSaleBasket::GetProductProvider($arItem)) {
                 $arFields = $productProvider::GetProductData(array("PRODUCT_ID" => $arItem["PRODUCT_ID"], "QUANTITY" => $arItem["QUANTITY"], "RENEWAL" => "N", "CHECK_COUPONS" => 'Y' == $arItem['CAN_BUY'] && 'N' == $arItem['DELAY'] ? 'Y' : 'N', "CHECK_DISCOUNT" => CSaleBasketHelper::isSetItem($arItem) ? 'N' : 'Y', "BASKET_ID" => $arItem["ID"], "NOTES" => $arItem["NOTES"]));
             } else {
                 $arFields = CSaleBasket::ExecuteCallbackFunction($arItem["CALLBACK_FUNC"], $arItem["MODULE"], $arItem["PRODUCT_ID"], $arItem["QUANTITY"], "N");
             }
             if (!empty($arFields) && is_array($arFields)) {
                 if ($isOrderConverted == 'Y' && $arItem['DELAY'] == 'N') {
                     if (!Sale\Compatible\DiscountCompatibility::isInited()) {
                         Sale\Compatible\DiscountCompatibility::init();
                     }
                     if (Sale\Compatible\DiscountCompatibility::usedByClient()) {
                         if (isset($arFields['BASE_PRICE']) && isset($arFields['CURRENCY'])) {
                             Sale\Compatible\DiscountCompatibility::setBasketItemBasePrice($arItem['ID'], $arFields['BASE_PRICE'], $arFields['CURRENCY']);
                         }
                         if (!empty($arFields['DISCOUNT_LIST'])) {
                             Sale\Compatible\DiscountCompatibility::setBasketItemDiscounts($arItem['ID'], $arFields['DISCOUNT_LIST']);
                         }
                     }
                 }
                 $arFields['CAN_BUY'] = 'Y';
                 $arFields['TYPE'] = (int) $arItem['TYPE'];
                 $arFields['SET_PARENT_ID'] = (int) $arItem['SET_PARENT_ID'];
             } else {
                 $arFields = array('CAN_BUY' => 'N');
             }
             CSaleBasket::Update($arItem['ID'], $arFields);
         }
     }
     return true;
 }
Example #7
0
 /**
  * Method is called to deduct all products of the order
  *
  * @param int $orderID
  * @param bool $bUndoReservation
  * @return mixed array
  */
 function OrderDeduction($orderID, $bReturn = false, $recurringID = 0, $bAutoDeduction = true, $arStoreBarcodeOrderFormData = array())
 {
     global $DB;
     static $storesCount = NULL;
     static $bAutoDeductionAllowed = NULL;
     $bRealDeductionAllowed = true;
     $arSavedStoreBarcodeData = array();
     $arItems = array();
     $arResult = array();
     if (defined("SALE_DEBUG") && SALE_DEBUG) {
         CSaleHelper::WriteToLog("OrderDeduction: started", array("orderID" => $orderID, "bReturn" => intval($bReturn), "bAutoDeduction" => intval($bAutoDeduction), "arStoreBarcodeOrderFormData" => $arStoreBarcodeOrderFormData), "OD1");
     }
     //TODO - recurringID - ?
     $orderID = IntVal($orderID);
     if ($orderID <= 0) {
         $arResult["RESULT"] = false;
         return $arResult;
     }
     $dbBasketList = CSaleBasket::GetList(array(), array("ORDER_ID" => $orderID), false, false, array('ID', 'PRODUCT_ID', 'PRODUCT_PROVIDER_CLASS', 'MODULE', 'BARCODE_MULTI', 'QUANTITY', 'RESERVED'));
     //check and emulate deduction
     while ($arBasket = $dbBasketList->Fetch()) {
         if (defined("SALE_DEBUG") && SALE_DEBUG) {
             CSaleHelper::WriteToLog("Deducting product #" . $arBasket["PRODUCT_ID"], array(), "OD2");
         }
         /** @var $productProvider IBXSaleProductProvider */
         if ($productProvider = CSaleBasket::GetProductProvider($arBasket)) {
             if (is_null($storesCount)) {
                 $storesCount = intval($productProvider::GetStoresCount());
             }
             if (defined("SALE_DEBUG") && SALE_DEBUG) {
                 CSaleHelper::WriteToLog("stores count: " . $storesCount, array(), "OD3");
             }
             if (is_null($bAutoDeductionAllowed)) {
                 if ($storesCount == 1 || $storesCount == -1) {
                     // if stores' count = 1 or stores aren't used
                     $bAutoDeductionAllowed = true;
                 } else {
                     $bAutoDeductionAllowed = false;
                 }
             }
             if (defined("SALE_DEBUG") && SALE_DEBUG) {
                 CSaleHelper::WriteToLog("auto deduction allowed: " . intval($bAutoDeductionAllowed), array(), "OD4");
             }
             if ($bAutoDeduction && !$bAutoDeductionAllowed && !$bReturn) {
                 if (defined("SALE_DEBUG") && SALE_DEBUG) {
                     CSaleHelper::WriteToLog("DDCT_AUTO_DEDUCT_WRONG_STORES_QUANTITY", array(), "OD5");
                 }
                 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("DDCT_AUTO_DEDUCT_WRONG_STORES_QUANTITY"), "DDCT_WRONG_STORES_QUANTITY");
                 $bRealDeductionAllowed = false;
             } else {
                 if ($bAutoDeduction && $arBasket["BARCODE_MULTI"] == "Y" && !$bReturn) {
                     if (defined("SALE_DEBUG") && SALE_DEBUG) {
                         CSaleHelper::WriteToLog("DDCT_AUTO_DEDUCT_BARCODE_MULTI", array(), "OD6");
                     }
                     $GLOBALS["APPLICATION"]->ThrowException(GetMessage("DDCT_AUTO_DEDUCT_BARCODE_MULTI", array("#PRODUCT_ID#" => $arBasket["PRODUCT_ID"])), "DDCT_CANT_DEDUCT_BARCODE_MULTI");
                     $bRealDeductionAllowed = false;
                 } else {
                     //get saved store & barcode data if stores are used to know where to return products
                     if ($bReturn && $storesCount > 0) {
                         $dbStoreBarcode = CSaleStoreBarcode::GetList(array(), array("BASKET_ID" => $arBasket["ID"]), false, false, array("ID", "BASKET_ID", "BARCODE", "QUANTITY", "STORE_ID"));
                         while ($arStoreBarcode = $dbStoreBarcode->Fetch()) {
                             $arSavedStoreBarcodeData[$arBasket["ID"]][] = $arStoreBarcode;
                         }
                         if (defined("SALE_DEBUG") && SALE_DEBUG) {
                             CSaleHelper::WriteToLog("OrderDeduction: CSaleStoreBarcode data (stores) to return products to", array("arSavedStoreBarcodeData" => $arSavedStoreBarcodeData), "OD7");
                         }
                     }
                     $arFields = array("PRODUCT_ID" => $arBasket["PRODUCT_ID"], "EMULATE" => "Y", "PRODUCT_RESERVED" => $arBasket["RESERVED"], "UNDO_DEDUCTION" => $bReturn ? "Y" : "N");
                     if ($bReturn) {
                         if ($storesCount > 0) {
                             $arFields["QUANTITY"] = 0;
                             //won't be used during deduction
                             $arFields["STORE_DATA"] = $arSavedStoreBarcodeData[$arBasket["ID"]];
                         } else {
                             $arFields["QUANTITY"] = $arBasket["QUANTITY"];
                             $arFields["STORE_DATA"] = array();
                         }
                     } else {
                         if ($storesCount == 1) {
                             $arFields["QUANTITY"] = 0;
                             if ($bAutoDeduction) {
                                 if ($arProductStore = $productProvider::GetProductStores(array("PRODUCT_ID" => $arBasket["PRODUCT_ID"]))) {
                                     $arFields["STORE_DATA"] = array("0" => array("STORE_ID" => $arProductStore[0]["STORE_ID"], "QUANTITY" => $arBasket["QUANTITY"], "AMOUNT" => $arProductStore[0]["AMOUNT"]));
                                 } else {
                                     $arFields["STORE_DATA"] = array();
                                 }
                             } else {
                                 $arFields["STORE_DATA"] = $arStoreBarcodeOrderFormData[$arBasket["ID"]];
                             }
                         } else {
                             if ($storesCount > 1) {
                                 $arFields["QUANTITY"] = 0;
                                 //won't be used during deduction
                                 $arFields["STORE_DATA"] = $arStoreBarcodeOrderFormData[$arBasket["ID"]];
                             } else {
                                 $arFields["QUANTITY"] = $arBasket["QUANTITY"];
                                 $arFields["STORE_DATA"] = array();
                             }
                         }
                     }
                     if (defined("SALE_DEBUG") && SALE_DEBUG) {
                         CSaleHelper::WriteToLog("Emulating call ::DeductProduct", array("arFields" => $arFields), "OD7");
                     }
                     //emulate deduction
                     $res = $productProvider::DeductProduct($arFields);
                     if ($res["RESULT"]) {
                         $arBasket["FIELDS"] = $arFields;
                         $arItems[] = $arBasket;
                         if (defined("SALE_DEBUG") && SALE_DEBUG) {
                             CSaleHelper::WriteToLog("Emulating call ::DeductProduct - success", array(), "OD8");
                         }
                     } else {
                         $bRealDeductionAllowed = false;
                         if (defined("SALE_DEBUG") && SALE_DEBUG) {
                             CSaleHelper::WriteToLog("Emulating call ::DeductProduct - error", array(), "OD9");
                         }
                     }
                 }
             }
             if ($ex = $GLOBALS["APPLICATION"]->GetException()) {
                 $arResult["ERROR"]["MESSAGE"] = $ex->GetString();
                 $arResult["ERROR"]["CODE"] = $ex->GetID();
             }
             if (!$bRealDeductionAllowed) {
                 break;
             }
         }
     }
     //real deduction
     if ($bRealDeductionAllowed) {
         $bProductsDeductedSuccessfully = true;
         $arDeductedItems = array();
         foreach ($arItems as $arItem) {
             /** @var $productProvider IBXSaleProductProvider */
             if ($productProvider = CSaleBasket::GetProductProvider($arItem)) {
                 $arItem["FIELDS"]["EMULATE"] = "N";
                 if (defined("SALE_DEBUG") && SALE_DEBUG) {
                     CSaleHelper::WriteToLog("Call ::DeductProduct", array("fields" => $arItem["FIELDS"]), "OD10");
                 }
                 //finally real deduction
                 $res = $productProvider::DeductProduct($arItem["FIELDS"]);
                 if ($res["RESULT"]) {
                     $arDeductedItems[] = $arItem;
                     if (!$bReturn && $storesCount > 0) {
                         if ($bAutoDeduction) {
                             $arStoreBarcodeFields = array("BASKET_ID" => $arItem["ID"], "BARCODE" => "", "STORE_ID" => array_pop(array_keys($res["STORES"])), "QUANTITY" => $arItem["QUANTITY"], "CREATED_BY" => intval($GLOBALS["USER"]->GetID()) > 0 ? IntVal($GLOBALS["USER"]->GetID()) : "", "MODIFIED_BY" => intval($GLOBALS["USER"]->GetID()) > 0 ? IntVal($GLOBALS["USER"]->GetID()) : "");
                             if (defined("SALE_DEBUG") && SALE_DEBUG) {
                                 CSaleHelper::WriteToLog("Call CSaleStoreBarcode::Add (auto deduction = true)", array("arStoreBarcodeFields" => $arStoreBarcodeFields), "OD11");
                             }
                             CSaleStoreBarcode::Add($arStoreBarcodeFields);
                         }
                         // else
                         // {
                         // 	foreach ($arStoreBarcodeOrderFormData as $id => $arRecord)
                         // 	{
                         // 		$arStoreBarcodeFields = array(
                         // 			"BASKET_ID"   => $arRecord["ID"],
                         // 			"BARCODE"     => ($arItem["BARCODE_MULTI"] == "Y") ? $arRecord["BARCODE"] : "",
                         // 			"STORE_ID"    => $arRecord["STORE_ID"],
                         // 			"QUANTITY"    => $arRecord["QUANTITY"],
                         // 			"CREATED_BY"  => ((intval($GLOBALS["USER"]->GetID())>0) ? IntVal($GLOBALS["USER"]->GetID()) : ""),
                         // 			"MODIFIED_BY" => ((intval($GLOBALS["USER"]->GetID())>0) ? IntVal($GLOBALS["USER"]->GetID()) : "")
                         // 		);
                         // 		if (defined("SALE_DEBUG") && SALE_DEBUG)
                         // 			CSaleHelper::WriteToLog("Call CSaleStoreBarcode::Add", array("arStoreBarcodeFields" => $arStoreBarcodeFields), "OD11");
                         // 		CSaleStoreBarcode::Add($arStoreBarcodeFields);
                         // 	}
                         // }
                     }
                     if (defined("SALE_DEBUG") && SALE_DEBUG) {
                         CSaleHelper::WriteToLog("Call ::DeductProduct - Success (DEDUCTED = Y)", array(), "OD11");
                     }
                     CSaleBasket::Update($arItem["ID"], array("DEDUCTED" => "Y"));
                     //CSaleOrder::AddOrderHistory
                 } else {
                     CSaleBasket::Update($arItem["ID"], array("DEDUCTED" => "N"));
                     $bProductsDeductedSuccessfully = false;
                     if ($ex = $GLOBALS["APPLICATION"]->GetException()) {
                         $arResult["ERROR"]["MESSAGE"] = $ex->GetString();
                         $arResult["ERROR"]["CODE"] = $ex->GetID();
                     }
                     if (defined("SALE_DEBUG") && SALE_DEBUG) {
                         CSaleHelper::WriteToLog("Call ::DeductProduct - Error (DEDUCTED = N)", array(), "OD12");
                     }
                     break;
                 }
             }
         }
         if ($bProductsDeductedSuccessfully) {
             $arResult["RESULT"] = true;
         } else {
             $arFields = array();
             foreach ($arDeductedItems as $arItem) {
                 /** @var $productProvider IBXSaleProductProvider */
                 if ($productProvider = CSaleBasket::GetProductProvider($arItem)) {
                     if ($storesCount > 0) {
                         $arFields = array("PRODUCT_ID" => $arItem["PRODUCT_ID"], "QUANTITY" => $arItem["QUANTITY"], "UNDO_DEDUCTION" => "Y", "EMULATE" => "N", "PRODUCT_RESERVED" => $arItem["FIELDS"]["PRODUCT_RESERVED"], "STORE_DATA" => $arItem["FIELDS"]["STORE_DATA"]);
                     } else {
                         $arFields = array("PRODUCT_ID" => $arItem["PRODUCT_ID"], "QUANTITY" => $arItem["QUANTITY"], "UNDO_DEDUCTION" => "Y", "PRODUCT_RESERVED" => $arItem["FIELDS"]["PRODUCT_RESERVED"], "EMULATE" => "N");
                     }
                     if (defined("SALE_DEBUG") && SALE_DEBUG) {
                         CSaleHelper::WriteToLog("Call ::DeductProduct - Revert deduction", array("storesCount" => $storesCount, "arFields" => $arFields), "OD13");
                     }
                     $res = $productProvider::DeductProduct($arFields);
                     if ($res["RESULT"]) {
                         CSaleBasket::Update($arItem["ID"], array("DEDUCTED" => "N"));
                     }
                 }
             }
             $arResult["RESULT"] = false;
         }
     } else {
         $arResult["RESULT"] = false;
     }
     if (defined("SALE_DEBUG") && SALE_DEBUG) {
         CSaleHelper::WriteToLog("OrderDeduction - result", array("arResult" => $arResult), "OD14");
     }
     return $arResult;
 }
Example #8
0
$weight = 0;
$price = 0;
$price_total = 0;
$arProdIds = array();
//http://jabber.bx/view.php?id=37744
$arProdIdsPrIds = array();
$useStores = false;
while ($arBasket = $dbBasket->Fetch()) {
    $arProdIds[] = $arBasket["PRODUCT_ID"];
    $arProdIdsPrIds[$arBasket["PRODUCT_ID"]] = $arBasket["ID"];
    $arBasket["BALANCE"] = "0";
    $arBasket["STORES"] = array();
    $arBasket["HAS_SAVED_QUANTITY"] = "N";
    $arBasket["HAS_SAVED_BARCODES"] = false;
    /** @var $productProvider IBXSaleProductProvider */
    if ($productProvider = CSaleBasket::GetProductProvider($arBasket)) {
        $storeCount = $productProvider::GetStoresCount(array("SITE_ID" => $LID));
        if ($storeCount > 0) {
            if ($arProductStore = $productProvider::GetProductStores(array("PRODUCT_ID" => $arBasket["PRODUCT_ID"], "SITE_ID" => $LID, 'BASKET_ID' => $arBasket['ID']))) {
                foreach ($arProductStore as $arStore) {
                    $arBasket["STORES"][$arStore["STORE_ID"]] = $arStore;
                }
                if (!$useStores && $storeCount != -1) {
                    $useStores = true;
                }
                // if barcodes/store quantity are already saved for this product,
                // then check if barcodes are still valid and save them to the store array
                $ind = 0;
                $dbres = CSaleStoreBarcode::GetList(array(), array("BASKET_ID" => $arBasket["ID"]), false, false, array("ID", "BASKET_ID", "BARCODE", "STORE_ID", "ORDER_ID", "QUANTITY", "DEDUCTED"));
                while ($arRes = $dbres->GetNext()) {
                    $arCheckBarcodeFields = array("BARCODE" => $arRes["BARCODE"], "PRODUCT_ID" => $arBasket["PRODUCT_ID"], "ORDER_ID" => $arParams["ORDER_ID"]);
Example #9
0
	function UpdateBasketPrices($fuserID, $siteID)
	{
		$fuserID = intval($fuserID);
		if (0 >= $fuserID)
			return false;
		if(strlen($siteID) <= 0)
			$siteID = SITE_ID;

		$dbBasketItems = CSaleBasket::GetList(
			array("ALL_PRICE" => "DESC"),
			array(
				"FUSER_ID" => $fuserID,
				"LID" => $siteID,
				"ORDER_ID" => "NULL",
				"SUBSCRIBE" => "N"
			),
			false,
			false,
			array("ID", "CALLBACK_FUNC", "MODULE", "PRODUCT_ID", "QUANTITY", "PRODUCT_PROVIDER_CLASS", "CAN_BUY", "DELAY", "NOTES")
		);
		while ($arItem = $dbBasketItems->Fetch())
		{
			$arFields = false;
			$arItem['CALLBACK_FUNC'] = strval($arItem['CALLBACK_FUNC']);
			$arItem['PRODUCT_PROVIDER_CLASS'] = strval($arItem['PRODUCT_PROVIDER_CLASS']);
			if ('' != $arItem['PRODUCT_PROVIDER_CLASS'] || '' != $arItem['CALLBACK_FUNC'])
			{
				$arItem["MODULE"] = strval($arItem["MODULE"]);
				$arItem['PRODUCT_ID'] = intval($arItem['PRODUCT_ID']);
				$arItem['QUANTITY'] = floatval($arItem['QUANTITY']);

				if ($productProvider = CSaleBasket::GetProductProvider($arItem))
				{
					$arFields = $productProvider::GetProductData(array(
						"PRODUCT_ID" => $arItem["PRODUCT_ID"],
						"QUANTITY"   => $arItem["QUANTITY"],
						"RENEWAL"    => "N",
						"CHECK_COUPONS" => ('Y' == $arItem['CAN_BUY'] && 'N' == $arItem['DELAY'] ? 'Y' : 'N'),
						"BASKET_ID" => $arItem["ID"],
						"NOTES" => $arItem["NOTES"]
					));
				}
				else
				{
					$arFields = CSaleBasket::ExecuteCallbackFunction(
						$arItem["CALLBACK_FUNC"],
						$arItem["MODULE"],
						$arItem["PRODUCT_ID"],
						$arItem["QUANTITY"],
						"N"
					);
				}

				if (!empty($arFields) && is_array($arFields))
				{
					$arFields["CAN_BUY"] = "Y";
				}
				else
				{
					$arFields = array('CAN_BUY' => 'N');
				}

				CSaleBasket::Update($arItem['ID'], $arFields);
			}
		}
	}
Example #10
0
 /**
  * @param $productId
  * @param $quantity
  * @param $userId
  * @param $LID
  * @param $userColumns
  * @param string $tmpId we can suggest that this mean the set_item
  * @return array
  * @throws Main\LoaderException
  */
 protected function getProductDataToFillBasket($productId, $quantity, $userId, $LID, $userColumns, $tmpId = "")
 {
     $isSetItem = $tmpId != "";
     if (self::$catalogIncluded === null) {
         self::$catalogIncluded = Main\Loader::includeModule('catalog');
     }
     if (!self::$catalogIncluded) {
         return array();
     }
     $arParams = array();
     static $proxyIblockElement = array();
     static $proxyCatalogMeasure = array();
     static $proxyParent = array();
     static $proxyIblockProperty = array();
     static $proxyProductData = array();
     static $proxyCatalogProduct = array();
     static $proxyCatalogMeasureRatio = array();
     $productId = (int) $productId;
     if ($productId <= 0) {
         return $arParams;
     }
     if (!empty($proxyIblockElement[$productId])) {
         $iblockId = $proxyIblockElement[$productId];
     } else {
         $iblockId = (int) \CIBlockElement::getIBlockByID($productId);
         if ($iblockId > 0) {
             $proxyIblockElement[$productId] = $iblockId;
         }
     }
     if ($iblockId <= 0) {
         return $arParams;
     }
     $arSku2Parent = array();
     $arElementId = array();
     $arElementId[] = $productId;
     $proxyParentKey = $productId . "|" . $iblockId;
     if (!empty($proxyParent[$proxyParentKey]) && is_array($proxyParent[$proxyParentKey])) {
         $arParent = $proxyParent[$proxyParentKey];
     } else {
         $arParent = \CCatalogSku::getProductInfo($productId, $iblockId);
         $proxyParent[$proxyParentKey] = $arParent;
     }
     if ($arParent) {
         $arElementId[] = $arParent["ID"];
         $arSku2Parent[$productId] = $arParent["ID"];
     }
     $arPropertyInfo = array();
     $userColumns = (string) $userColumns;
     $arUserColumns = $userColumns != '' ? explode(",", $userColumns) : array();
     foreach ($arUserColumns as $key => $column) {
         if (strncmp($column, 'PROPERTY_', 9) != 0) {
             unset($arUserColumns[$key]);
         } else {
             $propertyCode = substr($column, 9);
             if ($propertyCode == '') {
                 unset($arUserColumns[$key]);
                 continue;
             }
             if (!empty($proxyIblockProperty[$propertyCode]) && is_array($proxyIblockProperty[$propertyCode])) {
                 $arPropertyInfo[$column] = $proxyIblockProperty[$propertyCode];
             } else {
                 $dbres = \CIBlockProperty::GetList(array(), array("CODE" => $propertyCode));
                 if ($arPropData = $dbres->GetNext()) {
                     $arPropertyInfo[$column] = $arPropData;
                     $proxyIblockProperty[$propertyCode] = $arPropData;
                 }
             }
         }
     }
     $arSelect = array_merge(array("ID", "NAME", "IBLOCK_ID", "IBLOCK_SECTION_ID", "DETAIL_PICTURE", "PREVIEW_PICTURE", "XML_ID", "IBLOCK_XML_ID"), $arUserColumns);
     $proxyProductDataKey = md5(join('|', $arElementId) . "_" . join('|', $arSelect));
     if (!empty($proxyProductData[$proxyProductDataKey]) && is_array($proxyProductData[$proxyProductDataKey])) {
         $arProductData = $proxyProductData[$proxyProductDataKey];
     } else {
         $arProductData = getProductProps($arElementId, $arSelect);
         $proxyProductData[$proxyProductDataKey] = $arProductData;
     }
     $defaultMeasure = \CCatalogMeasure::getDefaultMeasure(true, true);
     if (!empty($arProductData)) {
         $arElementInfo = array();
         foreach ($arProductData as $elemId => &$arElement) {
             foreach ($arElement as $key => $value) {
                 if (strncmp($key, 'PROPERTY_', 9) == 0 && substr($key, -6) == "_VALUE") {
                     $columnCode = str_replace("_VALUE", "", $key);
                     $arElement[$key] = getIblockPropInfo($value, $arPropertyInfo[$columnCode], array("WIDTH" => 90, "HEIGHT" => 90));
                 }
             }
         }
         unset($arElement);
         if (isset($arProductData[$productId])) {
             $arElementInfo = $arProductData[$productId];
         }
         if (isset($arSku2Parent[$productId])) {
             $arParent = $arProductData[$arSku2Parent[$productId]];
         }
         if (!empty($arSku2Parent)) {
             foreach ($arUserColumns as $field) {
                 $fieldVal = $field . "_VALUE";
                 $parentId = $arSku2Parent[$productId];
                 if ((!isset($arElementInfo[$fieldVal]) || isset($arElementInfo[$fieldVal]) && strlen($arElementInfo[$fieldVal]) == 0) && (isset($arProductData[$parentId][$fieldVal]) && !empty($arProductData[$parentId][$fieldVal]))) {
                     $arElementInfo[$fieldVal] = $arProductData[$parentId][$fieldVal];
                 }
             }
             if (strpos($arElementInfo["~XML_ID"], '#') === false) {
                 $arElementInfo["~XML_ID"] = $arParent['~XML_ID'] . '#' . $arElementInfo["~XML_ID"];
             }
         }
         $arElementInfo["MODULE"] = "catalog";
         $arElementInfo["PRODUCT_PROVIDER_CLASS"] = "CCatalogProductProvider";
         $arElementInfo["PRODUCT_ID"] = $arElementInfo["ID"];
         if ($arElementInfo["IBLOCK_ID"] > 0) {
             $arElementInfo["EDIT_PAGE_URL"] = \CIBlock::GetAdminElementEditLink($arElementInfo["IBLOCK_ID"], $arElementInfo["PRODUCT_ID"], array("find_section_section" => $arElementInfo["IBLOCK_SECTION_ID"], 'WF' => 'Y'));
         }
         static $buyersGroups = array();
         if (empty($buyersGroups[$userId])) {
             $buyersGroups[$userId] = \CUser::getUserGroup($userId);
         }
         $arBuyerGroups = $buyersGroups[$userId];
         // price
         $currentVatMode = \CCatalogProduct::getPriceVatIncludeMode();
         $currentUseDiscount = \CCatalogProduct::getUseDiscount();
         \CCatalogProduct::setUseDiscount(!$isSetItem);
         \CCatalogProduct::setPriceVatIncludeMode(true);
         \CCatalogProduct::setUsedCurrency(Sale\Internals\SiteCurrencyTable::getSiteCurrency($LID));
         $arPrice = \CCatalogProduct::getOptimalPrice($arElementInfo["ID"], 1, $arBuyerGroups, "N", array(), $LID);
         \CCatalogProduct::clearUsedCurrency();
         \CCatalogProduct::setPriceVatIncludeMode($currentVatMode);
         \CCatalogProduct::setUseDiscount($currentUseDiscount);
         unset($currentUseDiscount, $currentVatMode);
         $currentPrice = $arPrice['RESULT_PRICE']['DISCOUNT_PRICE'];
         $arElementInfo['PRICE'] = $currentPrice;
         $arElementInfo['CURRENCY'] = $arPrice['RESULT_PRICE']['CURRENCY'];
         $currentTotalPrice = $arPrice['RESULT_PRICE']['BASE_PRICE'];
         $arProduct = array();
         if (!empty($proxyCatalogProduct[$productId]) && is_array($proxyCatalogProduct[$productId])) {
             $arProduct = $proxyCatalogProduct[$productId];
         } else {
             $rsProducts = \CCatalogProduct::getList(array(), array('ID' => $productId), false, false, array('ID', 'QUANTITY', 'WEIGHT', 'MEASURE', 'TYPE', 'BARCODE_MULTI'));
             if ($arProduct = $rsProducts->Fetch()) {
                 $proxyCatalogProduct[$productId] = $arProduct;
             }
         }
         if (empty($arProduct) || !is_array($arProduct)) {
             return array();
         }
         $balance = floatval($arProduct["QUANTITY"]);
         // sku props
         $arSkuData = array();
         $arProps[] = array("NAME" => "Catalog XML_ID", "CODE" => "CATALOG.XML_ID", "VALUE" => $arElementInfo['~IBLOCK_XML_ID']);
         static $proxySkuProperty = array();
         if (!empty($proxySkuProperty[$productId]) && is_array($proxySkuProperty[$productId])) {
             $arSkuProperty = $proxySkuProperty[$productId];
         } else {
             $arSkuProperty = \CSaleProduct::GetProductSkuProps($productId, '', true);
             $proxySkuProperty[$productId] = $arSkuProperty;
         }
         if (!empty($arSkuProperty)) {
             foreach ($arSkuProperty as &$val) {
                 $arSkuData[] = array('NAME' => $val['NAME'], 'VALUE' => $val['VALUE'], 'CODE' => $val['CODE']);
             }
             unset($val);
         }
         $arSkuData[] = array("NAME" => "Product XML_ID", "CODE" => "PRODUCT.XML_ID", "VALUE" => $arElementInfo["~XML_ID"]);
         $arElementInfo["WEIGHT"] = $arProduct["WEIGHT"];
         // measure
         $arElementInfo["MEASURE_TEXT"] = "";
         $arElementInfo["MEASURE_CODE"] = 0;
         if ((int) $arProduct["MEASURE"] > 0) {
             if (!empty($proxyCatalogMeasure[$arProduct["MEASURE"]]) && is_array($proxyCatalogMeasure[$arProduct["MEASURE"]])) {
                 $arMeasure = $proxyCatalogMeasure[$arProduct["MEASURE"]];
             } else {
                 $dbMeasure = \CCatalogMeasure::GetList(array(), array("ID" => intval($arProduct["MEASURE"])), false, false, array("ID", "SYMBOL_RUS", "SYMBOL_INTL"));
                 if ($arMeasure = $dbMeasure->Fetch()) {
                     $proxyCatalogMeasure[$arProduct["MEASURE"]] = $arMeasure;
                 }
             }
             if (!empty($arMeasure) && is_array($arMeasure)) {
                 $arElementInfo["MEASURE_TEXT"] = $arMeasure["SYMBOL_RUS"] != '' ? $arMeasure["SYMBOL_RUS"] : $arMeasure["SYMBOL_INTL"];
                 $arElementInfo["MEASURE_CODE"] = $arMeasure["CODE"];
             }
         }
         if ($arElementInfo["MEASURE_TEXT"] == '') {
             $arElementInfo["MEASURE_TEXT"] = $defaultMeasure["SYMBOL_RUS"] != '' ? $defaultMeasure["SYMBOL_RUS"] : $defaultMeasure["SYMBOL_INTL"];
         }
         // ratio
         $arElementInfo["RATIO"] = 1;
         if (!empty($proxyCatalogMeasureRatio[$productId]) && is_array($proxyCatalogMeasureRatio[$productId])) {
             $arRatio = $proxyCatalogMeasureRatio[$productId];
         } else {
             $dbratio = \CCatalogMeasureRatio::GetList(array(), array("PRODUCT_ID" => $productId));
             if ($arRatio = $dbratio->Fetch()) {
                 $proxyCatalogMeasureRatio[$productId] = $arRatio;
             }
         }
         if (!empty($arRatio) && is_array($arRatio)) {
             $arElementInfo["RATIO"] = $arRatio["RATIO"];
         }
         // image
         $imgCode = '';
         $imgUrl = '';
         if ($arElementInfo["PREVIEW_PICTURE"] > 0) {
             $imgCode = $arElementInfo["PREVIEW_PICTURE"];
         } elseif ($arElementInfo["DETAIL_PICTURE"] > 0) {
             $imgCode = $arElementInfo["DETAIL_PICTURE"];
         }
         if ($imgCode == "" && count($arParent) > 0) {
             if ($arParent["PREVIEW_PICTURE"] > 0) {
                 $imgCode = $arParent["PREVIEW_PICTURE"];
             } elseif ($arParent["DETAIL_PICTURE"] > 0) {
                 $imgCode = $arParent["DETAIL_PICTURE"];
             }
         }
         if ($imgCode > 0) {
             $arFile = \CFile::GetFileArray($imgCode);
             $arImgProduct = \CFile::ResizeImageGet($arFile, array('width' => 80, 'height' => 80), BX_RESIZE_IMAGE_PROPORTIONAL, false, false);
             if (is_array($arImgProduct)) {
                 $imgUrl = $arImgProduct["src"];
             }
         }
         $arSetInfo = array();
         $arStores = array();
         /** @var $productProvider IBXSaleProductProvider */
         if ($productProvider = \CSaleBasket::GetProductProvider(array("MODULE" => $arElementInfo["MODULE"], "PRODUCT_PROVIDER_CLASS" => $arElementInfo["PRODUCT_PROVIDER_CLASS"]))) {
             // get set items if it is set
             if ($arProduct["TYPE"] == \CCatalogProduct::TYPE_SET) {
                 if (method_exists($productProvider, "GetSetItems")) {
                     $arSets = $productProvider::GetSetItems($productId, \CSaleBasket::TYPE_SET);
                     if ($tmpId == "") {
                         $tmpId = randString(7);
                     }
                     if (!empty($arSets)) {
                         foreach ($arSets as $arSetData) {
                             foreach ($arSetData["ITEMS"] as $setItem) {
                                 $arSetItemParams = self::getProductDataToFillBasket($setItem["PRODUCT_ID"], $setItem["QUANTITY"], $userId, $LID, $userColumns, $tmpId);
                                 // recursive call
                                 // re-define some fields with set data values
                                 $arSetItemParams["PARENT_OFFER_ID"] = $productId;
                                 $arSetItemParams["OFFER_ID"] = $setItem["PRODUCT_ID"];
                                 $arSetItemParams["NAME"] = $setItem["NAME"];
                                 $arSetItemParams["MODULE"] = $setItem["MODULE"];
                                 $arSetItemParams["PRODUCT_PROVIDER_CLASS"] = $setItem["PRODUCT_PROVIDER_CLASS"];
                                 $arSetItemParams["QUANTITY"] = $setItem["QUANTITY"] * $quantity;
                                 $arSetItemParams["BARCODE_MULTI"] = $setItem["BARCODE_MULTI"];
                                 $arSetItemParams["PRODUCT_TYPE"] = $setItem["TYPE"];
                                 $arSetItemParams["WEIGHT"] = $setItem["WEIGHT"];
                                 $arSetItemParams["VAT_RATE"] = $setItem["VAT_RATE"];
                                 $arSetItemParams["SET_ITEMS"] = "";
                                 $arSetItemParams["OLD_PARENT_ID"] = $productId . "_tmp" . $tmpId;
                                 $arSetItemParams["IS_SET_ITEM"] = "Y";
                                 $arSetItemParams["IS_SET_PARENT"] = "N";
                                 $arSetItemParams["PROVIDER_DATA"] = serialize($setItem);
                                 $arSetInfo[] = $arSetItemParams;
                             }
                         }
                     }
                 }
             }
             // get stores
             $storeCount = $productProvider::GetStoresCount(array("SITE_ID" => $LID));
             // with exact SITE_ID or SITE_ID = NULL
             if ($storeCount > 0) {
                 if ($arProductStore = $productProvider::GetProductStores(array("PRODUCT_ID" => $productId, "SITE_ID" => $LID))) {
                     $arStores = $arProductStore;
                 }
             }
         }
         $currentTotalPrice = (double) $currentTotalPrice;
         // params array
         $arParams["OFFER_ID"] = $productId;
         $arParams["NAME"] = $arElementInfo["~NAME"];
         $arParams["EDIT_PAGE_URL"] = $arElementInfo["EDIT_PAGE_URL"];
         $arParams["DETAIL_PAGE_URL"] = htmlspecialcharsex($arElementInfo["~DETAIL_PAGE_URL"]);
         $arParams["PICTURE_URL"] = $imgUrl;
         $arParams["PRICE"] = floatval($arElementInfo["PRICE"]);
         $arParams["PRICE_BASE"] = $currentTotalPrice;
         $arParams["DIMENSIONS"] = serialize(array("WIDTH" => $arElementInfo["WIDTH"], "HEIGHT" => $arElementInfo["HEIGHT"], "LENGTH" => $arElementInfo["LENGTH"]));
         $arParams["QUANTITY"] = $quantity;
         $arParams["MODULE"] = $arElementInfo["MODULE"];
         $arParams["CURRENCY"] = $arElementInfo["CURRENCY"];
         $arParams["WEIGHT"] = $arElementInfo["WEIGHT"];
         $arParams["VAT_RATE"] = $arPrice["PRICE"]["VAT_RATE"];
         $arParams["PRICE_TYPE"] = $arPrice["PRICE"]["CATALOG_GROUP_NAME"];
         $arParams["AVAILABLE"] = $balance;
         $arParams["NOTES"] = !empty($arPrice["PRICE"]["CATALOG_GROUP_NAME"]) ? $arPrice["PRICE"]["CATALOG_GROUP_NAME"] : "";
         $arParams["CATALOG_XML_ID"] = $arElementInfo["~IBLOCK_XML_ID"];
         $arParams["PRODUCT_XML_ID"] = $arElementInfo["~XML_ID"];
         $arParams["PRODUCT_PROVIDER_CLASS"] = $arElementInfo["PRODUCT_PROVIDER_CLASS"];
         $arParams["PROPS"] = $arSkuData;
         $arParams["MEASURE_TEXT"] = $arElementInfo["MEASURE_TEXT"];
         $arParams["MEASURE_CODE"] = $arElementInfo["MEASURE_CODE"];
         $arParams["MEASURE_RATIO"] = $arElementInfo["RATIO"];
         $arParams["BARCODE_MULTI"] = $arProduct["BARCODE_MULTI"];
         $arParams["PRODUCT_TYPE"] = empty($arSetInfo) ? "" : \CSaleBasket::TYPE_SET;
         $arParams["OLD_PARENT_ID"] = empty($arSetInfo) ? "" : $productId . "_tmp" . $tmpId;
         $arParams["SET_ITEMS"] = $arSetInfo;
         $arParams["IS_SET_ITEM"] = "N";
         $arParams["IS_SET_PARENT"] = empty($arSetInfo) ? "N" : "Y";
         $arParams["STORES"] = empty($arSetInfo) ? $arStores : array();
         $arParams["PRODUCT_PROPS_VALUES"] = $arElementInfo;
         // along with other information also contains values of properties with correct keys (after getProductProps)
     }
     return $arParams;
 }
 if (!isset($_REQUEST["by"])) {
     $arViewSort = array("DATE_VISIT" => SORT_DESC);
 } else {
     $arViewSort[$_REQUEST["by"]] = $_REQUEST["order"] == "asc" ? SORT_ASC : SORT_DESC;
 }
 Bitrix\Main\Type\Collection::sortByColumn($arViewsData, $arViewSort);
 foreach ($arViewsData as $arViews) {
     $row =& $lAdmin_tab5->AddRow($arViews["PRODUCT_ID"], $arViews, '', '');
     $name = "[" . $arViews["PRODUCT_ID"] . "] <a href=\"" . $arViews["DETAIL_PAGE_URL"] . "\">" . $arViews["NAME"] . "</a>";
     if (floatVal($arViews["PRICE"]) <= 0) {
         $name .= "<div class=\"dont_can_buy\">(" . GetMessage('BUYER_DONT_CAN_BUY') . ")</div>";
     }
     $name .= "<input type=\"hidden\" name=\"table_id\" value=\"" . $sTableID_tab5 . "\">";
     // get set items
     /** @var $productProvider IBXSaleProductProvider */
     if ($productProvider = CSaleBasket::GetProductProvider($arViews)) {
         if (method_exists($productProvider, "GetSetItems")) {
             $arSets = $productProvider::GetSetItems($arViews["PRODUCT_ID"], CSaleBasket::TYPE_SET);
             if (!empty($arSets)) {
                 $name .= "<br/><a href=\"javascript:void(0);\" class=\"dashed-link show-set-link\" id=\"set_toggle_link_b3" . $arBasket["ID"] . "\" onclick=\"fToggleSetItems('b3" . $arBasket["ID"] . "', 'set_toggle_link_');\">" . GetMessage("BUYER_F_SHOW_SET") . "</a><br/>";
                 $name .= "<div class=\"set_item_b3" . $arBasket["ID"] . "\" style=\"display:none\">";
                 foreach ($arSets as $arSetData) {
                     foreach ($arSetData["ITEMS"] as $setItem) {
                         $name .= "<br/>[" . $setItem["ITEM_ID"] . "] <a style=\"font-style: italic\" href=" . $setItem["DETAIL_PAGE_URL"] . ">" . $setItem["NAME"] . "</a>";
                     }
                 }
                 $name .= "</div>";
             }
         }
     }
     $row->AddField("NAME", $name);
Example #12
0
				array("ID" => $arItem["PRODUCT_ID"]),
				false,
				false,
				$arSelect
			);

			if ($arElement = $dbRes->Fetch())
			{
				$bBasketUpdate = false;
				$arPropsValues["CML2_LINK"] = $arElement["PROPERTY_CML2_LINK_VALUE"];

				$newProductId = getProductByProps($arElement["IBLOCK_ID"], $arPropsValues);

				if ($newProductId > 0)
				{
					if ($productProvider = CSaleBasket::GetProductProvider($arItem))
					{
						$arFieldsTmp = $productProvider::GetProductData(array(
							"PRODUCT_ID" => $newProductId,
							"QUANTITY"   => $arItem['QUANTITY'],
							"RENEWAL"    => "N",
							"USER_ID"    => $USER->GetID(),
							"SITE_ID"    => SITE_ID,
							"BASKET_ID" => $arItem['ID'],
							"CHECK_QUANTITY" => "Y",
							"CHECK_PRICE" => "Y",
							"NOTES" => $arItem["NOTES"]
						));
					}
					elseif (isset($arItem["CALLBACK_FUNC"]) && !empty($arItem["CALLBACK_FUNC"]))
					{
Example #13
0
 /**
  * <p>Метод добавляет товар в корзину, если его ещё нет, и обновляет параметры товара с увеличением количества, если он уже находится в корзине. В массиве <b>arFields</b> перечисляются все параметры товара, которые нужны для работы модуля Интернет-магазина (т.е. этот модуль не зависит от других модулей и работает полностью самостоятельно). Метод динамичный.</p> <p>Интернет-магазин не зависит от других модулей, поэтому товары в корзину модуля продаж могут добавляться из любого места (например, из торгового каталога или со статической страницы). Для некоторых модулей существуют функции - оболочки, облегчающие добавление товара в корзину (например, для модуля <b>catalog</b> существуют функции <b>Add2Basket</b> и <b>Add2BasketByProductID</b>). </p>
  *
  *
  * @param array $arFields  Ассоциативный массив параметров элемента корзины, содержащий
  * следующие ключи: <ul> <li> <b>PRODUCT_ID</b> - уникальный в рамках модуля код
  * товара (обязательное поле);</li> <li> <b>PRODUCT_PRICE_ID</b> - ID (идентификатор)
  * конкретного ценового предложения товара, пришедшего в корзину.
  * Может быть использован в классе <a
  * href="http://dev.1c-bitrix.ru/api_help/catalog/classes/cprice/index.php">CPrice</a> модуля Catalog для
  * получения детальной информации о цене.</li> <li> <b> PRICE</b> - стоимость
  * единицы товара (обязательное поле);</li> <li> <b>CURRENCY</b> - валюта
  * стоимости единицы товара (обязательное поле), если валюта
  * отличается от базовой валюты для данного сайта, то стоимость
  * будет автоматически сконвертирована по текущему курсу;</li> <li>
  * <b>WEIGHT</b> - вес единицы товара;</li> <li> <b>QUANTITY</b> - количество единиц
  * товара;</li> <li> <b>LID</b> - сайт, на котором сделана покупка
  * (обязательное поле);</li> <li> <b>DELAY</b> - флаг "товар отложен" (Y/N);</li> <li>
  * <b>CAN_BUY</b> - флаг "товар можно купить" (Y/N) - может устанавливаться
  * автоматически про наличии функции обратного вызова для
  * поддержки актуальности корзины;</li> <li> <b>NAME</b> - название товара
  * (обязательное поле);</li> <li> <b>PRODUCT_XML_ID</b> - внешний код товара
  * (необходим при обмене заказами с 1С);</li> <li> <b>CATALOG_XML_ID</b> - внешний
  * код каталога (необходим при обмене заказами с 1С);</li> <li> <b>ORDER_ID</b> -
  * идентификатор заказа. Ключ будет пустым, если товар еще не
  * добавлен в заказ;</li> <li> <b>CALLBACK_FUNC<font color="#FF0000">*</font></b> - название
  * функции обратного вызова для поддержки актуальности корзины
  * (описание ниже);</li> <li> <b>MODULE</b> - модуль, добавляющий товар в
  * корзину;</li> <li> <b>NOTES</b> - особые заметки, например, тип цены;</li> <li>
  * <b>ORDER_CALLBACK_FUNC<font color="#FF0000">*</font></b> - название функции обратного
  * вызова для оформления заказа (описание ниже);</li> <li> <b>DETAIL_PAGE_URL</b> -
  * ссылка на страницу детального просмотра товара;</li> <li>
  * <b>CANCEL_CALLBACK_FUNC<font color="#FF0000">*</font></b> - название функции обратного
  * вызова для отмены заказа (описание ниже);</li> <li> <b>PAY_CALLBACK_FUNC<font
  * color="#FF0000">*</font></b> - название функции обратного вызова, которая
  * вызывается при установке флага "Доставка разрешена" заказа;</li> <li>
  * <b>FUSER_ID</b> - идентификатор пользователя интернет-магазина,
  * необязательный параметр, по умолчанию CSaleBasket::GetBasketUserID() (текущий
  * пользователь);</li> <li> <b>DISCOUNT_PRICE</b> - величина скидки;</li> <li>
  * <b>DISCOUNT_NAME</b> - название скидки;</li> <li> <b>DISCOUNT_VALUE</b> - размер скидки (в
  * процентах);</li> <li> <b>DISCOUNT_COUPON</b> - купон скидки;</li> <li> <b>PROPS</b> - массив
  * свойств товара, который сохраняется в корзине. Каждый элемент
  * этого массива является массивом следующего формата: <pre
  * class="syntax"><code>array("NAME" =&gt; "Название свойства", "CODE" =&gt; "Код свойства",
  * "VALUE" =&gt; "Значение свойства", "SORT" =&gt; "Индекс сортировки")</code></pre> </li>
  * <li> <b>PRODUCT_PROVIDER_CLASS<font color="#0000FF">**</font></b> - содержит имя класса,
  * реализующего интерфейс <b> IBXSaleProductProvider</b>. Торговый каталог
  * записывает в это поле имя класса <b>CCatalogProductProvider</b>. Если поле
  * пусто, то возникает попытка использовать старые поля:<b>CALLBACK_FUNC</b>,
  * <b>ORDER_CALLBACK_FUNC</b>, <b>CANCEL_CALLBACK_FUNC</b> и <b>PAY_CALLBACK_FUNC</b>.</li> </ul>
  *
  * @return int <p>Метод возвращает код элемента корзины, в который попал данный
  * товар.</p> <a name="examples"></a>
  *
  * <h4>Example</h4> 
  * <pre>
  * &lt;?<br>if (CModule::IncludeModule("sale"))<br>{<br>  $arFields = array(<br>    "PRODUCT_ID" =&gt; 51,<br>    "PRODUCT_PRICE_ID" =&gt; 0,<br>    "PRICE" =&gt; 138.54,<br>    "CURRENCY" =&gt; "RUB",<br>    "WEIGHT" =&gt; 530,<br>    "QUANTITY" =&gt; 1,<br>    "LID" =&gt; LANG,<br>    "DELAY" =&gt; "N",<br>    "CAN_BUY" =&gt; "Y",<br>    "NAME" =&gt; "Чемодан кожаный",<br>    "CALLBACK_FUNC" =&gt; "MyBasketCallback",<br>    "MODULE" =&gt; "my_module",<br>    "NOTES" =&gt; "",<br>    "ORDER_CALLBACK_FUNC" =&gt; "MyBasketOrderCallback",<br>    "DETAIL_PAGE_URL" =&gt; "/".LANG."/detail.php?ID=51"<br>  );<br><br>  $arProps = array();<br><br>  $arProps[] = array(<br>    "NAME" =&gt; "Цвет",<br>    "CODE" =&gt; "color",<br>    "VALUE" =&gt; "черный"<br>  );<br><br>  $arProps[] = array(<br>    "NAME" =&gt; "Размер",<br>    "VALUE" =&gt; "1.5 x 2.5"<br>  );<br><br>  $arFields["PROPS"] = $arProps;<br><br>  CSaleBasket::Add($arFields);<br>}<br>?&gt;<br>
  * 
  * 
  * 
  * //пример на проверку создания покупателя
  * 
  * $userId=XXX;//id пользователя
  * //получаем FUSER_ID, если покупатель для данного пользователя существует
  * $FUSER_ID=CSaleUser::GetList(array('USER_ID' =&gt; $userId));
  * //если покупателя нет - создаем его
  * if(!$FUSER_ID['ID'])                  
  *        $FUSER_ID['ID']=CSaleUser::_Add(array("USER_ID" =&gt; $userId)); //обратите внимание на нижнее подчеркивание перед Add
  * //если не получается создать покупателя - то тут уж ничего не поделаешь
  * if(!$FUSER_ID['ID']){         
  *  echo "Error while creating SaleUser";      
  *  die();      
  * }
  * $FUSER_ID=$FUSER_ID['ID'];
  * //теперь переменную $FUSER_ID можно использовать для добавления товаров в корзину пользователя с $userId.
  * 
  * 
  * Смотрите также:
  * 
  * <li><a href="/api_help/catalog/interface.php">Взаимодействие торгового каталога и магазина</a></li>
  * </pre>
  *
  *
  * @static
  * @link http://dev.1c-bitrix.ru/api_help/sale/classes/csalebasket/csalebasket__add.php
  * @author Bitrix
  */
 public static function Add($arFields)
 {
     global $DB, $APPLICATION;
     if (isset($arFields["ID"])) {
         unset($arFields["ID"]);
     }
     $isOrderConverted = \Bitrix\Main\Config\Option::get("main", "~sale_converted_15", 'N');
     CSaleBasket::Init();
     if (!CSaleBasket::CheckFields("ADD", $arFields)) {
         return false;
     }
     if (!array_key_exists('IGNORE_CALLBACK_FUNC', $arFields) || 'Y' != $arFields['IGNORE_CALLBACK_FUNC']) {
         if (array_key_exists("CALLBACK_FUNC", $arFields) && !empty($arFields["CALLBACK_FUNC"]) || array_key_exists("PRODUCT_PROVIDER_CLASS", $arFields) && !empty($arFields["PRODUCT_PROVIDER_CLASS"])) {
             /** @var $productProvider IBXSaleProductProvider */
             if ($productProvider = CSaleBasket::GetProductProvider(array("MODULE" => $arFields["MODULE"], "PRODUCT_PROVIDER_CLASS" => $arFields["PRODUCT_PROVIDER_CLASS"]))) {
                 $providerParams = array("PRODUCT_ID" => $arFields["PRODUCT_ID"], "QUANTITY" => $arFields["QUANTITY"], "RENEWAL" => $arFields["RENEWAL"], "USER_ID" => isset($arFields["USER_ID"]) ? $arFields["USER_ID"] : 0, "SITE_ID" => isset($arFields["LID"]) ? $arFields["LID"] : false);
                 if (isset($arFields['NOTES'])) {
                     $providerParams['NOTES'] = $arFields['NOTES'];
                 }
                 if (!$productProvider::GetProductData($providerParams)) {
                     return false;
                 }
             } else {
                 if (!CSaleBasket::ExecuteCallbackFunction($arFields["CALLBACK_FUNC"], $arFields["MODULE"], $arFields["PRODUCT_ID"], $arFields["QUANTITY"], $arFields["RENEWAL"], $arFields["USER_ID"], $arFields["LID"])) {
                     return false;
                 }
             }
         }
     }
     if ($isOrderConverted != "Y") {
         foreach (GetModuleEvents("sale", "OnBeforeBasketAdd", true) as $arEvent) {
             if (ExecuteModuleEventEx($arEvent, array(&$arFields)) === false) {
                 return false;
             }
         }
     }
     $bFound = false;
     $bEqAr = false;
     //TODO: is order converted?
     if ($isOrderConverted == "Y") {
         /** @var \Bitrix\Sale\BasketItem $basketItem */
         if (!($basketItem = \Bitrix\Sale\Compatible\BasketCompatibility::add($arFields))) {
             $APPLICATION->ThrowException(Localization\Loc::getMessage('BT_MOD_SALE_BASKET_ERR_ID_ABSENT'), "BASKET_ITEM");
             return false;
         }
         $ID = $basketItem->getId();
         $arFields['QUANTITY'] = $basketItem->getQuantity();
     } else {
         $boolProps = !empty($arFields["PROPS"]) && is_array($arFields["PROPS"]);
         // check if this item is already in the basket
         $arDuplicateFilter = array("FUSER_ID" => $arFields["FUSER_ID"], "PRODUCT_ID" => $arFields["PRODUCT_ID"], "LID" => $arFields["LID"], "ORDER_ID" => "NULL");
         if (!(isset($arFields["TYPE"]) && $arFields["TYPE"] == CSaleBasket::TYPE_SET)) {
             if (isset($arFields["SET_PARENT_ID"])) {
                 $arDuplicateFilter["SET_PARENT_ID"] = $arFields["SET_PARENT_ID"];
             } else {
                 $arDuplicateFilter["SET_PARENT_ID"] = "NULL";
             }
         }
         $db_res = CSaleBasket::GetList(array(), $arDuplicateFilter, false, false, array("ID", "QUANTITY"));
         while ($res = $db_res->Fetch()) {
             if (!$bEqAr) {
                 $arPropsCur = array();
                 $arPropsOld = array();
                 if ($boolProps) {
                     foreach ($arFields["PROPS"] as &$arProp) {
                         if (array_key_exists('VALUE', $arProp) && '' != $arProp["VALUE"]) {
                             $propID = '';
                             if (array_key_exists('CODE', $arProp) && '' != $arProp["CODE"]) {
                                 $propID = $arProp["CODE"];
                             } elseif (array_key_exists('NAME', $arProp) && '' != $arProp["NAME"]) {
                                 $propID = $arProp["NAME"];
                             }
                             if ('' == $propID) {
                                 continue;
                             }
                             $arPropsCur[$propID] = $arProp["VALUE"];
                         }
                     }
                     if (isset($arProp)) {
                         unset($arProp);
                     }
                 }
                 $dbProp = CSaleBasket::GetPropsList(array(), array("BASKET_ID" => $res["ID"]), false, false, array('NAME', 'VALUE', 'CODE'));
                 while ($arProp = $dbProp->Fetch()) {
                     if ('' != $arProp["VALUE"]) {
                         $propID = '';
                         if ('' != $arProp["CODE"]) {
                             $propID = $arProp["CODE"];
                         } elseif ('' != $arProp["NAME"]) {
                             $propID = $arProp["NAME"];
                         }
                         if ('' == $propID) {
                             continue;
                         }
                         $arPropsOld[$propID] = $arProp["VALUE"];
                     }
                 }
                 $bEqAr = false;
                 if (count($arPropsCur) == count($arPropsOld)) {
                     $bEqAr = true;
                     foreach ($arPropsCur as $key => $val) {
                         if (!array_key_exists($key, $arPropsOld) || $arPropsOld[$key] != $val) {
                             $bEqAr = false;
                             break;
                         }
                     }
                 }
                 if ($bEqAr) {
                     $ID = $res["ID"];
                     $arFields["QUANTITY"] += $res["QUANTITY"];
                     CSaleBasket::Update($ID, $arFields);
                     $bFound = true;
                     continue;
                 }
             }
         }
     }
     if (!$bFound) {
         //TODO: is order converted?
         if ($isOrderConverted != "Y") {
             $arInsert = $DB->PrepareInsert("b_sale_basket", $arFields);
             $strSql = "INSERT INTO b_sale_basket(" . $arInsert[0] . ", DATE_INSERT, DATE_UPDATE) VALUES(" . $arInsert[1] . ", " . $DB->GetNowFunction() . ", " . $DB->GetNowFunction() . ")";
             $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
             $ID = intval($DB->LastID());
             $boolOrder = false;
             if (isset($arFields['ORDER_ID'])) {
                 $boolOrder = 0 < (int) $arFields['ORDER_ID'];
             }
             if (!$boolOrder && !CSaleBasketHelper::isSetItem($arFields)) {
                 $siteID = isset($arFields["LID"]) ? $arFields["LID"] : SITE_ID;
                 $_SESSION["SALE_BASKET_NUM_PRODUCTS"][$siteID]++;
             }
             if ($boolProps) {
                 foreach ($arFields["PROPS"] as &$prop) {
                     if ('' != $prop["NAME"]) {
                         $arInsert = $DB->PrepareInsert("b_sale_basket_props", $prop);
                         $strSql = "INSERT INTO b_sale_basket_props(BASKET_ID, " . $arInsert[0] . ") VALUES(" . $ID . ", " . $arInsert[1] . ")";
                         $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
                     }
                 }
                 if (isset($prop)) {
                     unset($prop);
                 }
             }
             // if item is set parent
             if (isset($arFields["TYPE"]) && $arFields["TYPE"] == CSaleBasket::TYPE_SET) {
                 CSaleBasket::Update($ID, array("SET_PARENT_ID" => $ID));
                 if (!isset($arFields["MANUAL_SET_ITEMS_INSERTION"])) {
                     /** @var $productProvider IBXSaleProductProvider */
                     if ($productProvider = CSaleBasket::GetProductProvider($arFields)) {
                         if (method_exists($productProvider, "GetSetItems")) {
                             $arSets = $productProvider::GetSetItems($arFields["PRODUCT_ID"], CSaleBasket::TYPE_SET, array('BASKET_ID' => $ID));
                             if (is_array($arSets)) {
                                 foreach ($arSets as $arSetData) {
                                     foreach ($arSetData["ITEMS"] as $setItem) {
                                         $setItem["SET_PARENT_ID"] = $ID;
                                         $setItem["LID"] = $arFields["LID"];
                                         $setItem["QUANTITY"] = $setItem["QUANTITY"] * $arFields["QUANTITY"];
                                         $setItem['FUSER_ID'] = $arFields['FUSER_ID'];
                                         CSaleBasket::Add($setItem);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
         if ($boolOrder) {
             CSaleOrderChange::AddRecord($arFields["ORDER_ID"], "BASKET_ADDED", array("PRODUCT_ID" => $arFields["PRODUCT_ID"], "NAME" => $arFields["NAME"], "QUANTITY" => $arFields["QUANTITY"]));
         }
     }
     if ($isOrderConverted != "Y") {
         foreach (GetModuleEvents("sale", "OnBasketAdd", true) as $arEvent) {
             ExecuteModuleEventEx($arEvent, array($ID, $arFields));
         }
     }
     return $ID;
 }
Example #14
0
 function UpdateBasketPrices($fuserID, $siteID)
 {
     $fuserID = (int) $fuserID;
     if ($fuserID <= 0) {
         return false;
     }
     $siteID = (string) $siteID;
     if ($siteID == '') {
         $siteID = SITE_ID;
     }
     $isOrderConverted = \Bitrix\Main\Config\Option::get("main", "~sale_converted_15", 'N');
     DiscountCouponsManager::clearApply(false);
     $basketItems = array();
     /*
     if (!empty($arBasketItems) && is_array($arBasketItems))
     			{
     				foreach ($arBasketItems as &$basketItemData)
     				{
     					if (array_key_exists('MEASURE_RATIO', $basketItemData))
     					{
     						$basketItemQuantity = floatval($basketItemData['QUANTITY']);
     						$basketItemRatio = floatval($basketItemData['MEASURE_RATIO']);
     
     						$mod = roundEx(($basketItemQuantity / $basketItemRatio - intval($basketItemQuantity / $basketItemRatio)), 6);
     
     						if ($mod !== 0)
     						{
     							$basketItemData['QUANTITY'] = ceil(ceil($basketItemQuantity) / $basketItemRatio)* $basketItemRatio;
     							CSaleBasket::Update($basketItemData['ID'], array('QUANTITY' => $basketItemData['QUANTITY']));
     						}
     					}
     				}
     				unset($basketItemData);
     			}
     */
     $dbBasketItems = CSaleBasket::GetList(array("ALL_PRICE" => "DESC"), array("FUSER_ID" => $fuserID, "LID" => $siteID, "ORDER_ID" => "NULL", "SUBSCRIBE" => "N"), false, false, array("ID", "MODULE", "PRODUCT_ID", "QUANTITY", "CALLBACK_FUNC", "PRODUCT_PROVIDER_CLASS", "CAN_BUY", "DELAY", "NOTES", "TYPE", "SET_PARENT_ID"));
     while ($arItem = $dbBasketItems->Fetch()) {
         $basketItems[] = $arItem;
     }
     if (!empty($basketItems) && is_array($basketItems)) {
         $basketItems = getRatio($basketItems);
         foreach ($basketItems as $basketItem) {
             $fields = array();
             $basketItem['CALLBACK_FUNC'] = (string) $basketItem['CALLBACK_FUNC'];
             $basketItem['PRODUCT_PROVIDER_CLASS'] = (string) $basketItem['PRODUCT_PROVIDER_CLASS'];
             if (strval(trim($basketItem['PRODUCT_PROVIDER_CLASS'])) !== '' || strval(trim($basketItem['CALLBACK_FUNC'])) !== '') {
                 $basketItem['MODULE'] = (string) $basketItem['MODULE'];
                 $basketItem['PRODUCT_ID'] = (int) $basketItem['PRODUCT_ID'];
                 $basketItem['QUANTITY'] = (double) $basketItem['QUANTITY'];
                 if ($productProvider = CSaleBasket::GetProductProvider($basketItem)) {
                     $fields = $productProvider::GetProductData(array("PRODUCT_ID" => $basketItem["PRODUCT_ID"], "QUANTITY" => $basketItem["QUANTITY"], "RENEWAL" => "N", "CHECK_COUPONS" => 'Y' == $basketItem['CAN_BUY'] && 'N' == $basketItem['DELAY'] ? 'Y' : 'N', "CHECK_DISCOUNT" => CSaleBasketHelper::isSetItem($basketItem) ? 'N' : 'Y', "BASKET_ID" => $basketItem["ID"], "NOTES" => $basketItem["NOTES"]));
                 } else {
                     $fields = CSaleBasket::ExecuteCallbackFunction($basketItem["CALLBACK_FUNC"], $basketItem["MODULE"], $basketItem["PRODUCT_ID"], $basketItem["QUANTITY"], "N");
                 }
                 if (!empty($fields) && is_array($fields)) {
                     if ($isOrderConverted == 'Y' && $basketItem['DELAY'] == 'N') {
                         if (!Sale\Compatible\DiscountCompatibility::isInited()) {
                             Sale\Compatible\DiscountCompatibility::init();
                         }
                         if (Sale\Compatible\DiscountCompatibility::usedByClient()) {
                             Sale\Compatible\DiscountCompatibility::setBasketItemData($basketItem['ID'], $fields);
                         }
                     }
                     $fields['CAN_BUY'] = 'Y';
                     $fields['TYPE'] = (int) $basketItem['TYPE'];
                     $fields['SET_PARENT_ID'] = (int) $basketItem['SET_PARENT_ID'];
                 } else {
                     $fields = array('CAN_BUY' => 'N');
                 }
             }
             if (array_key_exists('MEASURE_RATIO', $basketItem)) {
                 $basketItemQuantity = floatval($basketItem['QUANTITY']);
                 $basketItemRatio = floatval($basketItem['MEASURE_RATIO']);
                 $mod = roundEx($basketItemQuantity / $basketItemRatio - intval($basketItemQuantity / $basketItemRatio), 6);
                 if ($mod != 0) {
                     $fields['QUANTITY'] = floor(ceil($basketItemQuantity) / $basketItemRatio) * $basketItemRatio;
                 }
             }
             if (!empty($fields) && is_array($fields)) {
                 CSaleBasket::Update($basketItem['ID'], $fields);
             }
         }
     }
     return true;
 }
Example #15
0
 function UpdateBasketPrices($fuserID, $siteID)
 {
     $fuserID = (int) $fuserID;
     if ($fuserID <= 0) {
         return false;
     }
     $siteID = (string) $siteID;
     if ($siteID == '') {
         $siteID = SITE_ID;
     }
     $dbBasketItems = CSaleBasket::GetList(array("ALL_PRICE" => "DESC"), array("FUSER_ID" => $fuserID, "LID" => $siteID, "ORDER_ID" => "NULL", "SUBSCRIBE" => "N"), false, false, array("ID", "MODULE", "PRODUCT_ID", "QUANTITY", "CALLBACK_FUNC", "PRODUCT_PROVIDER_CLASS", "CAN_BUY", "DELAY", "NOTES", "TYPE", "SET_PARENT_ID"));
     while ($arItem = $dbBasketItems->Fetch()) {
         $arFields = false;
         $arItem['CALLBACK_FUNC'] = (string) $arItem['CALLBACK_FUNC'];
         $arItem['PRODUCT_PROVIDER_CLASS'] = (string) $arItem['PRODUCT_PROVIDER_CLASS'];
         if ('' != $arItem['PRODUCT_PROVIDER_CLASS'] || '' != $arItem['CALLBACK_FUNC']) {
             $arItem['MODULE'] = (string) $arItem['MODULE'];
             $arItem['PRODUCT_ID'] = (int) $arItem['PRODUCT_ID'];
             $arItem['QUANTITY'] = (double) $arItem['QUANTITY'];
             if ($productProvider = CSaleBasket::GetProductProvider($arItem)) {
                 $arFields = $productProvider::GetProductData(array("PRODUCT_ID" => $arItem["PRODUCT_ID"], "QUANTITY" => $arItem["QUANTITY"], "RENEWAL" => "N", "CHECK_COUPONS" => 'Y' == $arItem['CAN_BUY'] && 'N' == $arItem['DELAY'] ? 'Y' : 'N', "BASKET_ID" => $arItem["ID"], "NOTES" => $arItem["NOTES"]));
             } else {
                 $arFields = CSaleBasket::ExecuteCallbackFunction($arItem["CALLBACK_FUNC"], $arItem["MODULE"], $arItem["PRODUCT_ID"], $arItem["QUANTITY"], "N");
             }
             if (!empty($arFields) && is_array($arFields)) {
                 $arFields['CAN_BUY'] = 'Y';
                 $arFields['TYPE'] = (int) $arItem['TYPE'];
                 $arFields['SET_PARENT_ID'] = (int) $arItem['SET_PARENT_ID'];
             } else {
                 $arFields = array('CAN_BUY' => 'N');
             }
             CSaleBasket::Update($arItem['ID'], $arFields);
         }
     }
     return true;
 }
Example #16
0
function getProductDataToFillBasket($productId, $quantity, $userId, $LID, $userColumns, $tmpId = "")
{
	if (!\Bitrix\Main\Loader::includeModule("catalog"))
		return array();

	$arParams = array();

	$productId = (int)$productId;
	if ($productId <= 0)
	{
		return $arParams;
	}
	$iblockId = (int)CIBlockElement::GetIBlockByID($productId);
	if ($iblockId <= 0)
	{
		return $arParams;
	}

	$arSku2Parent = array();
	$arElementId = array();

	$arElementId[] = $productId;
	$arParent = CCatalogSku::GetProductInfo($productId, $iblockId);
	if ($arParent)
	{
		$arElementId[] = $arParent["ID"];
		$arSku2Parent[$productId] = $arParent["ID"];
	}

	$arPropertyInfo = array();
	$userColumns = (string)$userColumns;
	$arUserColumns = ($userColumns != '') ? explode(",", $userColumns) : array();
	foreach ($arUserColumns as $key => $column)
	{
		if (strncmp($column, 'PROPERTY_', 9) != 0)
		{
			unset($arUserColumns[$key]);
		}
		else
		{
			$propertyCode = substr($column, 9);
			if ($propertyCode == '')
			{
				unset($arUserColumns[$key]);
				continue;
			}
			$dbres = CIBlockProperty::GetList(array(), array("CODE" => $propertyCode));
			if ($arPropData = $dbres->GetNext())
				$arPropertyInfo[$column] = $arPropData;
		}
	}

	$arSelect = array_merge(
		array("ID", "NAME", "LID", "IBLOCK_ID", "IBLOCK_SECTION_ID", "DETAIL_PICTURE", "PREVIEW_PICTURE", "DETAIL_PAGE_URL", "XML_ID", "IBLOCK_XML_ID"),
		$arUserColumns
	);

	$arProductData = getProductProps($arElementId, $arSelect);

	$defaultMeasure = CCatalogMeasure::getDefaultMeasure(true, true);

	if (!empty($arProductData))
	{
		$arElementInfo = array();
		foreach ($arProductData as $elemId => &$arElement)
		{
			foreach ($arElement as $key => $value)
			{
				if (strncmp($key, 'PROPERTY_', 9) == 0 && substr($key, -6) == "_VALUE")
				{
					$columnCode = str_replace("_VALUE", "", $key);
					$arElement[$key] = getIblockPropInfo($value, $arPropertyInfo[$columnCode], array("WIDTH" => 90, "HEIGHT" => 90));
				}
			}
		}
		unset($arElement);

		if (isset($arProductData[$productId]))
			$arElementInfo = $arProductData[$productId];

		if (isset( $arSku2Parent[$productId]))
			$arParent = $arProductData[$arSku2Parent[$productId]];

		if (!empty($arSku2Parent)) // if sku element doesn't have value of some property - we'll show parent element value instead
		{
			foreach ($arUserColumns as $field)
			{
				$fieldVal = $field."_VALUE";
				$parentId = $arSku2Parent[$productId];

				if ((!isset($arElementInfo[$fieldVal]) || (isset($arElementInfo[$fieldVal]) && strlen($arElementInfo[$fieldVal]) == 0))
					&& (isset($arProductData[$parentId][$fieldVal]) && !empty($arProductData[$parentId][$fieldVal]))) // can be array or string
				{
					$arElementInfo[$fieldVal] = $arProductData[$parentId][$fieldVal];
				}
			}
			if (strpos($arElementInfo["~XML_ID"], '#') === false)
			{
				$arElementInfo["~XML_ID"] = $arParent['~XML_ID'].'#'.$arElementInfo["~XML_ID"];
			}
		}

		$arElementInfo["MODULE"] = "catalog";
		$arElementInfo["PRODUCT_PROVIDER_CLASS"] = "CCatalogProductProvider";

		$arElementInfo["PRODUCT_ID"] = $arElementInfo["ID"];

		if ($arElementInfo["IBLOCK_ID"] > 0)
		{
			$arElementInfo["EDIT_PAGE_URL"] = CIBlock::GetAdminElementEditLink($arElementInfo["IBLOCK_ID"], $arElementInfo["PRODUCT_ID"], array(
				"find_section_section" => $arElementInfo["IBLOCK_SECTION_ID"],
				'WF' => 'Y',
			));
		}

		$arBuyerGroups = CUser::GetUserGroup($userId);

		// price
		$arPrice = CCatalogProduct::GetOptimalPrice($arElementInfo["ID"], 1, $arBuyerGroups, "N", array(), $LID);
		$currentPrice = $arPrice["DISCOUNT_PRICE"];
		$arElementInfo["PRICE"] = $currentPrice;
		$arElementInfo["CURRENCY"] = $arPrice["PRICE"]["CURRENCY"];
		$arElementInfo["DISCOUNT_PRICE"] = $arPrice["PRICE"]["PRICE"] - $arPrice["DISCOUNT_PRICE"];
		$currentTotalPrice = ($arElementInfo["PRICE"] + $arElementInfo["DISCOUNT_PRICE"]);
		$discountPercent = 0;
		if ($arElementInfo["DISCOUNT_PRICE"] > 0)
			$discountPercent = intval(($arElementInfo["DISCOUNT_PRICE"] * 100) / $currentTotalPrice);

		$rsProducts = CCatalogProduct::GetList(
			array(),
			array('ID' => $productId),
			false,
			false,
			array('ID', 'QUANTITY', 'WEIGHT', 'MEASURE', 'TYPE', 'BARCODE_MULTI')
		);
		if (!($arProduct = $rsProducts->Fetch()))
		{
			return array();
		}
		$balance = floatval($arProduct["QUANTITY"]);

		// sku props
		$arSkuData = array();
		$arProps[] = array(
			"NAME" => "Catalog XML_ID",
			"CODE" => "CATALOG.XML_ID",
			"VALUE" => $arElementInfo['~IBLOCK_XML_ID']
		);
		$arSkuProperty = CSaleProduct::GetProductSkuProps($productId, '', true);
		if (!empty($arSkuProperty))
		{
			foreach ($arSkuProperty as &$val)
			{
				$arSkuData[] = array(
					'NAME' => $val['NAME'],
					'VALUE' => $val['VALUE'],
					'CODE' => $val['CODE']
				);
			}
			unset($val);
		}
		$arSkuData[] = array(
			"NAME" => "Product XML_ID",
			"CODE" => "PRODUCT.XML_ID",
			"VALUE" => $arElementInfo["~XML_ID"]
		);

		// currency
		$arCurFormat = CCurrencyLang::GetCurrencyFormat($arElementInfo["CURRENCY"]);
		$priceValutaFormat = str_replace("#", "", $arCurFormat["FORMAT_STRING"]);

		$arElementInfo["WEIGHT"] = $arProduct["WEIGHT"];

		// measure
		$arElementInfo["MEASURE_TEXT"] = "";
		if ((int)$arProduct["MEASURE"] > 0)
		{
			$dbMeasure = CCatalogMeasure::GetList(array(), array("ID" => intval($arProduct["MEASURE"])), false, false, array("ID", "SYMBOL_RUS", "SYMBOL_INTL"));
			if ($arMeasure = $dbMeasure->Fetch())
				$arElementInfo["MEASURE_TEXT"] = ($arMeasure["SYMBOL_RUS"] != '' ? $arMeasure["SYMBOL_RUS"] : $arMeasure["SYMBOL_INTL"]);
		}
		if ($arElementInfo["MEASURE_TEXT"] == '')
		{
			$arElementInfo["MEASURE_TEXT"] = ($defaultMeasure["SYMBOL_RUS"] != '' ? $defaultMeasure["SYMBOL_RUS"] : $defaultMeasure["SYMBOL_INTL"]);
		}


		// ratio
		$arElementInfo["RATIO"] = 1;
		$dbratio = CCatalogMeasureRatio::GetList(array(), array("PRODUCT_ID" => $productId));
		if ($arRatio = $dbratio->Fetch())
			$arElementInfo["RATIO"] = $arRatio["RATIO"];

		// image
		if ($arElementInfo["PREVIEW_PICTURE"] > 0)
			$imgCode = $arElementInfo["PREVIEW_PICTURE"];
		elseif ($arElementInfo["DETAIL_PICTURE"] > 0)
			$imgCode = $arElementInfo["DETAIL_PICTURE"];

		if ($imgCode == "" && count($arParent) > 0)
		{
			if ($arParent["PREVIEW_PICTURE"] > 0)
				$imgCode = $arParent["PREVIEW_PICTURE"];
			elseif ($arParent["DETAIL_PICTURE"] > 0)
				$imgCode = $arParent["DETAIL_PICTURE"];
		}

		if ($imgCode > 0)
		{
			$arFile = CFile::GetFileArray($imgCode);
			$arImgProduct = CFile::ResizeImageGet($arFile, array('width'=>80, 'height'=>80), BX_RESIZE_IMAGE_PROPORTIONAL, false, false);
			if (is_array($arImgProduct))
				$imgUrl = $arImgProduct["src"];
		}

		$arSetInfo = array();
		$arStores = array();

		/** @var $productProvider IBXSaleProductProvider */
		if ($productProvider = CSaleBasket::GetProductProvider(array("MODULE" => $arElementInfo["MODULE"], "PRODUCT_PROVIDER_CLASS" => $arElementInfo["PRODUCT_PROVIDER_CLASS"])))
		{
			// get set items if it is set
			if ($arProduct["TYPE"] == CCatalogProduct::TYPE_SET)
			{
				if (method_exists($productProvider, "GetSetItems"))
				{
					$arSets = $productProvider::GetSetItems($productId, CSaleBasket::TYPE_SET);

					if ($tmpId == "")
						$tmpId = randString(7);

					if (!empty($arSets))
					{
						foreach ($arSets as $arSetData)
						{
							foreach ($arSetData["ITEMS"] as $setItem)
							{
								$arSetItemParams = getProductDataToFillBasket($setItem["PRODUCT_ID"], $setItem["QUANTITY"], $userId, $LID, $userColumns, $tmpId); // recursive call

								// re-define some fields with set data values
								$arSetItemParams["id"] = $setItem["PRODUCT_ID"];
								$arSetItemParams["name"] = $setItem["NAME"];
								$arSetItemParams["module"] = $setItem["MODULE"];
								$arSetItemParams["productProviderClass"] = $setItem["PRODUCT_PROVIDER_CLASS"];
								$arSetItemParams["url"] = $setItem["DETAIL_PAGE_URL"];
								$arSetItemParams["quantity"] = $setItem["QUANTITY"] * $quantity;
								$arSetItemParams["barcodeMulti"] = $setItem["BARCODE_MULTI"];
								$arSetItemParams["productType"] = $setItem["TYPE"];
								$arSetItemParams["weight"] = $setItem["WEIGHT"];
								$arSetItemParams["vatRate"] = $setItem["VAT_RATE"];
								$arSetItemParams["setItems"] = "";

								$arSetItemParams["setParentId"] = $productId."_tmp".$tmpId;
								$arSetItemParams["isSetItem"] = "Y";
								$arSetItemParams["isSetParent"] = "N";

								$arSetInfo[] = $arSetItemParams;
							}
						}
					}
				}
			}

			// get stores
			$storeCount = $productProvider::GetStoresCount(array("SITE_ID" => $LID)); // with exact SITE_ID or SITE_ID = NULL

			if ($storeCount > 0)
			{
				if ($arProductStore = $productProvider::GetProductStores(array("PRODUCT_ID" => $productId, "SITE_ID" => $LID)))
					$arStores = $arProductStore;
			}
		}

		$currentTotalPrice = (float)$currentTotalPrice;
		// params array
		$arParams["id"] = $productId;
		$arParams["name"] = $arElementInfo["~NAME"];
		$arParams["url"] = htmlspecialcharsex($arElementInfo["~DETAIL_PAGE_URL"]);
		$arParams["urlEdit"] = $arElementInfo["EDIT_PAGE_URL"];
		$arParams["urlImg"] = $imgUrl;
		$arParams["price"] = floatval($arElementInfo["PRICE"]);
		$arParams["priceBase"] = $currentTotalPrice;
		$arParams["priceBaseFormat"] = CCurrencyLang::CurrencyFormat($currentTotalPrice, $arElementInfo["CURRENCY"], false);
		$arParams["priceFormated"] = CCurrencyLang::CurrencyFormat(floatval($arElementInfo["PRICE"]), $arElementInfo["CURRENCY"], false);
		$arParams["valutaFormat"] = $priceValutaFormat;
		$arParams["dimensions"] = serialize(array("WIDTH" => $arElementInfo["WIDTH"], "HEIGHT" => $arElementInfo["HEIGHT"], "LENGTH" => $arElementInfo["LENGTH"]));
		$arParams["priceDiscount"] = floatval($arElementInfo["DISCOUNT_PRICE"]);
		$arParams["priceTotalFormated"] = CCurrencyLang::CurrencyFormat($currentTotalPrice, $arElementInfo["CURRENCY"], true);
		$arParams["discountPercent"] = $discountPercent;
		$arParams["summaFormated"] = CCurrencyLang::CurrencyFormat($arElementInfo["PRICE"], $arElementInfo["CURRENCY"], false);
		$arParams["quantity"] = $quantity;
		$arParams["module"] = $arElementInfo["MODULE"];
		$arParams["currency"] = $arElementInfo["CURRENCY"];
		$arParams["weight"] = $arElementInfo["WEIGHT"];
		$arParams["vatRate"] = $arPrice["PRICE"]["VAT_RATE"];
		$arParams["priceType"] = $arPrice["PRICE"]["CATALOG_GROUP_NAME"];
		$arParams["balance"] = $balance;
		$arParams["notes"] = (is_array($arPrice["PRICE"]) && array_key_exists("CATALOG_GROUP_NAME", $arPrice["PRICE"])) ? $arPrice["PRICE"]["CATALOG_GROUP_NAME"] : "";
		$arParams["catalogXmlID"] = $arElementInfo["~IBLOCK_XML_ID"];
		$arParams["productXmlID"] = $arElementInfo["~XML_ID"];
		$arParams["callback"] = "";
		$arParams["orderCallback"] = "";
		$arParams["cancelCallback"] = "";
		$arParams["payCallback"] = "";
		$arParams["productProviderClass"] = $arElementInfo["PRODUCT_PROVIDER_CLASS"];
		$arParams["skuProps"] = $arSkuData;
		$arParams["measureText"] = $arElementInfo["MEASURE_TEXT"];
		$arParams["ratio"] = $arElementInfo["RATIO"];
		$arParams["barcodeMulti"] = $arProduct["BARCODE_MULTI"];

		$arParams["productType"] = empty($arSetInfo) ? "" : CSaleBasket::TYPE_SET;
		$arParams["setParentId"] = empty($arSetInfo) ? "" : $productId."_tmp".$tmpId;

		$arParams["setItems"] = $arSetInfo;
		$arParams["isSetItem"] = "N";
		$arParams["isSetParent"] = empty($arSetInfo) ? "N" : "Y";

		$arParams["stores"] = empty($arSetInfo) ? $arStores : array();
		$arParams["productPropsValues"] = $arElementInfo; // along with other information also contains values of properties with correct keys (after getProductProps)
	}

	return $arParams;
}
Example #17
0
 /**
  * The function add viewed product
  *
  * @param array $arFields - params for add
  * @return true false
  */
 public static function Add($arFields)
 {
     global $DB;
     global $USER;
     global $APPLICATION;
     foreach (GetModuleEvents("sale", "OnBeforeViewedAdd", true) as $arEvent) {
         if (ExecuteModuleEventEx($arEvent, array(&$arFields)) === false) {
             return false;
         }
     }
     if (isset($arFields["ID"])) {
         unset($arFields["ID"]);
     }
     $arFields["PRODUCT_ID"] = IntVal($arFields["PRODUCT_ID"]);
     $arFields["USER_ID"] = IntVal($arFields["USER_ID"]);
     $arFields["FUSER_ID"] = IntVal($arFields["FUSER_ID"]);
     $arFields["IBLOCK_ID"] = IntVal($arFields["IBLOCK_ID"]);
     if (strlen($arFields["CALLBACK_FUNC"]) <= 0) {
         $arFields["CALLBACK_FUNC"] = "CatalogViewedProductCallback";
     }
     if (strlen($arFields["MODULE"]) <= 0) {
         $arFields["MODULE"] = "catalog";
     }
     if (strlen($arFields["PRODUCT_PROVIDER_CLASS"]) <= 0 && $arFields["MODULE"] == "catalog") {
         $arFields["PRODUCT_PROVIDER_CLASS"] = "CCatalogProductProvider";
     }
     if ($arFields["PRODUCT_ID"] <= 0) {
         return false;
     }
     if (strlen($arFields["LID"]) <= 0) {
         return false;
     }
     if (\Bitrix\Main\Loader::includeModule("catalog")) {
         if (\Bitrix\Main\Config\Option::get("sale", "viewed_capability", "") == "Y") {
             return \Bitrix\Catalog\CatalogViewedProductTable::refresh($arFields["PRODUCT_ID"], CSaleBasket::GetBasketUserID(), $arFields["LID"]);
         }
     }
     $arFilter = array();
     $arFilter["PRODUCT_ID"] = $arFields["PRODUCT_ID"];
     if ($arFields["USER_ID"] > 0) {
         $arFuserItems = CSaleUser::GetList(array("USER_ID" => $arFields["USER_ID"]));
         $FUSER_ID = $arFuserItems["ID"];
     } elseif (IntVal($arFields["FUSER_ID"]) > 0) {
         $FUSER_ID = $arFields["FUSER_ID"];
     } else {
         $FUSER_ID = CSaleBasket::GetBasketUserID();
     }
     $arFilter["FUSER_ID"] = $FUSER_ID;
     $arFields["FUSER_ID"] = $FUSER_ID;
     $db_res = CSaleViewedProduct::GetList(array(), $arFilter, false, false, array('ID'));
     if (!($arItems = $db_res->Fetch())) {
         if (CModule::IncludeModule('catalog')) {
             /** @var $productProvider IBXSaleProductProvider */
             if ($productProvider = CSaleBasket::GetProductProvider($arFields)) {
                 $arResultTmp = $productProvider::ViewProduct(array("PRODUCT_ID" => $arFields["PRODUCT_ID"], "USER_ID" => $arFields["USER_ID"], "SITE_ID" => $arFields["LID"]));
             } else {
                 $arResultTmp = CSaleBasket::ExecuteCallbackFunction($arFields["CALLBACK_FUNC"], $arFields["MODULE"], $arFields["PRODUCT_ID"], $arFields["USER_ID"], $arFields["LID"]);
             }
             if ($arResultTmp && count($arResultTmp) > 0) {
                 $arFields = array_merge($arFields, $arResultTmp);
             }
             if (strlen($arFields["NAME"]) <= 0) {
                 return false;
             }
             $arInsert = $DB->PrepareInsert("b_sale_viewed_product", $arFields);
             //chance deleted
             $rnd = mt_rand(0, 1000);
             if ($rnd < 100) {
                 $db_res = CSaleViewedProduct::GetList(array(), array("FUSER_ID" => $FUSER_ID), array("COUNT" => "ID"), false);
                 $arCount = $db_res->Fetch();
                 $viewedCount = COption::GetOptionString("sale", "viewed_count", "100");
                 if ($arCount["ID"] > IntVal($viewedCount)) {
                     $limit = $arCount["ID"] - $viewedCount + $viewedCount * 0.2;
                     CSaleViewedProduct::DeleteForUser($FUSER_ID, $limit);
                 }
             }
             $strSql = "INSERT INTO b_sale_viewed_product (" . $arInsert[0] . ", DATE_VISIT) VALUES(" . $arInsert[1] . ", " . $DB->GetNowFunction() . ")";
             $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
             $ID = IntVal($DB->LastID());
         }
     } else {
         $ID = IntVal($arItems["ID"]);
         $arFields["DATE_VISIT"] = $DB->GetNowFunction();
         $arInsert = $DB->PrepareInsert("b_sale_viewed_product", $arFields);
         CSaleViewedProduct::Update($ID, $arFields);
     }
     foreach (GetModuleEvents("sale", "OnViewedAdd", true) as $arEvent) {
         ExecuteModuleEventEx($arEvent, array($arFields));
     }
     return $ID;
 }
Example #18
0
 public function checkQuantity($arBasketItem, $desiredQuantity)
 {
     global $USER;
     $arResult = array();
     /** @var $productProvider IBXSaleProductProvider */
     if ($productProvider = CSaleBasket::GetProductProvider($arBasketItem)) {
         $arFieldsTmp = $productProvider::GetProductData(array("PRODUCT_ID" => $arBasketItem["PRODUCT_ID"], "QUANTITY" => $desiredQuantity, "RENEWAL" => "N", "USER_ID" => $USER->GetID(), "SITE_ID" => SITE_ID, "BASKET_ID" => $arBasketItem["ID"], "CHECK_QUANTITY" => "Y", "CHECK_PRICE" => "N", "NOTES" => $arBasketItem["NOTES"]));
     } elseif (isset($arBasketItem["CALLBACK_FUNC"]) && !empty($arBasketItem["CALLBACK_FUNC"])) {
         $arFieldsTmp = CSaleBasket::ExecuteCallbackFunction($arBasketItem["CALLBACK_FUNC"], $arBasketItem["MODULE"], $arBasketItem["PRODUCT_ID"], $desiredQuantity, "N", $USER->GetID(), SITE_ID);
     } else {
         return $arResult;
     }
     if (empty($arFieldsTmp) || !isset($arFieldsTmp["QUANTITY"])) {
         $arResult["ERROR"] = Loc::getMessage("SBB_PRODUCT_NOT_AVAILABLE", array("#PRODUCT#" => $arBasketItem["NAME"]));
     } elseif ($desiredQuantity > doubleval($arFieldsTmp["QUANTITY"])) {
         $arResult["ERROR"] = Loc::getMessage("SBB_PRODUCT_NOT_ENOUGH_QUANTITY", array("#PRODUCT#" => $arBasketItem["NAME"], "#NUMBER#" => $desiredQuantity));
     }
     return $arResult;
 }
Example #19
0
	/**
	 * <p>Метод осуществляет продление подписки с кодом ID.</p> <p><b>Примечание</b>. Метод использует внутреннюю транзакцию. Если у вас используется <b>MySQL</b> и <b>InnoDB</b>, и ранее была открыта транзакция, то ее необходимо закрыть до подключения метода.</p>
	 *
	 *
	 *
	 *
	 * @param int $ID  Код записи с информацией о продлении.
	 *
	 *
	 *
	 * @return bool <p>Метод возвращает <i>true</i> в случае успешного продления или <i>false</i>
	 * в случае ошибки.</p><br><br>
	 *
	 * @static
	 * @link http://dev.1c-bitrix.ru/api_help/sale/classes/csalerecurring/csalerecurring.nextpayment.php
	 * @author Bitrix
	 */
	public static function NextPayment($ID)
	{
		global $DB;
		global $USER;

		$ID = IntVal($ID);
		if ($ID <= 0)
		{
			$GLOBALS["APPLICATION"]->ThrowException(GetMessage("SKGR_NO_RECID"), "NO_RECORD_ID");
			return False;
		}

		$arRecur = CSaleRecurring::GetByID($ID);
		if (!$arRecur)
		{
			$GLOBALS["APPLICATION"]->ThrowException(str_replace("#ID#", $ID, GetMessage("SKGR_NO_RECID1")), "NO_RECORD");
			return False;
		}

		$arOrder = CSaleOrder::GetByID($arRecur["ORDER_ID"]);
		if (!$arOrder)
		{
			$GLOBALS["APPLICATION"]->ThrowException(str_replace("#ID#", $arRecur["ORDER_ID"], GetMessage("SKGR_NO_ORDER1")), "NO_ORDER");
			return False;
		}


		$bSuccess = True;
		$newOrderID = IntVal($arRecur["ORDER_ID"]);

		/** @var $productProvider IBXSaleProductProvider */
		if ($productProvider = CSaleBasket::GetProductProvider($arRecur))
		{
			$arProduct = $productProvider::RecurringOrderProduct(array(
				"PRODUCT_ID" => $arRecur["PRODUCT_ID"],
				"USER_ID"    => $arOrder["USER_ID"]
			));
		}
		else
		{
			$arProduct = CSaleRecurring::ExecuteCallbackFunction(
					$arRecur["CALLBACK_FUNC"],
					$arRecur["MODULE"],
					$arRecur["PRODUCT_ID"],
					$arOrder["USER_ID"]
				);
		}

		if (!$arProduct || !is_array($arProduct) || count($arProduct) <= 0)
		{
			CSaleRecurring::CancelRecurring($arRecur["ID"], "Y", "Product is not found");

			/*
			$arFields = array(
					"CANCELED" => "Y",
					"DATE_CANCELED" => Date(CDatabase::DateFormatToPHP(CLang::GetDateFormat("FULL", LANG))),
					"CANCELED_REASON" => "Product is not found"
				);
			CSaleRecurring::Update($arRecur["ID"], $arFields);
			*/
			//CSaleRecurring::Delete($arRecur["ID"]);

			return True;
		}

		if ($arProduct["WITHOUT_ORDER"] == "Y" || $arRecur["SUCCESS_PAYMENT"] == "Y")
		{
			$baseSiteCurrency = CSaleLang::GetLangCurrency($arOrder["LID"]);
			$productPrice = roundEx(CCurrencyRates::ConvertCurrency($arProduct["PRICE"], $arProduct["CURRENCY"], $baseSiteCurrency), SALE_VALUE_PRECISION);

			// Delivery
			$deliveryPrice = 0;
			$deliveryID = 0;
			$arOrder["DELIVERY_ID"] = IntVal($arOrder["DELIVERY_ID"]);
			if ($arOrder["DELIVERY_ID"] > 0)
			{
				$deliveryLocation = 0;
				$dbOrderPropValues = CSaleOrderPropsValue::GetList(
						array(),
						array(
								"ORDER_ID" => $arRecur["ORDER_ID"],
								"PROP_IS_LOCATION" => "Y"
							),
						false,
						false,
						array("VALUE")
					);
				if ($arOrderPropValues = $dbOrderPropValues->Fetch())
					$deliveryLocation = IntVal($arOrderPropValues["VALUE"]);

				$dbDelivery = CSaleDelivery::GetList(
						array("SORT" => "ASC", "NAME" => "ASC"),
						array(
								"LID" => $arOrder["LID"],
								"WEIGHT" => DoubleVal($arProduct["WEIGHT"]) * DoubleVal($arProduct["QUANTITY"]), // Changed by Sigurd, 2007-08-16
								"ORDER_PRICE" => $productPrice * DoubleVal($arProduct["QUANTITY"]),
								"ACTIVE" => "Y",
								"LOCATION" => $deliveryLocation
							)
					);
				while ($arDelivery = $dbDelivery->Fetch())
				{
					$deliveryPriceTmp = roundEx(CCurrencyRates::ConvertCurrency($arDelivery["PRICE"], $arDelivery["CURRENCY"], $baseSiteCurrency), SALE_VALUE_PRECISION);
					if (IntVal($arDelivery["ID"]) == $arOrder["DELIVERY_ID"])
					{
						$deliveryID = IntVal($arDelivery["ID"]);
						$deliveryPrice = $deliveryPriceTmp;
						break;
					}
					if ($deliveryPriceTmp < $deliveryPrice || $deliveryID <= 0)
					{
						$deliveryID = IntVal($arDelivery["ID"]);
						$deliveryPrice = $deliveryPriceTmp;
					}
				}

				if ($deliveryID <= 0)
				{
					$GLOBALS["APPLICATION"]->ThrowException(GetMessage("SKGR_NO_DELIVERY"), "NO_DELIVERY");
					return False;
				}
			}

			// Sale discounts
			$discount = 0;
			$discountPrice = $productPrice;
			$discountProduct = 0;
			$dbDiscount = CSaleDiscount::GetList(
					array("SORT" => "ASC"),
					array(
							"LID" => $arOrder["LID"],
							"ACTIVE" => "Y",
							"!>ACTIVE_FROM" => Date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL"))),
							"!<ACTIVE_TO" => Date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL"))),
							"<=PRICE_FROM" => $productPrice,
							">=PRICE_TO" => $productPrice,
							"USER_GROUPS" => $USER->GetUserGroup($arOrder['USER_ID']),
						)
				);
			if ($arDiscount = $dbDiscount->Fetch())
			{
				if ($arDiscount["DISCOUNT_TYPE"] == "P")
				{
					$discountProduct = roundEx($productPrice * $arDiscount["DISCOUNT_VALUE"] / 100, SALE_VALUE_PRECISION);
					$discount = roundEx($discountProduct * DoubleVal($arProduct["QUANTITY"]), SALE_VALUE_PRECISION); // Changed by Sigurd, 2007-08-16
					$discountPrice = $productPrice - $discountProduct;
				}
				else
				{
					$discountValue = CCurrencyRates::ConvertCurrency($arDiscount["DISCOUNT_VALUE"], $arDiscount["CURRENCY"], $baseSiteCurrency);
					$discountValue = roundEx($discountValue, SALE_VALUE_PRECISION);

					$discountProduct = roundEx(1.0 * $discountValue / DoubleVal($arProduct["QUANTITY"]), SALE_VALUE_PRECISION);// Changed by Sigurd, 2007-08-16
					$discount = roundEx($curDiscount * DoubleVal($arProduct["QUANTITY"]), SALE_VALUE_PRECISION);
					$discountPrice = $productPrice - $discountProduct;
				}
			}

			$bUseVat = false;
			$vatRate = 0;
			if(DoubleVal($arProduct["VAT_RATE"]) > 0)
			{
				$bUseVat = true;
				$vatRate = $arProduct["VAT_RATE"];
			}

			// Tax
			$arTaxExempt = array();
			$dbUserGroups = CUser::GetUserGroupEx($arOrder["USER_ID"]);
			while ($arUserGroups = $dbUserGroups->Fetch())
			{
				$dbTaxExemptTmp = CSaleTax::GetExemptList(array("GROUP_ID" => $arUserGroups["GROUP_ID"]));
				while ($arTaxExemptTmp = $dbTaxExemptTmp->Fetch())
				{
					$arTaxExemptTmp["TAX_ID"] = IntVal($arTaxExemptTmp["TAX_ID"]);
					if (!in_array($arTaxExemptTmp["TAX_ID"], $arTaxExempt))
						$arTaxExempt[] = $arTaxExemptTmp["TAX_ID"];
				}
			}

			$taxPrice = 0;
			$taxVatPrice = 0;
			if(!$bUseVat)
			{
				$taxLocation = 0;
				$dbOrderPropValues = CSaleOrderPropsValue::GetList(
						array(),
						array(
								"ORDER_ID" => $arRecur["ORDER_ID"],
								"PROP_IS_LOCATION4TAX" => "Y"
							),
						false,
						false,
						array("VALUE")
					);
				if ($arOrderPropValues = $dbOrderPropValues->Fetch())
					$taxLocation = IntVal($arOrderPropValues["VALUE"]);

				$arTaxList = array();
				$dbTaxRateTmp = CSaleTaxRate::GetList(
						array("APPLY_ORDER" => "ASC"),
						array(
								"LID" => $arOrder["LID"],
								"PERSON_TYPE_ID" => $arOrder["PERSON_TYPE_ID"],
								"ACTIVE" => "Y",
								"LOCATION" => $taxLocation
							)
					);
				while ($arTaxRateTmp = $dbTaxRateTmp->Fetch())
				{
					if (!in_array(IntVal($arTaxRateTmp["TAX_ID"]), $arTaxExempt))
					{
						$arTaxList[] = $arTaxRateTmp;
					}
				}
			}
			else
			{
				$arTaxList[] = Array(
							"ID" => 0,
							"TAX_NAME" => GetMessage("SKGR_VAT"),
							"IS_PERCENT" => "Y",
							"VALUE" => $vatRate*100,
							"VALUE_MONEY" => 0,
							"APPLY_ORDER" => 100,
							"IS_IN_PRICE" => "Y",
							"CODE" => "VAT"
				);
			}


			$arTaxSums = array();

			if (!empty($arTaxList))
			{
				if(!$bUseVat)
				{
					$taxPriceTmp = CSaleOrderTax::CountTaxes(
							$discountPrice * DoubleVal($arProduct["QUANTITY"]),
							$arTaxList,
							$baseSiteCurrency
						);

					for ($di = 0, $intCount = count($arTaxList); $di < $intCount; $di++)
					{
						$arTaxList[$di]["VALUE_MONEY"] += $arTaxList[$di]["TAX_VAL"];
					}

					for ($di = 0, $intCount = count($arTaxList); $di < $intCount; $di++)
					{
						$arTaxSums[$arTaxList[$di]["TAX_ID"]]["VALUE"] = $arTaxList[$di]["VALUE_MONEY"];
						$arTaxSums[$arTaxList[$di]["TAX_ID"]]["NAME"] = $arTaxList[$di]["NAME"];
						if ($arTaxList[$di]["IS_IN_PRICE"] != "Y")
						{
							$taxPrice += $arTaxList[$di]["VALUE_MONEY"];
						}
					}
				}
				else
				{
					$arTaxList[0]["VALUE_MONEY"] = (($discountPrice / ($vatRate +1)) * $vatRate) * DoubleVal($arProduct["QUANTITY"]);
					$taxVatPrice = $arTaxList[0]["VALUE_MONEY"];
				}
			}


			// Changed by Sigurd, 2007-08-16
			$totalOrderPrice = $discountPrice * DoubleVal($arProduct["QUANTITY"]) + $deliveryPrice + $taxPrice;

			$arProduct["WITHOUT_ORDER"] = (($arProduct["WITHOUT_ORDER"]=="Y") ? "Y" : "N");
			if ($arProduct["WITHOUT_ORDER"] == "N")
			{
				$DB->StartTransaction();

				// Saving
				$arSaleUser = CSaleUser::GetList(Array(), Array("USER_ID" => $arOrder["USER_ID"]));
				if(!empty($arSaleUser))
				{
					$currentFUser = $arSaleUser["ID"];
				}
				else
				{
					$currentFUser = CSaleUser::_Add(
							array(
									"=DATE_INSERT" => $DB->GetNowFunction(),
									"=DATE_UPDATE" => $DB->GetNowFunction(),
									"USER_ID" => $arOrder["USER_ID"]
								)
						);
				}

				$arFields = array(
						"FUSER_ID" => $currentFUser,
						"PRODUCT_ID" => $arProduct["PRODUCT_ID"],
						"PRODUCT_NAME" => $arProduct["PRODUCT_NAME"],
						"PRODUCT_URL" => $arProduct["PRODUCT_URL"],
						"PRODUCT_PRICE_ID" => $arProduct["PRODUCT_PRICE_ID"],
						"PRICE" => $arProduct["PRICE"],
						"CURRENCY" => $arProduct["CURRENCY"],
						"WEIGHT" => $arProduct["WEIGHT"],
						"QUANTITY" => $arProduct["QUANTITY"],
						"LID" => $arOrder["LID"],
						"DELAY" => "N",
						"CAN_BUY" => "Y",
						"NAME" => $arProduct["NAME"],
						"CALLBACK_FUNC" => $arProduct["CALLBACK_FUNC"],
						"ORDER_CALLBACK_FUNC" => $arProduct["ORDER_CALLBACK_FUNC"],
						"CANCEL_CALLBACK_FUNC" => $arProduct["CANCEL_CALLBACK_FUNC"],
						"PAY_CALLBACK_FUNC" => $arProduct["PAY_CALLBACK_FUNC"],
						"PRODUCT_PROVIDER_CLASS" => $arProduct["PRODUCT_PROVIDER_CLASS"],
						"MODULE" => $arRecur["MODULE"],
						"NOTES" => $arProduct["CATALOG_GROUP_NAME"],
						"DETAIL_PAGE_URL" => $arProduct["DETAIL_PAGE_URL"],
						"VATE_RATE" => $arProduct["VATE_RATE"],
						"PRODUCT_XML_ID" => $arProduct["PRODUCT_XML_ID"],
						"RENEWAL" => "Y"
					);

				$basketID = CSaleBasket::Add($arFields);

				$basketID = IntVal($basketID);
				if ($basketID <= 0)
					$bSuccess = False;

				if ($bSuccess)
				{
					if (CModule::IncludeModule("statistic"))
						CStatistic::Set_Event("eStore", "add2basket", $arFields["PRODUCT_ID"]);

					$arFields = array(
							"LID" => $arOrder["LID"],
							"PERSON_TYPE_ID" => $arOrder["PERSON_TYPE_ID"],
							"PAYED" => "N",
							"CANCELED" => "N",
							"STATUS_ID" => "N",
							"PRICE_DELIVERY" => $deliveryPrice,
							"ALLOW_DELIVERY" => "N",
							"PRICE" => $totalOrderPrice,
							"CURRENCY" => $baseSiteCurrency,
							"DISCOUNT_VALUE" => $discount,
							"USER_ID" => $arOrder["USER_ID"],
							"PAY_SYSTEM_ID" => $arOrder["PAY_SYSTEM_ID"],
							"DELIVERY_ID" => $deliveryID,
							"USER_DESCRIPTION" => $arOrder["USER_DESCRIPTION"],
							"TAX_VALUE" => (($bUseVat)? $taxVatPrice : $taxPrice),
							"STAT_GID" => $arOrder["STAT_GID"],
							"RECURRING_ID" => $arRecur["ID"]
						);

					$newOrderID = CSaleOrder::Add($arFields);

					$newOrderID = IntVal($newOrderID);
					if ($newOrderID <= 0)
						$bSuccess = False;
				}

				if ($bSuccess)
				{
					$arDiscounts = array();
					$arDiscounts[$basketID] = $discountProduct;
					CSaleBasket::OrderBasket($newOrderID, $currentFUser, $arOrder["LID"], $arDiscounts);
				}

				if ($bSuccess)
				{
					for ($it = 0, $intCount = count($arTaxList); $it < $intCount; $it++)
					{
						$arFields = array(
							"ORDER_ID" => $newOrderID,
							"TAX_NAME" => $arTaxList[$it]["TAX_NAME"],
							"IS_PERCENT" => $arTaxList[$it]["IS_PERCENT"],
							"VALUE" => ($arTaxList[$it]["IS_PERCENT"]=="Y") ? $arTaxList[$it]["VALUE"] : RoundEx(CCurrencyRates::ConvertCurrency($arTaxList[$it]["VALUE"], $arTaxList[$it]["CURRENCY"], $baseSiteCurrency), 2),
							"VALUE_MONEY" => $arTaxList[$it]["VALUE_MONEY"],
							"APPLY_ORDER" => $arTaxList[$it]["APPLY_ORDER"],
							"IS_IN_PRICE" => $arTaxList[$it]["IS_IN_PRICE"],
							"CODE" => $arTaxList[$it]["CODE"]
							);
						CSaleOrderTax::Add($arFields);
					}

					$dbOrderPropValues = CSaleOrderPropsValue::GetList(
							array(),
							array("ORDER_ID" => $arRecur["ORDER_ID"]),
							false,
							false,
							array("ORDER_PROPS_ID", "NAME", "CODE", "VALUE", "PROP_IS_PAYER", "PROP_IS_EMAIL")
						);
					while ($arOrderPropValues = $dbOrderPropValues->Fetch())
					{
						$arFields = array(
							"ORDER_ID" => $newOrderID,
							"ORDER_PROPS_ID" => $arOrderPropValues["ORDER_PROPS_ID"],
							"NAME" => $arOrderPropValues["NAME"],
							"CODE" => $arOrderPropValues["CODE"],
							"VALUE" => $arOrderPropValues["VALUE"]
							);
						CSaleOrderPropsValue::Add($arFields);

						if ($arOrderPropValues["PROP_IS_PAYER"] == "Y")
							$payerName = $arOrderPropValues["VALUE"];
						if ($arOrderPropValues["PROP_IS_EMAIL"] == "Y")
							$payerEMail = $arOrderPropValues["VALUE"];
					}
				}

				if ($bSuccess)
				{
					if (CModule::IncludeModule("statistic"))
						CStatistic::Set_Event("eStore", "order_create", $newOrderID);
				}

				if ($bSuccess)
				{
					$strOrderList = "";
					$dbBasketTmp = CSaleBasket::GetList(
						array("NAME" => "ASC"),
						array("ORDER_ID" => $newOrderID)
					);
					while ($arBasketTmp = $dbBasketTmp->Fetch())
					{
						$strOrderList .= $arBasketTmp["NAME"]." - ".$arBasketTmp["QUANTITY"]." ".GetMessage("SALE_QUANTITY_UNIT");
						$strOrderList .= "\n";
					}

					if (strlen($payerName) <= 0 || strlen($payerEMail) <= 0)
					{
						$dbUser = CUser::GetByID($arOrder["USER_ID"]);
						if ($arUser = $dbUser->Fetch())
						{
							if (strlen($payerName) <= 0)
								$payerName = $arUser["NAME"].((strlen($arUser["NAME"])<=0 || strlen($arUser["LAST_NAME"])<=0) ? "" : " ").$arUser["LAST_NAME"];
							if (strlen($payerEMail) <= 0)
								$payerEMail = $arUser["EMAIL"];
						}
					}

					$arFields = Array(
						"ORDER_ID" => $newOrderID,
						"ORDER_DATE" => Date($DB->DateFormatToPHP(CLang::GetDateFormat("SHORT", $arOrder["LID"]))),
						"ORDER_USER" => $payerName,
						"PRICE" => SaleFormatCurrency($totalOrderPrice, $baseSiteCurrency),
						"BCC" => COption::GetOptionString("sale", "order_email", "order@".$SERVER_NAME),
						"EMAIL" => $payerEMail,
						"ORDER_LIST" => $strOrderList,
						"SALE_EMAIL" => COption::GetOptionString("sale", "order_email", "order@".$SERVER_NAME)
					);
					$eventName = "SALE_NEW_ORDER_RECURRING";

					$bSend = true;
					foreach(GetModuleEvents("sale", "OnOrderRecurringSendEmail", true) as $arEvent)
					{
						if (ExecuteModuleEventEx($arEvent, Array($newOrderID, &$eventName, &$arFields))===false)
							$bSend = false;
					}

					if($bSend)
					{
						$event = new CEvent;
						$event->Send($eventName, $arOrder["LID"], $arFields, "N");
					}
				}

				if ($bSuccess)
					$DB->Commit();
				else
					$DB->Rollback();
			}
		}
		else
		{
			$totalOrderPrice = $arOrder["PRICE"];
			$baseSiteCurrency = $arOrder["CURRENCY"];
		}

		$res = False;
		if ($bSuccess)
		{
			$res = CSaleUserAccount::Pay($arOrder["USER_ID"], $totalOrderPrice, $baseSiteCurrency, $newOrderID, True);
			if ($res)
			{
				if ($arProduct["WITHOUT_ORDER"] == "N")
				{
					CSaleOrder::PayOrder($newOrderID, "Y", False, False, $arRecur["ID"]);
					CSaleOrder::DeliverOrder($newOrderID, "Y", $arRecur["ID"]);
					CSaleOrder::DeductOrder($newOrderID, "Y", "", true, array(), $arRecur["ID"]);
				}
				else
				{
					/** @var $productProvider IBXSaleProductProvider */
					if ($productProvider = CSaleBasket::GetProductProvider($arProduct))
					{
						$r = $productProvider::DeliverProduct(array(
							"PRODUCT_ID" => $arProduct["PRODUCT_ID"],
							"USER_ID"    => $arOrder["USER_ID"],
							"PAID"       => true
						));
					}
					else
					{
						$r = CSaleBasket::ExecuteCallbackFunction(
							$arProduct["PAY_CALLBACK_FUNC"],
							$arRecur["MODULE"],
							$arProduct["PRODUCT_ID"],
							$arOrder["USER_ID"],
							true
						);
					}
				}

				$arFields = array(
					"ORDER_ID" => $newOrderID,
					"PRODUCT_NAME" => $arProduct["PRODUCT_NAME"],
					"PRODUCT_URL" => $arProduct["PRODUCT_URL"],
					"PRICE_TYPE" => $arProduct["PRICE_TYPE"],
					"RECUR_SCHEME_TYPE" => $arProduct["RECUR_SCHEME_TYPE"],
					"RECUR_SCHEME_LENGTH" => $arProduct["RECUR_SCHEME_LENGTH"],
					"WITHOUT_ORDER" => $arProduct["WITHOUT_ORDER"],
					"PRIOR_DATE" => Date($GLOBALS["DB"]->DateFormatToPHP(CLang::GetDateFormat("FULL", SITE_ID))),
					"NEXT_DATE" => $arProduct["NEXT_DATE"],
					"REMAINING_ATTEMPTS" => (Defined("SALE_PROC_REC_ATTEMPTS") ? SALE_PROC_REC_ATTEMPTS : 3),
					"SUCCESS_PAYMENT" => "Y"
				);

				CSaleRecurring::Update($arRecur["ID"], $arFields);
			}
			else
			{
				$arFields = array(
						"ORDER_ID" => $newOrderID,
						"PRODUCT_NAME" => $arProduct["PRODUCT_NAME"],
						"PRODUCT_URL" => $arProduct["PRODUCT_URL"],
						"PRICE_TYPE" => $arProduct["PRICE_TYPE"],
						"RECUR_SCHEME_LENGTH" => $arProduct["RECUR_SCHEME_LENGTH"],
						"RECUR_SCHEME_TYPE" => $arProduct["RECUR_SCHEME_TYPE"],
						"WITHOUT_ORDER" => $arProduct["WITHOUT_ORDER"],
						"NEXT_DATE" => Date($GLOBALS["DB"]->DateFormatToPHP(CLang::GetDateFormat("FULL", SITE_ID)), time() + SALE_PROC_REC_TIME + CTimeZone::GetOffset()),
						"REMAINING_ATTEMPTS" => (IntVal($arRecur["REMAINING_ATTEMPTS"]) - 1),
						"SUCCESS_PAYMENT" => "N"
					);
				CSaleRecurring::Update($arRecur["ID"], $arFields);

				if ((IntVal($arRecur["REMAINING_ATTEMPTS"]) - 1) <= 0)
				{
					CSaleRecurring::CancelRecurring($arRecur["ID"], "Y", "Can't pay order");
					/*
					$arFields["CANCELED"] = "Y";
					$arFields["DATE_CANCELED"] = Date(CDatabase::DateFormatToPHP(CLang::GetDateFormat("FULL", LANG)));
					$arFields["CANCELED_REASON"] = "Can't pay order";
					*/
				}
			}
		}

		return $res;
	}