14if (!Loader::includeModule(
'sale'))
61 $adminSection = (defined(
'ADMIN_SECTION') &&
ADMIN_SECTION ===
true);
85 $arParams[
'SELECT_QUANTITY_TRACE'] = (isset(
$arParams[
'SELECT_QUANTITY_TRACE']) &&
$arParams[
'SELECT_QUANTITY_TRACE'] ==
'Y' ?
'Y' :
'N');
86 $arParams[
'SELECT_CHECK_MAX_QUANTITY'] = (isset(
$arParams[
'SELECT_CHECK_MAX_QUANTITY']) &&
$arParams[
'SELECT_CHECK_MAX_QUANTITY'] ==
'Y' ?
'Y' :
'N');
98 $productID = (int)
$arParams[
'PRODUCT_ID'];
104 $emptyResult =
array();
108 if (!$userGroups = static::getHitCache(self::CACHE_USER_GROUPS, $intUserID))
111 static::setHitCache(self::CACHE_USER_GROUPS, $intUserID, $userGroups);
114 if (empty($userGroups))
120 $userGroups =
array(2);
122 $userGroups =
$USER->GetUserGroupArray();
125 if (!$arProduct = static::getHitCache(self::CACHE_ITEM_WITH_RIGHTS, $productID))
127 $elementFilter =
array(
130 'ACTIVE_DATE' =>
'Y',
131 'CHECK_PERMISSIONS' =>
'Y',
132 'MIN_PERMISSION' =>
'R'
135 $elementFilter[
'PERMISSIONS_BY'] = $intUserID;
142 array(
'ID',
'IBLOCK_ID',
'NAME',
'DETAIL_PAGE_URL',
'XML_ID')
145 static::setHitCache(self::CACHE_ITEM_WITH_RIGHTS, $productID, $arProduct);
146 unset($dbIBlockElement, $elementFilter);
149 if(empty($arProduct) || !is_array($arProduct))
152 if (!isset(self::$catalogList[$arProduct[
'IBLOCK_ID']]))
155 'select' =>
array(
'IBLOCK_ID',
'SUBSCRIPTION',
'PRODUCT_IBLOCK_ID',
'CATALOG_XML_ID' =>
'IBLOCK.XML_ID'),
156 'filter' =>
array(
'=IBLOCK_ID' => $arProduct[
'IBLOCK_ID'])
159 if (empty(self::$catalogList[$arProduct[
'IBLOCK_ID']]) || !is_array(self::$catalogList[$arProduct[
'IBLOCK_ID']]))
161 if (self::$catalogList[$arProduct[
'IBLOCK_ID']][
'SUBSCRIPTION'] ==
'Y')
164 if (self::$catalogList[$arProduct[
'IBLOCK_ID']][
'PRODUCT_IBLOCK_ID'] > 0)
166 if (!static::checkParentActivity($arProduct[
'ID'], $arProduct[
'IBLOCK_ID']))
170 if (!$arCatalogProduct = static::getHitCache(self::CACHE_PRODUCT, $productID))
173 'QUANTITY',
'QUANTITY_TRACE',
'CAN_BUY_ZERO',
175 'WEIGHT',
'WIDTH',
'HEIGHT',
'LENGTH',
182 'filter' =>
array(
'=ID' => $productID)
184 if (!empty($arCatalogProduct))
186 $arCatalogProduct[
'ID'] = (int)$arCatalogProduct[
'ID'];
187 $arCatalogProduct[
'TYPE'] = (int)$arCatalogProduct[
'TYPE'];
188 $arCatalogProduct[
'QUANTITY'] = (float)$arCatalogProduct[
'QUANTITY'];
189 $arCatalogProduct[
'QUANTITY_RESERVED'] = (float)$arCatalogProduct[
'QUANTITY_RESERVED'];
190 Catalog\Product\SystemField::prepareRow($arCatalogProduct,
Catalog\
Product\SystemField::OPERATION_PROVIDER);
192 static::setHitCache(self::CACHE_PRODUCT, $productID, $arCatalogProduct);
195 if (empty($arCatalogProduct) || !is_array($arCatalogProduct))
217 "CATALOG_NO_QUANTITY_PRODUCT"
224 static::$errors =
array();
225 if (!static::checkProductSet($productID))
227 $APPLICATION->ThrowException(implode(
', ', static::$errors),
'NO_PRODUCT');
228 static::$errors =
array();
235 if (mb_strpos($arProduct[
"~XML_ID"],
'#') ===
false)
237 $parent = \CCatalogSku::GetProductInfo($arProduct[
'ID'], $arProduct[
'IBLOCK_ID']);
241 'select' => [
'ID',
'XML_ID'],
242 'filter' => [
'=ID' => $parent[
'ID']]
244 $parentData = $parentIterator->fetch();
245 if (!empty($parentData))
247 $arProduct[
'~XML_ID'] = $parentData[
'XML_ID'].
'#'.$arProduct[
'~XML_ID'];
249 unset($parentData, $parentIterator);
255 $dblQuantity = $arCatalogProduct[
'QUANTITY'];
258 $quantityLimitExceeded = ($quantityLimited && $dblQuantity < $quantity);
260 $arCatalogProduct[
'MEASURE'] = (int)$arCatalogProduct[
'MEASURE'];
261 $arCatalogProduct[
'MEASURE_NAME'] =
'';
262 $arCatalogProduct[
'MEASURE_CODE'] = 0;
263 if ($arCatalogProduct[
'MEASURE'] <= 0)
265 $arMeasure = CCatalogMeasure::getDefaultMeasure(
true,
true);
266 $arCatalogProduct[
'MEASURE_NAME'] = $arMeasure[
'~SYMBOL_RUS'];
267 $arCatalogProduct[
'MEASURE_CODE'] = $arMeasure[
'CODE'];
271 $rsMeasures = CCatalogMeasure::getList(
273 array(
'ID' => $arCatalogProduct[
'MEASURE']),
276 array(
'ID',
'SYMBOL_RUS',
'CODE')
278 if ($arMeasure = $rsMeasures->Fetch())
280 $arCatalogProduct[
'MEASURE_NAME'] = $arMeasure[
'SYMBOL_RUS'];
281 $arCatalogProduct[
'MEASURE_CODE'] = $arMeasure[
'CODE'];
286 "NAME" => $arProduct[
"~NAME"],
288 "DETAIL_PAGE_URL" => $arProduct[
'~DETAIL_PAGE_URL'],
289 "BARCODE_MULTI" => $arCatalogProduct[
"BARCODE_MULTI"],
290 "WEIGHT" => (
float)$arCatalogProduct[
'WEIGHT'],
291 "DIMENSIONS" => serialize(
array(
292 "WIDTH" => $arCatalogProduct[
"WIDTH"],
293 "HEIGHT" => $arCatalogProduct[
"HEIGHT"],
294 "LENGTH" => $arCatalogProduct[
"LENGTH"]
296 "VAT_INCLUDED" =>
"Y",
297 "MEASURE_ID" => $arCatalogProduct[
'MEASURE'],
298 "MEASURE_NAME" => $arCatalogProduct[
'MEASURE_NAME'],
299 "MEASURE_CODE" => $arCatalogProduct[
'MEASURE_CODE'],
300 "CATALOG_XML_ID" => self::$catalogList[$arProduct[
'IBLOCK_ID']][
'CATALOG_XML_ID'],
301 "PRODUCT_XML_ID" => $arProduct[
'~XML_ID']
303 switch ($arCatalogProduct[
'TYPE'])
315 foreach (
Catalog\
Product\SystemField::getProviderSelectFields() as $index => $value)
317 $field = is_string($index) ? $index : $value;
318 $arResult[$field] = $arCatalogProduct[$field];
321 if (
$arParams[
'SELECT_QUANTITY_TRACE'] ==
"Y")
322 $arResult[
"QUANTITY_TRACE"] = $arCatalogProduct[
"QUANTITY_TRACE"];
323 if (
$arParams[
'SELECT_CHECK_MAX_QUANTITY'] ==
'Y')
324 $arResult[
'CHECK_MAX_QUANTITY'] = ($quantityLimited ?
'Y' :
'N');
328 $arResult[
"QUANTITY"] = ($quantityLimitExceeded ? $dblQuantity : $quantity);
329 if ($quantityLimitExceeded)
333 "CATALOG_QUANTITY_NOT_ENOGH",
335 "#NAME#" => $arProduct[
"NAME"],
336 "#CATALOG_QUANTITY#" => $dblQuantity,
337 "#QUANTITY#" => $quantity,
338 '#MEASURE_NAME#' => $arCatalogProduct[
'MEASURE_NAME']
341 "CATALOG_QUANTITY_NOT_ENOGH"
350 if (
$arParams[
"AVAILABLE_QUANTITY"] ==
"Y")
351 $arResult[
"AVAILABLE_QUANTITY"] = ($quantityLimitExceeded ? $dblQuantity : $quantity);
355 $productHash =
array(
357 'PRODUCT_ID' => $productID,
361 $arCoupons =
array();
372 if (!empty($arCoupons))
373 $arCoupons = array_keys($arCoupons);
387 'USE_DISCOUNTS' =>
$arParams[
'CHECK_DISCOUNT'] ==
'Y',
388 'RESULT_WITH_VAT' =>
true,
398 ($adminSection ? $strSiteID :
false),
406 $quantity = $nearestQuantity;
413 ($adminSection ? $strSiteID :
false),
434 $arDiscountList =
array();
435 if (empty($arPrice[
'DISCOUNT_LIST']) && !empty($arPrice[
'DISCOUNT']) && is_array($arPrice[
'DISCOUNT']))
436 $arPrice[
'DISCOUNT_LIST'] =
array($arPrice[
'DISCOUNT']);
437 if (!empty($arPrice[
'DISCOUNT_LIST']))
439 $appliedCoupons =
array();
440 foreach ($arPrice[
'DISCOUNT_LIST'] as &$arOneDiscount)
444 if (!empty($arOneDiscount[
'COUPON']))
445 $appliedCoupons[] = $arOneDiscount[
'COUPON'];
447 unset($arOneDiscount);
448 if (!empty($appliedCoupons))
450 unset($resultApply, $appliedCoupons);
453 if (empty($arPrice[
'PRICE'][
'CATALOG_GROUP_NAME']))
455 if (!empty($arPrice[
'PRICE'][
'CATALOG_GROUP_ID']))
458 if ($priceName !=
'')
459 $arPrice[
'PRICE'][
'CATALOG_GROUP_NAME'] = $priceName;
464 $arResult[
'PRODUCT_PRICE_ID'] = $arPrice[
'RESULT_PRICE'][
'ID'];
465 $arResult[
'NOTES'] = $arPrice[
'PRICE'][
'CATALOG_GROUP_NAME'];
466 $arResult[
'VAT_RATE'] = $arPrice[
'RESULT_PRICE'][
'VAT_RATE'];
467 $arResult[
'VAT_INCLUDED'] = $arPrice[
'RESULT_PRICE'][
'VAT_INCLUDED'];
473 if (empty($arPrice[
'RESULT_PRICE']) || !is_array($arPrice[
'RESULT_PRICE']))
476 $arResult[
'PRICE_TYPE_ID'] = $arPrice[
'RESULT_PRICE'][
'PRICE_TYPE_ID'];
477 $arResult[
'BASE_PRICE'] = $arPrice[
'RESULT_PRICE'][
'BASE_PRICE'];
478 $arResult[
'PRICE'] = $arPrice[
'RESULT_PRICE'][
'DISCOUNT_PRICE'];
479 $arResult[
'CURRENCY'] = $arPrice[
'RESULT_PRICE'][
'CURRENCY'];
480 $arResult[
'DISCOUNT_PRICE'] = $arPrice[
'RESULT_PRICE'][
'DISCOUNT'];
483 if (isset($arPrice[
'RESULT_PRICE'][
'PERCENT']))
484 $arResult[
'DISCOUNT_VALUE'] = ($arPrice[
'RESULT_PRICE'][
'PERCENT'] > 0 ? $arPrice[
'RESULT_PRICE'][
'PERCENT'] .
'%' :
null);
487 if (!empty($arDiscountList))
488 $arResult[
'DISCOUNT_LIST'] = $arDiscountList;
489 if (!empty($arPrice[
'DISCOUNT']))
491 $arResult[
'DISCOUNT_NAME'] =
'['.$arPrice[
'DISCOUNT'][
'ID'].
'] '.$arPrice[
'DISCOUNT'][
'NAME'];
492 if (!empty($arPrice[
'DISCOUNT'][
'COUPON']))
493 $arResult[
'DISCOUNT_COUPON'] = $arPrice[
'DISCOUNT'][
'COUPON'];
503 if (!$arVAT = static::getHitCache(self::CACHE_VAT, $productID))
508 static::setHitCache(self::CACHE_VAT, $productID, $arVAT);
512 if (isset($arVAT) && is_array($arVAT))
514 if ($arVat[
'EXCLUDE_VAT'] ===
'N')
516 $vatRate = $arVAT[
'RATE'] * 0.01;
532 $adminSection = (defined(
'ADMIN_SECTION') &&
ADMIN_SECTION ===
true);
555 $productID = (int)
$arParams[
'PRODUCT_ID'];
556 $quantity = (float)
$arParams[
'QUANTITY'];
566 if (!$userGroups = static::getHitCache(self::CACHE_USER_GROUPS, $intUserID))
569 static::setHitCache(self::CACHE_USER_GROUPS, $intUserID, $userGroups);
572 if (empty($userGroups))
577 $userGroups =
array(2);
579 $userGroups =
$USER->GetUserGroupArray();
582 if (!$arProduct = static::getHitCache(self::CACHE_ITEM_WITH_RIGHTS, $productID))
584 $elementFilter =
array(
587 'ACTIVE_DATE' =>
'Y',
588 'CHECK_PERMISSIONS' =>
'Y',
589 'MIN_PERMISSION' =>
'R'
592 $elementFilter[
'PERMISSIONS_BY'] = $intUserID;
599 array(
'ID',
'IBLOCK_ID',
'NAME',
'DETAIL_PAGE_URL')
602 static::setHitCache(self::CACHE_ITEM_WITH_RIGHTS, $productID, $arProduct);
603 unset($dbIBlockElement, $elementFilter);
606 if (empty($arProduct) || !is_array($arProduct))
609 if (!static::checkParentActivity($arProduct[
'ID'], $arProduct[
'IBLOCK_ID']))
612 if (!$arCatalogProduct = static::getHitCache(self::CACHE_PRODUCT, $productID))
615 'QUANTITY',
'QUANTITY_TRACE',
'CAN_BUY_ZERO',
616 'WEIGHT',
'WIDTH',
'HEIGHT',
'LENGTH',
623 'filter' =>
array(
'=ID' => $productID)
625 if (!empty($arCatalogProduct))
627 Catalog\Product\SystemField::prepareRow($arCatalogProduct,
Catalog\
Product\SystemField::OPERATION_PROVIDER);
628 $arCatalogProduct[
'QUANTITY'] = (float)$arCatalogProduct[
'QUANTITY'];
629 static::setHitCache(self::CACHE_PRODUCT, $productID, $arCatalogProduct);
633 if (empty($arCatalogProduct) || !is_array($arCatalogProduct))
650 static::$errors =
array();
651 if (!static::checkProductSet($productID))
653 static::$errors =
array();
661 $productHash =
array(
663 'PRODUCT_ID' => $productID,
668 if (!empty($arCoupons))
669 $arCoupons = array_keys($arCoupons);
675 'USE_DISCOUNTS' =>
$arParams[
'CHECK_DISCOUNT'] ==
'Y',
676 'RESULT_WITH_VAT' =>
true,
686 ($adminSection ? $strSiteID :
false),
694 $quantity = $nearestQuantity;
701 ($adminSection ? $strSiteID :
false),
716 $arDiscountList =
array();
717 if (empty($arPrice[
'DISCOUNT_LIST']) && !empty($arPrice[
'DISCOUNT']) && is_array($arPrice[
'DISCOUNT']))
718 $arPrice[
'DISCOUNT_LIST'] =
array($arPrice[
'DISCOUNT']);
719 if (!empty($arPrice[
'DISCOUNT_LIST']))
721 $appliedCoupons =
array();
722 foreach ($arPrice[
'DISCOUNT_LIST'] as &$arOneDiscount)
726 if (!empty($arOneDiscount[
'COUPON']))
727 $appliedCoupons[] = $arOneDiscount[
'COUPON'];
729 unset($arOneDiscount);
730 if (!empty($appliedCoupons))
732 unset($resultApply, $appliedCoupons);
735 if (empty($arPrice[
'PRICE'][
'CATALOG_GROUP_NAME']))
737 if (!empty($arPrice[
'PRICE'][
'CATALOG_GROUP_ID']))
740 if ($priceName !=
'')
741 $arPrice[
'PRICE'][
'CATALOG_GROUP_NAME'] = $priceName;
746 if (empty($arPrice[
'RESULT_PRICE']) || !is_array($arPrice[
'RESULT_PRICE']))
750 'PRODUCT_PRICE_ID' => $arPrice[
'RESULT_PRICE'][
'ID'],
752 'PRICE_TYPE_ID' => $arPrice[
'RESULT_PRICE'][
'PRICE_TYPE_ID'],
753 'BASE_PRICE' => $arPrice[
'RESULT_PRICE'][
'BASE_PRICE'],
754 'PRICE' => $arPrice[
'RESULT_PRICE'][
'DISCOUNT_PRICE'],
755 'VAT_RATE' => $arPrice[
'RESULT_PRICE'][
'VAT_RATE'],
756 'VAT_INCLUDED' => $arPrice[
'RESULT_PRICE'][
'VAT_INCLUDED'],
757 "CURRENCY" => $arPrice[
'RESULT_PRICE'][
'CURRENCY'],
758 "WEIGHT" => (
float)$arCatalogProduct[
"WEIGHT"],
759 "DIMENSIONS" => serialize(
array(
760 "WIDTH" => $arCatalogProduct[
"WIDTH"],
761 "HEIGHT" => $arCatalogProduct[
"HEIGHT"],
762 "LENGTH" => $arCatalogProduct[
"LENGTH"]
764 "NAME" => $arProduct[
"~NAME"],
766 "DETAIL_PAGE_URL" => $arProduct[
'~DETAIL_PAGE_URL'],
767 "NOTES" => $arPrice[
"PRICE"][
"CATALOG_GROUP_NAME"],
768 "DISCOUNT_PRICE" => $arPrice[
'RESULT_PRICE'][
'DISCOUNT'],
769 "DISCOUNT_VALUE" => ($arPrice[
'RESULT_PRICE'][
'PERCENT'] > 0 ? $arPrice[
'RESULT_PRICE'][
'PERCENT'].
'%' :
null),
770 "DISCOUNT_NAME" =>
null,
771 "DISCOUNT_COUPON" =>
null,
772 "DISCOUNT_LIST" =>
array()
774 switch ($arCatalogProduct[
'TYPE'])
786 foreach (
Catalog\
Product\SystemField::getProviderSelectFields() as $index => $value)
788 $field = is_string($index) ? $index : $value;
789 $arResult[$field] = $arCatalogProduct[$field];
797 if (!empty($arDiscountList))
798 $arResult[
'DISCOUNT_LIST'] = $arDiscountList;
799 if (!empty($arPrice[
'DISCOUNT']))
801 $arResult[
'DISCOUNT_NAME'] =
'['.$arPrice[
'DISCOUNT'][
'ID'].
'] '.$arPrice[
'DISCOUNT'][
'NAME'];
802 if (!empty($arPrice[
'DISCOUNT'][
'COUPON']))
803 $arResult[
'DISCOUNT_COUPON'] = $arPrice[
'DISCOUNT'][
'COUPON'];
870 $disableReservation = !static::isReservationEnabled();
872 if ((
string)
$arParams[
"UNDO_RESERVATION"] !=
"Y")
891 'filter' => [
'=ID' =>
$arParams[
"PRODUCT_ID"]],
895 if (empty($arProduct))
911 $arProduct[
"QUANTITY"] = (float)$arProduct[
"QUANTITY"];
912 $arProduct[
"QUANTITY_RESERVED"] = (float)$arProduct[
"QUANTITY_RESERVED"];
914 if ($disableReservation)
916 $startReservedQuantity = 0;
918 if (
$arParams[
"UNDO_RESERVATION"] !=
"Y")
927 $arRes[
"RESULT"] = $internalResult->isSuccess();
928 unset($internalResult);
932 if ($arProduct[
"QUANTITY_TRACE"] ==
"N" || (isset(
$arParams[
"ORDER_DEDUCTED"]) &&
$arParams[
"ORDER_DEDUCTED"] ==
"Y"))
936 $startReservedQuantity = 0;
940 $startReservedQuantity = $arProduct[
"QUANTITY_RESERVED"];
942 if (
$arParams[
"UNDO_RESERVATION"] ==
"N")
944 if ($arProduct[
"CAN_BUY_ZERO"] ==
"Y")
946 $arFields[
"QUANTITY_RESERVED"] = $arProduct[
"QUANTITY_RESERVED"] +
$arParams[
"QUANTITY_ADD"];
948 if ($arProduct[
"QUANTITY"] >=
$arParams[
"QUANTITY_ADD"])
962 $arRes[
"RESULT"] = $internalResult->isSuccess();
963 unset($internalResult);
967 if ($arProduct[
"QUANTITY"] >=
$arParams[
"QUANTITY_ADD"])
970 $arFields[
"QUANTITY_RESERVED"] = $arProduct[
"QUANTITY_RESERVED"] +
$arParams[
"QUANTITY_ADD"];
976 $arRes[
"QUANTITY_NOT_RESERVED"] =
$arParams[
"QUANTITY_ADD"] - $arProduct[
"QUANTITY"];
979 $arFields[
"QUANTITY_RESERVED"] = $arProduct[
"QUANTITY_RESERVED"] + $arProduct[
"QUANTITY"];
987 $arRes[
"RESULT"] = $internalResult->isSuccess();
988 unset($internalResult);
993 if (
$arParams[
"QUANTITY_ADD"] > $arProduct[
"QUANTITY_RESERVED"])
997 "DDCT_DEDUCTION_UNDO_ERROR_RESERVE_QUANTITY",
998 self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"])
1002 $arRes[
"RESULT"] =
false;
1004 static::clearHitCache(self::CACHE_PRODUCT);
1006 $arRes[
'CAN_RESERVE'] =
"Y";
1012 $needReserved = $arProduct[
"QUANTITY_RESERVED"] -
$arParams[
"QUANTITY_ADD"];
1014 $arFields[
"QUANTITY_RESERVED"] = $needReserved;
1020 $arRes[
"RESULT"] = $internalResult->isSuccess();
1021 unset($internalResult);
1028 $needReserved =
$arFields[
"QUANTITY_RESERVED"] - $startReservedQuantity;
1029 if ($startReservedQuantity >
$arFields[
"QUANTITY_RESERVED"])
1031 $needReserved =
$arFields[
"QUANTITY_RESERVED"];
1034 $arRes[
"QUANTITY_RESERVED"] = $needReserved;
1041 static::clearHitCache(self::CACHE_PRODUCT);
1043 $arRes[
'CAN_RESERVE'] = ($disableReservation ?
"N" :
"Y");
1059 $disableReservation = !static::isReservationEnabled();
1062 if ((
string)
$arParams[
"UNDO_DEDUCTION"] !=
"Y")
1068 $APPLICATION->ThrowException(Loc::getMessage(
"RSRV_INCORRECT_ID"),
"NO_ORDER_ID");
1069 $arRes[
"RESULT"] =
false;
1073 $isOrderConverted = \Bitrix\Main\Config\Option::get(
"main",
"~sale_converted_15",
'Y');
1079 if ((
string)
$arParams[
"EMULATE"] !=
"Y")
1082 if ((
string)
$arParams[
"PRODUCT_RESERVED"] !=
"Y")
1092 if (isset(
$arParams[
"BASKET_ITEM"]) && $isOrderConverted !=
'N')
1094 if (
$arParams[
"BASKET_ITEM"] instanceof \Bitrix\Sale\BasketItem)
1106 array(
'ID',
'QUANTITY',
'QUANTITY_RESERVED',
'QUANTITY_TRACE',
'CAN_BUY_ZERO',
'TYPE')
1109 if ($arProduct = $rsProducts->Fetch())
1112 ($arProduct[
'TYPE'] == Catalog\ProductTable::TYPE_SKU || $arProduct[
'TYPE'] == Catalog\ProductTable::TYPE_EMPTY_SKU)
1113 && (
string)Main\Config\Option::get(
'catalog',
'show_catalog_tab_with_offers') !=
'Y'
1116 $arRes[
"RESULT"] =
false;
1120 if (
$arParams[
"EMULATE"] ==
"Y" || $arProduct[
"QUANTITY_TRACE"] ==
"N")
1129 if ($isOrderConverted !=
'N' && empty(
$arParams[
"STORE_DATA"]) && $basketItem)
1131 if (static::canProductAutoShip($basketItem))
1133 $arParams[
"STORE_DATA"] = static::getProductStoreData($basketItem,
$arParams[
"QUANTITY"]);
1138 $barcodeMulti =
false;
1139 if ($isOrderConverted !=
'N')
1141 $barcodeMulti = $basketItem->isBarcodeMulti();
1149 foreach (
$arParams[
"STORE_DATA"] as $id => $arRecord)
1151 if (!empty($arRecord[
"BARCODE"]) && is_array($arRecord[
"BARCODE"]))
1153 foreach ($arRecord[
"BARCODE"] as $barcodeId => $barcodeValue)
1155 if (strval(trim($barcodeValue)) ==
"")
1157 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_DEDUCTION_MULTI_BARCODE_EMPTY", array_merge(self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"]),
array(
"#STORE_ID#" => $arRecord[
'STORE_ID']))),
"DDCT_DEDUCTION_MULTI_BARCODE_EMPTY");
1158 $arRes[
"RESULT"] =
false;
1166 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_DEDUCTION_MULTI_BARCODE_EMPTY", array_merge(self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"]),
array(
"#STORE_ID#" => $arRecord[
'STORE_ID']))),
"DDCT_DEDUCTION_MULTI_BARCODE_EMPTY");
1167 $arRes[
"RESULT"] =
false;
1177 foreach (
$arParams[
"STORE_DATA"] as $id => $arRecord)
1179 if (!empty($arRecord[
"BARCODE"]) && is_array($arRecord[
"BARCODE"]))
1181 foreach($arRecord[
"BARCODE"] as $barcodeValue)
1183 $arRes[
'BARCODE'][$barcodeValue] =
false;
1189 foreach (
$arParams[
"STORE_DATA"] as $id => $arRecord)
1191 if (!isset($arRecord[
"STORE_ID"]) || intval($arRecord[
"STORE_ID"]) < 0 || !isset($arRecord[
"QUANTITY"]) || intval($arRecord[
"QUANTITY"]) < 0)
1193 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_DEDUCTION_STORE_ERROR", self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"])),
"DDCT_DEDUCTION_STORE_ERROR");
1194 $arRes[
"RESULT"] =
false;
1201 "PRODUCT_ID" =>
$arParams[
"PRODUCT_ID"],
1202 "STORE_ID" => $arRecord[
"STORE_ID"]
1206 array(
'ID',
'AMOUNT')
1210 if ($arProp[
"AMOUNT"] < $arRecord[
"QUANTITY"])
1214 'DDCT_DEDUCTION_QUANTITY_STORE_ERROR_2',
1216 self::GetProductCatalogInfo(
$arParams[
'PRODUCT_ID']),
1219 '#STORE_ID#' => $arRecord[
'STORE_ID'],
1223 'DDCT_DEDUCTION_QUANTITY_STORE_ERROR'
1225 $arRes[
"RESULT"] =
false;
1234 $arRes[
"STORES"][$arRecord[
"STORE_ID"]] = $arRecord[
"QUANTITY"];
1235 $totalAmount += $arRecord[
"QUANTITY"];
1240 if (isset($arRecord[
"BARCODE"]) && is_array($arRecord[
"BARCODE"]) &&
count($arRecord[
"BARCODE"]) > 0)
1243 foreach ($arRecord[
"BARCODE"] as $barcodeId => $barcodeValue)
1245 if (strval(trim($barcodeValue)) ==
"" || !$barcodeMulti)
1251 "STORE_ID" => $arRecord[
"STORE_ID"],
1252 "BARCODE" => $barcodeValue,
1256 $dbres = CCatalogStoreBarcode::GetList(
1261 array(
"ID",
"STORE_ID",
"BARCODE",
"PRODUCT_ID")
1264 if ($catalogStoreBarcodeRes = $dbres->Fetch())
1266 CCatalogStoreBarcode::Delete($catalogStoreBarcodeRes[
"ID"]);
1267 $arRes[
'BARCODE'][$barcodeValue] =
true;
1273 "DDCT_DEDUCTION_BARCODE_ERROR",
1274 array_merge(self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"]),
array(
"#BARCODE#" => $barcodeValue))
1276 "DDCT_DEDUCTION_BARCODE_ERROR"
1278 $arRes[
'BARCODE'][$barcodeValue] =
false;
1279 $arRes[
"RESULT"] =
false;
1287 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_DEDUCTION_SAVE_ERROR", self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"])),
"DDCT_DEDUCTION_SAVE_ERROR");
1288 $arRes[
"RESULT"] =
false;
1297 if (
$arParams[
"PRODUCT_RESERVED"] ==
"Y")
1299 if ($totalAmount <= $arProduct[
"QUANTITY_RESERVED"])
1301 $needReserved = $arProduct[
"QUANTITY_RESERVED"] - $totalAmount;
1302 if ($totalAmount > $arProduct[
"QUANTITY_RESERVED"])
1304 $needReserved = $arProduct[
"QUANTITY_RESERVED"];
1307 $arFields[
"QUANTITY_RESERVED"] = $needReserved;
1309 else if ($totalAmount <= $arProduct[
"QUANTITY_RESERVED"] + $arProduct[
"QUANTITY"])
1312 $arFields[
"QUANTITY"] = $arProduct[
"QUANTITY"] - ($totalAmount - $arProduct[
"QUANTITY_RESERVED"]);
1316 $arRes[
"RESULT"] =
false;
1322 if ($totalAmount <= $arProduct[
"QUANTITY"])
1324 $arFields[
"QUANTITY"] = $arProduct[
"QUANTITY"] - $totalAmount;
1326 else if ($totalAmount <= $arProduct[
"QUANTITY_RESERVED"] + $arProduct[
"QUANTITY"])
1330 $minusQuantity = ($totalAmount - $arProduct[
"QUANTITY"]);
1332 $needReserved = $arProduct[
"QUANTITY_RESERVED"] - $minusQuantity;
1333 if ($minusQuantity > $arProduct[
"QUANTITY_RESERVED"])
1335 $needReserved = $arProduct[
"QUANTITY_RESERVED"];
1338 $arFields[
"QUANTITY_RESERVED"] = $needReserved;
1343 $arRes[
"RESULT"] =
false;
1354 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_DEDUCTION_STORE_ERROR", self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"])),
"DEDUCTION_STORE_ERROR1");
1355 $arRes[
"RESULT"] =
false;
1361 if (($disableReservation && (
$arParams[
'UNDO_DEDUCTION'] ==
"Y" ||
$arParams[
"PRODUCT_RESERVED"] ==
"N")) || !$disableReservation)
1363 if (
$arParams[
"QUANTITY"] <= $arProduct[
"QUANTITY_RESERVED"] + $arProduct[
"QUANTITY"])
1365 if (
$arParams[
"PRODUCT_RESERVED"] ==
"Y")
1367 if (
$arParams[
"QUANTITY"] <= $arProduct[
"QUANTITY_RESERVED"])
1370 $needReserved = $arProduct[
"QUANTITY_RESERVED"] -
$arParams[
"QUANTITY"];
1371 if (
$arParams[
"QUANTITY"] > $arProduct[
"QUANTITY_RESERVED"])
1373 $needReserved = $arProduct[
"QUANTITY_RESERVED"];
1376 $arFields[
"QUANTITY_RESERVED"] = $needReserved;
1381 $arFields[
"QUANTITY"] = $arProduct[
"QUANTITY"] - (
$arParams[
"QUANTITY"] - $arProduct[
"QUANTITY_RESERVED"]);
1386 if (
$arParams[
"QUANTITY"] <= $arProduct[
"QUANTITY"])
1394 $minusQuantity = (
$arParams[
"QUANTITY"] - $arProduct[
"QUANTITY"]);
1396 $needReserved = $arProduct[
"QUANTITY_RESERVED"] - $minusQuantity;
1397 if ($minusQuantity > $arProduct[
"QUANTITY_RESERVED"])
1399 $needReserved = $arProduct[
"QUANTITY_RESERVED"];
1402 $arFields[
"QUANTITY_RESERVED"] = $needReserved;
1410 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_DEDUCTION_QUANTITY_ERROR", self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"])),
"DDCT_DEDUCTION_QUANTITY_ERROR");
1411 $arRes[
"RESULT"] =
false;
1425 if (
$arParams[
"EMULATE"] ==
"Y" || $arProduct[
"QUANTITY_TRACE"] ==
"N")
1433 if ($isOrderConverted !=
'N' && empty(
$arParams[
"STORE_DATA"]) && $basketItem)
1435 if (static::canProductAutoShip($basketItem))
1437 $arParams[
"STORE_DATA"] = static::getProductStoreData($basketItem,
$arParams[
"QUANTITY"]);
1442 $arParams[
"STORE_DATA"] = static::getProductOneStoreData($basketItem,
$arParams[
"QUANTITY"]);
1448 $totalAddedAmount = 0;
1449 foreach (
$arParams[
"STORE_DATA"] as $id => $arRecord)
1454 "PRODUCT_ID" =>
$arParams[
"PRODUCT_ID"],
1455 "STORE_ID" => $arRecord[
"STORE_ID"]
1459 array(
'ID',
'AMOUNT')
1466 array(
"AMOUNT" => $arProp[
"AMOUNT"] + $arRecord[
"QUANTITY"])
1471 $arRes[
"STORES"][$arRecord[
"STORE_ID"]] = $arRecord[
"QUANTITY"];
1472 $totalAddedAmount += $arRecord[
"QUANTITY"];
1474 $barcodeMulti =
false;
1475 if ($isOrderConverted !=
'N')
1477 $barcodeMulti = $basketItem->isBarcodeMulti();
1481 if (isset($arRecord[
"BARCODE"]))
1483 if (!empty($arRecord[
"BARCODE"]) && is_array($arRecord[
"BARCODE"]))
1486 foreach ($arRecord[
"BARCODE"] as $barcodeValue)
1488 if (strval(trim($barcodeValue)) ==
'' || (strval(trim($barcodeValue)) !=
'' && !$barcodeMulti))
1492 "STORE_ID" => $arRecord[
"STORE_ID"],
1493 "BARCODE" => $barcodeValue,
1500 elseif (!is_array($arRecord[
"BARCODE"]))
1503 "STORE_ID" => $arRecord[
"STORE_ID"],
1504 "BARCODE" => $arRecord[
"BARCODE"],
1514 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_DEDUCTION_SAVE_ERROR", self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"])),
"DDCT_DEDUCTION_SAVE_ERROR");
1515 $arRes[
"RESULT"] =
false;
1525 if (
$arParams[
"PRODUCT_RESERVED"] ==
"Y")
1527 $arUpdateFields[
"QUANTITY_RESERVED"] = $arProduct[
"QUANTITY_RESERVED"] + $totalAddedAmount;
1531 $arUpdateFields[
"QUANTITY"] = $arProduct[
"QUANTITY"] + $totalAddedAmount;
1540 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_DEDUCTION_STORE_ERROR", self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"])),
"DEDUCTION_STORE_ERROR2");
1541 $arRes[
"RESULT"] =
false;
1547 if (
$arParams[
"PRODUCT_RESERVED"] ==
"Y" && !$disableReservation)
1549 $arFields[
"QUANTITY_RESERVED"] = $arProduct[
"QUANTITY_RESERVED"] +
$arParams[
"QUANTITY"];
1565 $arRes[
"RESULT"] =
false;
1570 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_UNKNOWN_ERROR", self::GetProductCatalogInfo(
$arParams[
"PRODUCT_ID"])),
"UNKNOWN_DEDUCTION_ERROR");
1573 if (
$arRes[
'RESULT'] ===
true)
1575 static::clearHitCache(self::CACHE_PRODUCT);
1590 $result = new \Bitrix\Sale\Result();
1592 $storesList =
array();
1596 $productId = $basketItem->getProductId();
1599 'select' =>
array(
'ID',
'TYPE',
'QUANTITY',
'QUANTITY_RESERVED',
'QUANTITY_TRACE',
'CAN_BUY_ZERO'),
1600 'filter' =>
array(
'=ID' => $productId)
1602 if (empty($arProduct))
1616 if (empty($basketStoreData))
1618 if (static::canProductAutoShip($basketItem))
1620 $basketStoreData = static::getProductStoreData($basketItem, $quantity);
1624 if (!empty($basketStoreData))
1627 foreach ($basketStoreData as $storeId => $basketStore)
1630 if (intval($storeId) < -1 || intval($storeId) == 0
1631 || !isset($basketStore[
"QUANTITY"]) || intval($basketStore[
"QUANTITY"]) < 0)
1638 if (intval($storeId) == -1)
1640 $totalAmount = intval($basketStore[
"QUANTITY"]);
1645 $rsProps = CCatalogStoreProduct::GetList(
1648 "PRODUCT_ID" => $productId,
1649 "STORE_ID" => $storeId
1653 array(
'ID',
'AMOUNT')
1657 if ($arProp[
"AMOUNT"] < $basketStore[
"QUANTITY"])
1661 'DDCT_DEDUCTION_QUANTITY_STORE_ERROR_2',
1663 self::GetProductCatalogInfo($productId),
1666 '#STORE_ID#' => $storeId,
1670 'DDCT_DEDUCTION_QUANTITY_STORE_ERROR'
1677 $storesList[$storeId] = $basketStore[
"QUANTITY"];
1678 $totalAmount += $basketStore[
"QUANTITY"];
1681 if (isset($basketStore[
"BARCODE"]) && is_array($basketStore[
"BARCODE"]) &&
count($basketStore[
"BARCODE"]) > 0)
1683 foreach ($basketStore[
"BARCODE"] as $barcodeId => $barcodeValue)
1685 if (strval(trim($barcodeValue)) ==
"")
1687 if ($basketItem->isBarcodeMulti())
1691 "DDCT_DEDUCTION_MULTI_BARCODE_EMPTY",
1692 array_merge(self::GetProductCatalogInfo($productId),
array(
"#STORE_ID#" => $basketStore[
'STORE_ID']))
1694 "DDCT_DEDUCTION_MULTI_BARCODE_EMPTY"
1701 "STORE_ID" => static::CATALOG_PROVIDER_EMPTY_STORE_ID,
1702 "BARCODE" => $barcodeValue,
1703 "PRODUCT_ID" => $productId
1706 if ($basketItem->isBarcodeMulti())
1711 $dbres = CCatalogStoreBarcode::GetList(
1716 array(
"ID",
"STORE_ID",
"BARCODE",
"PRODUCT_ID")
1719 if (!
$arRes = $dbres->Fetch())
1723 "DDCT_DEDUCTION_BARCODE_ERROR",
1724 array_merge(self::GetProductCatalogInfo($productId),
array(
"#BARCODE#" => $barcodeValue))
1726 "DDCT_DEDUCTION_BARCODE_ERROR"
1731 elseif($basketItem->isBarcodeMulti())
1735 "DDCT_DEDUCTION_MULTI_BARCODE_EMPTY",
1736 array_merge(self::GetProductCatalogInfo($productId),
array(
"#STORE_ID#" => $basketStore[
'STORE_ID']))
1738 "DDCT_DEDUCTION_MULTI_BARCODE_EMPTY"
1745 if (!
$result->isSuccess(
true))
1750 if ($reserved ==
'Y')
1752 $reservedPoolQuantity = static::getProductPoolQuantityByBasketItem($basketItem);
1753 $reservedQuantity = $arProduct[
"QUANTITY_RESERVED"] + floatval($reservedPoolQuantity);
1757 $productQuantity = ($reserved ==
'Y' ? $reservedQuantity : $arProduct[
"QUANTITY"]);
1761 if ($totalAmount > $arProduct[
"QUANTITY_RESERVED"] + $arProduct[
"QUANTITY"])
1764 Loc::getMessage(
"DDCT_DEDUCTION_SHIPMENT_QUANTITY_NOT_ENOUGH", self::GetProductCatalogInfo($productId)),
1765 "SALE_PROVIDER_SHIPMENT_QUANTITY_NOT_ENOUGH"
1775 Loc::getMessage(
"DDCT_DEDUCTION_STORE_ERROR", self::GetProductCatalogInfo($productId)),
1776 "DEDUCTION_STORE_ERROR1"
1784 $reservedPoolQuantity = static::getProductPoolQuantityByBasketItem($basketItem);
1785 $reservedQuantity = $arProduct[
"QUANTITY_RESERVED"] + floatval($reservedPoolQuantity);
1787 if ($arProduct[
"CAN_BUY_ZERO"] !=
"Y" && $arProduct[
"QUANTITY_TRACE"] ==
"Y")
1789 if ($quantity > $reservedQuantity + $arProduct[
"QUANTITY"])
1792 Loc::getMessage(
"DDCT_DEDUCTION_QUANTITY_ERROR", self::GetProductCatalogInfo($productId)),
1793 "DDCT_DEDUCTION_QUANTITY_ERROR"
1808 $result = new \Bitrix\Sale\Result();
1813 array(
'ID' => $productId),
1816 array(
'ID',
'QUANTITY',
'QUANTITY_RESERVED',
'QUANTITY_TRACE',
'CAN_BUY_ZERO',
'TYPE')
1819 if ($arProduct = $rsProducts->Fetch())
1826 $fields[
"QUANTITY_TRACE"] = ($arProduct[
"QUANTITY_TRACE"] ==
"Y");
1860 $storeIds = static::getStoreIds(
$arParams);
1861 if (empty($storeIds))
1865 if (!(
$result = static::getHitCache(self::CACHE_STORE_PRODUCT, $cacheId)))
1869 'select' =>
array(
'PRODUCT_ID',
'AMOUNT',
'STORE_ID',
'STORE_NAME' =>
'STORE.TITLE'),
1870 'filter' =>
array(
'=PRODUCT_ID' =>
$arParams[
'PRODUCT_ID'],
'@STORE_ID' => $storeIds),
1871 'order' =>
array(
'STORE_ID' =>
'ASC')
1874 $result[$row[
'STORE_ID']] = $row;
1880 static::setHitCache(self::CACHE_STORE_PRODUCT, $cacheId,
$result);
1892 "PRODUCT_ID" =>
$arParams[
"PRODUCT_ID"],
1899 $dbres = CCatalogStoreBarcode::GetList(
1903 if (
$res = $dbres->GetNext())
1909 private static function GetProductCatalogInfo($productID)
1911 $productID = (int)$productID;
1912 if ($productID <= 0)
1916 if (!$arProduct = static::getHitCache(
'IBLOCK_ELEMENT', $productID))
1918 $dbProduct = CIBlockElement::GetList(
array(),
array(
"ID" => $productID),
false,
false,
array(
'ID',
'IBLOCK_ID',
'NAME',
'IBLOCK_SECTION_ID'));
1919 if ($arProduct = $dbProduct->Fetch())
1921 static::setHitCache(
'IBLOCK_ELEMENT', $productID, $arProduct);
1926 "#PRODUCT_ID#" => $arProduct[
"ID"],
1927 "#PRODUCT_NAME#" => $arProduct[
"NAME"],
1933 static $proxyCatalogProductSet =
array();
1934 static $proxyCatalogSkuData =
array();
1936 $arProductId =
array();
1937 $proxyCatalogProductSetKey = $productID.
"|".$intType;
1939 if (!isset($proxyCatalogProductSet[$proxyCatalogProductSetKey]))
1941 $arSets = $proxyCatalogProductSet[$proxyCatalogProductSetKey];
1943 if (is_array($arSets))
1945 foreach ($arSets as
$k => $arSet)
1947 foreach ($arSet[
"ITEMS"] as $k1 => $item)
1949 $arItem =
self::GetProductData(
array(
"PRODUCT_ID" => $item[
"ITEM_ID"],
"QUANTITY" => $item[
"QUANTITY"],
"CHECK_QUANTITY" =>
"N",
"CHECK_PRICE" =>
"N"));
1950 if (array_key_exists(
'QUANTITY_TRACE', $arItem))
1951 unset($arItem[
'QUANTITY_TRACE']);
1953 $arItem[
"PRODUCT_ID"] = $item[
"ITEM_ID"];
1954 $arItem[
"MODULE"] =
"catalog";
1955 $arItem[
"PRODUCT_PROVIDER_CLASS"] =
"CCatalogProductProvider";
1958 $arItem[
'SET_DISCOUNT_PERCENT'] = ($item[
'DISCOUNT_PERCENT'] ==
'' ?
false : (float)$item[
'DISCOUNT_PERCENT']);
1961 $arProductId[] = $item[
"ITEM_ID"];
1963 $arItem[
"PROPS"] =
array();
1965 if (!empty($proxyCatalogSkuData[$item[
"ITEM_ID"]]) && is_array($proxyCatalogSkuData[$item[
"ITEM_ID"]]))
1967 $arParentSku = $proxyCatalogSkuData[$item[
"ITEM_ID"]];
1971 if ($arParentSku = CCatalogSku::GetProductInfo($item[
"ITEM_ID"]))
1973 $proxyCatalogSkuData[$item[
"ITEM_ID"]] = $arParentSku;
1978 if (!empty($arParentSku))
1980 $arPropsSku =
array();
1982 if (!$arProduct = static::getHitCache(
'IBLOCK_ELEMENT', $item[
"ITEM_ID"]))
1984 $dbProduct = CIBlockElement::GetList(
array(),
array(
"ID" => $item[
"ITEM_ID"]),
false,
false,
array(
'ID',
'IBLOCK_ID',
'NAME',
'IBLOCK_SECTION_ID'));
1985 if ($arProduct = $dbProduct->Fetch())
1987 static::setHitCache(
'IBLOCK_ELEMENT', $item[
"ITEM_ID"], $arProduct);
1991 if (!$arPropsSku = static::getHitCache(
'IBLOCK_PROPERTY', $arParentSku[
'OFFER_IBLOCK_ID']))
1994 'select' =>
array(
'ID',
'IBLOCK_ID',
'CODE'),
1996 '=IBLOCK_ID' => $arParentSku[
'OFFER_IBLOCK_ID'],
1999 '!=ID' => $arParentSku[
'SKU_PROPERTY_ID']
2001 'order' =>
array(
'SORT' =>
'ASC')
2004 $arPropsSku[] = $row[
'CODE'];
2007 static::setHitCache(
'IBLOCK_PROPERTY', $arParentSku[
'OFFER_IBLOCK_ID'], $arPropsSku);
2010 $proxyProductPropertyKey = $item[
"ITEM_ID"].
"_".$arParentSku[
"IBLOCK_ID"].
"_".md5(join(
'|', $arPropsSku));
2012 if (!$product_properties = static::getHitCache(
'PRODUCT_PROPERTY', $proxyProductPropertyKey))
2016 $arParentSku[
"IBLOCK_ID"],
2020 static::setHitCache(
'PRODUCT_PROPERTY', $proxyProductPropertyKey, $product_properties);
2023 foreach ($product_properties as $propData)
2025 $arItem[
"PROPS"][] =
array(
2026 "NAME" => $propData[
"NAME"],
2027 "CODE" => $propData[
"CODE"],
2028 "VALUE" => $propData[
"VALUE"],
2029 "SORT" => $propData[
"SORT"]
2034 $arSets[
$k][
"ITEMS"][$k1] = array_merge($item, $arItem);
2038 if (!$productList = static::getHitCache(
'IBLOCK_ELEMENT_LIST', $productID))
2040 $rsProducts = CIBlockElement::GetList(
2042 array(
'ID' => $arProductId),
2045 array(
"ID",
"IBLOCK_ID",
"IBLOCK_SECTION_ID",
"PREVIEW_PICTURE",
"DETAIL_PICTURE",
"IBLOCK_TYPE_ID",
"XML_ID")
2047 while ($arProduct = $rsProducts->GetNext())
2049 $productList[] = $arProduct;
2052 if (!empty($productList) && is_array($productList))
2054 static::setHitCache(
'IBLOCK_ELEMENT_LIST', $productID, $productList);
2058 if (!empty($productList) && is_array($productList))
2060 foreach ($productList as $arProduct)
2062 foreach ($arSets as
$k => $arSet)
2064 foreach ($arSet[
"ITEMS"] as $k1 => $item)
2066 if ($item[
"ITEM_ID"] == $arProduct[
"ID"])
2069 $strIBlockXmlID = strval(CIBlock::GetArrayByID($arProduct[
'IBLOCK_ID'],
'XML_ID'));
2070 if ($strIBlockXmlID !=
"")
2073 "NAME" =>
"Catalog XML_ID",
2074 "CODE" =>
"CATALOG.XML_ID",
2075 "VALUE" => $strIBlockXmlID
2079 if (!empty($proxyCatalogSkuData[$item[
"ITEM_ID"]]) && mb_strpos($arProduct[
"XML_ID"],
'#') ===
false)
2081 $arParentSku = $proxyCatalogSkuData[$item[
"ITEM_ID"]];
2082 if (!empty($proxyParentData[$arParentSku[
'ID']]) && is_array($proxyParentData[$arParentSku[
'ID']]))
2084 $parentData = $proxyParentData[$arParentSku[
'ID']];
2089 'select' =>
array(
'ID',
'XML_ID'),
2090 'filter' =>
array(
'ID' => $arParentSku[
'ID'])
2092 if ($parentData = $parentIterator->fetch())
2093 $proxyParentData[$arParentSku[
'ID']] = $parentData;
2094 unset($parentIterator);
2097 $arProduct[
"XML_ID"] = $parentData[
'XML_ID'].
'#'.$arProduct[
"XML_ID"];
2102 "NAME" =>
"Product XML_ID",
2103 "CODE" =>
"PRODUCT.XML_ID",
2104 "VALUE" => $arProduct[
"XML_ID"]
2107 $arSets[
"$k"][
"ITEMS"][$k1][
"IBLOCK_ID"] = $arProduct[
"IBLOCK_ID"];
2108 $arSets[
"$k"][
"ITEMS"][$k1][
"IBLOCK_SECTION_ID"] = $arProduct[
"IBLOCK_SECTION_ID"];
2109 $arSets[
"$k"][
"ITEMS"][$k1][
"PREVIEW_PICTURE"] = $arProduct[
"PREVIEW_PICTURE"];
2110 $arSets[
"$k"][
"ITEMS"][$k1][
"DETAIL_PICTURE"] = $arProduct[
"DETAIL_PICTURE"];
2111 $arSets[
"$k"][
"ITEMS"][$k1][
"PRODUCT_XML_ID"] = $arProduct[
"XML_ID"];
2112 $arSets[
"$k"][
"ITEMS"][$k1][
"PROPS"] = array_merge($arSets[
"$k"][
"ITEMS"][$k1][
"PROPS"], $arProps);
2126 protected static function isNeedClearPublicCache($currentQuantity, $newQuantity, $quantityTrace, $canBuyZero, $ratio = 1): bool
2141 $adminSection = (defined(
'ADMIN_SECTION') &&
ADMIN_SECTION ===
true);
2148 static $arUserCache =
array();
2154 if (!isset($arUserCache[
$userId]))
2157 'select' =>
array(
'ID'),
2160 if ($userDat = $userIterator->fetch())
2162 $userDat[
'ID'] = (int)$userDat[
'ID'];
2163 $arUserCache[$userDat[
'ID']] = CUser::GetUserGroup($userDat[
'ID']);
2171 $dbIBlockElement = CIBlockElement::GetList(
2176 'ACTIVE_DATE' =>
'Y',
2177 'CHECK_PERMISSION' =>
'N'
2181 array(
'ID',
'IBLOCK_ID',
'NAME',
'DETAIL_PAGE_URL')
2183 if (!($arProduct = $dbIBlockElement->GetNext()))
2187 $iblockRights =
null;
2189 if (!$iblockRights = static::getHitCache(self::CACHE_IBLOCK_RIGHTS_MODE, $arProduct[
'IBLOCK_ID']))
2191 if ($iblockRights = CIBlock::GetArrayByID($arProduct[
'IBLOCK_ID'],
'RIGHTS_MODE'))
2193 static::setHitCache(self::CACHE_IBLOCK_RIGHTS_MODE, $arProduct[
'IBLOCK_ID'], $iblockRights);
2197 if ($iblockRights ==
'E')
2199 $proxyUserPermissionKey = $productId.
"|".
$userId;
2201 if (!$arUserRights = static::getHitCache(self::CACHE_USER_RIGHTS, $proxyUserPermissionKey))
2203 if ($arUserRights = CIBlockElementRights::GetUserOperations($productId,
$userId))
2205 static::setHitCache(self::CACHE_USER_RIGHTS, $proxyUserPermissionKey, $arUserRights);
2209 if (empty($arUserRights) || !isset($arUserRights[
'element_read']))
2212 unset($arUserRights);
2216 if (CIBlock::GetPermission($arProduct[
'IBLOCK_ID'],
$userId) <
'R')
2222 $dbIBlockElement = CIBlockElement::GetList(
2227 'ACTIVE_DATE' =>
'Y',
2228 'CHECK_PERMISSIONS' =>
'Y',
2229 'MIN_PERMISSION' =>
'R'
2233 array(
'ID',
'IBLOCK_ID',
'NAME',
'DETAIL_PAGE_URL')
2235 if (!($arProduct = $dbIBlockElement->GetNext()))
2241 array(
'ID' => $productId),
2251 if ($arCatalogProduct = $rsProducts->Fetch())
2258 return $arCatalogProduct[
'QUANTITY'];
2271 if (!isset(self::$userCache[
$userId]))
2274 return self::$userCache[
$userId];
2277 protected static function getProductPoolQuantityByBasketItem(\
Bitrix\Sale\BasketItem $basketItem)
2280 if (!$basket = $basketItem->getCollection())
2284 if (!
$order = $basket->getOrder())
2287 return \Bitrix\Sale\Provider::getReservationPoolItem(
$order->getInternalId(), $basketItem);
2292 $priceType = (int)$priceType;
2293 if ($priceType <= 0)
2295 if (!isset(self::$priceTitleCache[$priceType]))
2297 self::$priceTitleCache[$priceType] =
'';
2299 'select' =>
array(
'ID',
'NAME',
'NAME_LANG' =>
'CURRENT_LANG.NAME'),
2300 'filter' =>
array(
'=ID' => $priceType)
2304 $group[
'NAME_LANG'] = (string)$group[
'NAME_LANG'];
2305 self::$priceTitleCache[$priceType] = ($group[
'NAME_LANG'] !=
'' ? $group[
'NAME_LANG'] : $group[
'NAME']);
2309 return self::$priceTitleCache[$priceType];
2322 if (!static::isExistsHitCache(self::CACHE_PARENT_PRODUCT_ACTIVE, $cacheKey))
2325 $parent = CCatalogSku::GetProductInfo($productId,
$iblockId);
2326 if (!empty($parent))
2328 $itemList = CIBlockElement::GetList(
2331 'ID' => $parent[
'ID'],
2332 'IBLOCK_ID' => $parent[
'IBLOCK_ID'],
2334 'ACTIVE_DATE' =>
'Y',
2335 'CHECK_PERMISSIONS' =>
'N'
2341 $item = $itemList->Fetch();
2346 static::setHitCache(self::CACHE_PARENT_PRODUCT_ACTIVE, $cacheKey,
$result);
2349 return (static::getHitCache(self::CACHE_PARENT_PRODUCT_ACTIVE, $cacheKey) !=
'N');
2360 if (!empty(self::$hitCache[
$type]) && !empty(self::$hitCache[
$type][
$key]))
2374 return (!empty(self::$hitCache[
$type]) && !empty(self::$hitCache[
$type][
$key]));
2386 if (empty(self::$hitCache[
$type]))
2389 if (empty(self::$hitCache[
$type][
$key]))
2403 self::$hitCache =
array();
2405 unset(self::$hitCache[
$type]);
2416 $countStores = static::GetStoresCount(
array(
'SITE_ID' => $basketItem->getField(
'LID')));
2417 $defaultDeductionStore =
Main\Config\Option::get(
"sale",
"deduct_store_id",
"", $basketItem->getField(
'LID'));
2419 $canAutoDeduct = (($countStores == 1 || $countStores == -1 || $defaultDeductionStore > 0) && !$basketItem->isBarcodeMulti());
2421 $countProductStores = 0;
2423 if ($canAutoDeduct ===
true)
2426 if ($productStore = static::GetProductStores(
array(
2427 'PRODUCT_ID' => $basketItem->getProductId(),
2428 'SITE_ID' => $basketItem->getField(
'LID')
2431 foreach ($productStore as $productStoreItem)
2433 if ($productStoreItem[
'AMOUNT'] > 0)
2435 $countProductStores++;
2440 return ($countProductStores == 1);
2451 $productStoreData =
array();
2453 if ($productStore = static::GetProductStores(
array(
2454 'PRODUCT_ID' => $basketItem->getProductId(),
2455 'SITE_ID' => $basketItem->getField(
'LID')
2458 foreach ($productStore as $productStoreItem)
2460 if ($productStoreItem[
'AMOUNT'] > 0)
2462 $productStoreData =
array(
2463 $productStoreItem[
'STORE_ID'] =>
array(
2464 'STORE_ID' => $productStoreItem[
'STORE_ID'],
2465 'QUANTITY' => $quantity
2473 return (!empty($productStoreData) ? $productStoreData :
false);
2484 $productStoreData =
array();
2486 if ($productStore = static::GetProductStores(
array(
2487 'PRODUCT_ID' => $basketItem->getProductId(),
2488 'SITE_ID' => $basketItem->getField(
'LID')
2491 if (
count($productStore) != 1)
2496 foreach ($productStore as $productStoreItem)
2498 $productStoreData =
array(
2499 $productStoreItem[
'STORE_ID'] =>
array(
2500 'STORE_ID' => $productStoreItem[
'STORE_ID'],
2501 'QUANTITY' => $quantity,
2507 return (!empty($productStoreData) ? $productStoreData :
false);
2512 $filterId =
array(
'ACTIVE' =>
'Y');
2514 $filterId[
'+SITE_ID'] =
$params[
'SITE_ID'];
2516 $cacheId = md5(serialize($filterId));
2517 $storeIds = static::getHitCache(self::CACHE_STORE, $cacheId);
2518 if (empty($storeIds))
2520 $storeIds =
array();
2522 $filter = Main\Entity\Query::filter();
2523 $filter->where(
'ACTIVE',
'=',
'Y');
2526 $subFilter = Main\Entity\Query::filter();
2527 $subFilter->logic(
'or')->where(
'SITE_ID',
'=',
$params[
'SITE_ID'])->where(
'SITE_ID',
'=',
'')->whereNull(
'SITE_ID');
2533 'select' =>
array(
'ID'),
2535 'order' =>
array(
'ID' =>
'ASC')
2538 $storeIds[] = (int)$row[
'ID'];
2540 if (!empty($storeIds))
2541 static::setHitCache(self::CACHE_STORE, $cacheId, $storeIds);
2543 unset($cacheId, $filterId);
2558 if (empty($allSets))
2564 $set = current($allSets);
2567 foreach ($set[
'ITEMS'] as $item)
2569 if ($item[
'ITEM_ID'] != $item[
'OWNER_ID'])
2570 $itemIds[$item[
'ITEM_ID']] = $item[
'ITEM_ID'];
2572 if (empty($itemIds))
2582 'ACTIVE_DATE' =>
'Y',
2583 'CHECK_PERMISSIONS' =>
'N'
2587 array(
'ID',
'IBLOCK_ID')
2590 unset($itemIds[$row[
'ID']]);
2593 if (!empty($itemIds))
2595 static::$errors[] =
Loc::getMessage(
'CATALOG_ERR_NO_PRODUCT_SET_ITEM');
2618 return static::isReservationEnabled();
CatalogViewedProductCallback($productID, $UserID, $strSiteID=SITE_ID)
CatalogPayOrderCallback($productID, $userID, $bPaid, $orderID)
CatalogRecurringCallback($productID, $userID)
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static isUsedInventoryManagement()
static update($id, array $data)
static getList(array $parameters)
static setConfig(array $config)
static checkCurrencyID($currency)
static get($moduleId, $name, $default="", $siteId=false)
static getMessage($code, $replace=null, $language=null)
static getList(array $parameters=array())
static getUserGroupIds($userId)
static getForApply($filter, $product=[], $uniqueDiscount=false)
static setApplyByProduct($product, $couponsList, $oldMode=false)
static isUsedSaleDiscountOnly()
static getDiscountDescription(array $discount)
static calculateDiscountList($priceData, $currency, &$discountList, $getWithVat=true)
static ClearDiscountUserID()
static SetDiscountUserID($intUserID)
static GetNearestQuantityPrice($productID, $quantity=1, $arUserGroups=array())
static Update($id, $fields)
static GetOptimalPrice($intProductID, $quantity=1, $arUserGroups=array(), $renewal="N", $priceList=array(), $siteID=false, $arDiscountCoupons=false)
static GetVATDataByID($id)
static GetList($arOrder=array(), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
const CACHE_PARENT_PRODUCT_ACTIVE
static getUserGroups($userId)
const CACHE_IBLOCK_RIGHTS
static getPriceTitle($priceType)
const CACHE_ITEM_WITH_RIGHTS
static GetProductStores($arParams)
static RecurringOrderProduct($arParams)
static isNeedClearPublicCache($currentQuantity, $newQuantity, $quantityTrace, $canBuyZero, $ratio=1)
const CACHE_STORE_PRODUCT
static $proxyIblockRights
static checkProductSet($productId)
static CancelProduct($arParams)
static isReservationEnabled()
static getProductAvailableQuantity($productId, $userId=null)
static GetSetItems($productID, $intType, $arProducInfo=array())
static GetStoresCount($arParams=array())
static $proxyIblockElementListPermN
static $proxyCatalogProduct
static GetProductData($arParams)
static checkParentActivity($productId, $iblockId=0)
static isExistsHitCache($type, $key)
static getStoreIds(array $params)
static tryShipmentProduct(\Bitrix\Sale\BasketItem $basketItem, $reserved='N', array $basketStoreData=array(), $quantity=null)
static OrderProduct($arParams)
const CACHE_ITEM_WITHOUT_RIGHTS
static ReserveProduct($arParams)
static clearHitCache($type=null)
const CATALOG_PROVIDER_EMPTY_STORE_ID
static CheckProductBarcode($arParams)
static getProductOneStoreData(\Bitrix\Sale\BasketItem $basketItem, $quantity)
static ViewProduct($arParams)
static canProductAutoShip(\Bitrix\Sale\BasketItem $basketItem)
const CACHE_IBLOCK_RIGHTS_MODE
static $proxyIblockElementListPermY
static getHitCache($type, $key)
static DeliverProduct($arParams)
static setHitCache($type, $key, $value)
static clearPublicCache($productID, $productInfo=array())
static tryUnshipmentProduct($productId)
static getProductStoreData(\Bitrix\Sale\BasketItem $basketItem, $quantity)
static getAllSetsByProduct($intProductID, $intSetType)
static getStoreName($storeId)
static Update($id, $arFields)
static GetList($arOrder=array(), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
static GetLangCurrency($siteId)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
static DeductProduct($arFields)
ExecuteModuleEventEx($arEvent, $arParams=[])
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']