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; }
/** * 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');
/** * @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; }
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; }
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; }
/** * 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; }
$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"]);
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); } } }
/** * @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);
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"])) {
/** * <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" => "Название свойства", "CODE" => "Код свойства", * "VALUE" => "Значение свойства", "SORT" => "Индекс сортировки")</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> * <?<br>if (CModule::IncludeModule("sale"))<br>{<br> $arFields = array(<br> "PRODUCT_ID" => 51,<br> "PRODUCT_PRICE_ID" => 0,<br> "PRICE" => 138.54,<br> "CURRENCY" => "RUB",<br> "WEIGHT" => 530,<br> "QUANTITY" => 1,<br> "LID" => LANG,<br> "DELAY" => "N",<br> "CAN_BUY" => "Y",<br> "NAME" => "Чемодан кожаный",<br> "CALLBACK_FUNC" => "MyBasketCallback",<br> "MODULE" => "my_module",<br> "NOTES" => "",<br> "ORDER_CALLBACK_FUNC" => "MyBasketOrderCallback",<br> "DETAIL_PAGE_URL" => "/".LANG."/detail.php?ID=51"<br> );<br><br> $arProps = array();<br><br> $arProps[] = array(<br> "NAME" => "Цвет",<br> "CODE" => "color",<br> "VALUE" => "черный"<br> );<br><br> $arProps[] = array(<br> "NAME" => "Размер",<br> "VALUE" => "1.5 x 2.5"<br> );<br><br> $arFields["PROPS"] = $arProps;<br><br> CSaleBasket::Add($arFields);<br>}<br>?><br> * * * * //пример на проверку создания покупателя * * $userId=XXX;//id пользователя * //получаем FUSER_ID, если покупатель для данного пользователя существует * $FUSER_ID=CSaleUser::GetList(array('USER_ID' => $userId)); * //если покупателя нет - создаем его * if(!$FUSER_ID['ID']) * $FUSER_ID['ID']=CSaleUser::_Add(array("USER_ID" => $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; }
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; }
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; }
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; }
/** * 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; }
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; }
/** * <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; }