26 if (!is_array($arBasketItem)
27 || empty($arBasketItem)
28 || !isset($arBasketItem[
"MODULE"])
29 || !isset($arBasketItem[
"PRODUCT_PROVIDER_CLASS"])
30 || ($arBasketItem[
"PRODUCT_PROVIDER_CLASS"] ==
'')
34 $productProviderClass = $arBasketItem[
"PRODUCT_PROVIDER_CLASS"];
36 if (CModule::IncludeModule($arBasketItem[
"MODULE"])
37 && class_exists($productProviderClass)
38 && ((array_key_exists(
"IBXSaleProductProvider", class_implements($productProviderClass))))
41 return $productProviderClass;
47 return '\Bitrix\Catalog\Product\CatalogProviderCompatibility';
63 return "CSaleBasket::ClearProductSubscribe('".$LID.
"');";
73 public static function ProductSubscribe(
$ID, $MODULE)
76 $MODULE = trim($MODULE);
78 if (
$ID <= 0 || $MODULE ==
'')
82 $subscribeProd = COption::GetOptionString(
"sale",
"subscribe_prod",
"");
87 array(
"USER_ID" =>
"DESC",
"LID" =>
"ASC"),
102 'MODULE',
'PRODUCT_ID',
'CURRENCY',
'DATE_INSERT',
'QUANTITY',
'LID',
'DELAY',
'CALLBACK_FUNC',
'SUBSCRIBE',
'PRODUCT_PROVIDER_CLASS')
104 while ($arItemsBasket = $rsItemsBasket->Fetch())
106 $LID = $arItemsBasket[
"LID"];
110 $sendEmailList =
array();
111 $USER_ID = $arItemsBasket[
'USER_ID'];
112 $arMailProp =
array();
113 $arPayerProp =
array();
117 if (!empty($arUserProfiles))
121 while ($arPersonType = $dbPersonType->Fetch())
126 array(
"PERSON_TYPE_ID" => $arPersonType[
"ID"],
"IS_EMAIL" =>
"Y",
"ACTIVE" =>
"Y"),
129 array(
'ID',
'PERSON_TYPE_ID')
137 array(
"PERSON_TYPE_ID" => $arPersonType[
"ID"],
"IS_PAYER" =>
"Y",
"ACTIVE" =>
"Y"),
140 array(
'ID',
'PERSON_TYPE_ID')
148 $arUser = $rsUser->Fetch();
155 $arUserSendName =
array();
156 if (!empty($arUserProfiles) && !empty($arPayerProp))
158 foreach($arPayerProp as $personType => $namePropID)
160 if (isset($arUserProfiles[$personType]))
162 foreach($arUserProfiles[$personType] as $profiles)
164 if (isset($profiles[
"VALUES"][$namePropID]) && $profiles[
"VALUES"][$namePropID] !=
'')
166 $arUserSendName[$personType] = trim($profiles[
"VALUES"][$namePropID]);
171 $arUserSendName[$personType] =
$userName;
177 $arUserSendName[$personType] =
$userName;
187 $arUserSendMail =
array();
188 if (!empty($arUserProfiles) && !empty($arMailProp))
190 foreach($arMailProp as $personType => $mailPropID)
192 if (isset($arUserProfiles[$personType]))
194 foreach($arUserProfiles[$personType] as $profiles)
196 if (isset($profiles[
"VALUES"][$mailPropID]) && $profiles[
"VALUES"][$mailPropID] !=
'')
198 $arUserSendMail[$personType] = trim($profiles[
"VALUES"][$mailPropID]);
203 $arUserSendMail[$personType] = $arUser[
"EMAIL"];
209 $arUserSendMail[$personType] = $arUser[
"EMAIL"];
215 $arUserSendMail[] = $arUser[
"EMAIL"];
221 $arCallback = $productProvider::GetProductData(
array(
225 "USER_ID" => $USER_ID,
227 "BASKET_ID" => $arItemsBasket[
"ID"],
230 elseif (isset($arItemsBasket[
"CALLBACK_FUNC"]) && !empty($arItemsBasket[
"CALLBACK_FUNC"]))
233 trim($arItemsBasket[
"CALLBACK_FUNC"]),
243 if (!empty($arCallback))
245 $arCallback[
"QUANTITY"] = 1;
246 $arCallback[
"DELAY"] =
"N";
247 $arCallback[
"SUBSCRIBE"] =
"N";
248 CSaleBasket::Update($arItemsBasket[
"ID"], $arCallback);
252 if (!empty($arUserSendMail) && !empty($arCallback))
254 $eventName =
"SALE_SUBSCRIBE_PRODUCT";
257 foreach ($arUserSendMail as $personType => $mail)
259 $checkMail = mb_strtolower($mail);
260 if (isset($sendEmailList[$checkMail]))
263 if (isset($arUserSendName[$personType]) && $arUserSendName[$personType] !=
'')
264 $sendName = $arUserSendName[$personType];
268 "USER_NAME" => $sendName,
269 "NAME" => $arCallback[
"NAME"],
271 "SALE_EMAIL" => COption::GetOptionString(
"sale",
"order_email",
"order@".
$_SERVER[
"SERVER_NAME"]),
275 $sendEmailList[$checkMail] =
true;
284 public static function DoGetUserShoppingCart(
$siteId,
$userId, $shoppingCart, &$arErrors, $arCoupons =
array(),
$orderId = 0, $enableCustomCurrency =
false)
286 $isOrderConverted = Option::get(
"main",
"~sale_converted_15",
'Y');
291 $arErrors[] =
array(
"CODE" =>
"PARAM",
"TEXT" => Loc::getMessage(
'SKGB_PARAM_SITE_ERROR'));
297 if (!is_array($shoppingCart))
299 if (intval($shoppingCart).
"|" != $shoppingCart.
"|")
301 $arErrors[] =
array(
"CODE" =>
"PARAM",
"TEXT" => Loc::getMessage(
'SKGB_PARAM_SK_ERROR'));
304 $shoppingCart = intval($shoppingCart);
307 array(
"NAME" =>
"ASC"),
309 "FUSER_ID" => $shoppingCart,
311 "ORDER_ID" =>
"NULL",
317 "ID",
"LID",
"CALLBACK_FUNC",
"MODULE",
"PRODUCT_ID",
"QUANTITY",
"DELAY",
318 "CAN_BUY",
"PRICE",
"WEIGHT",
"NAME",
"CURRENCY",
"CATALOG_XML_ID",
319 "VAT_RATE",
"NOTES",
"DISCOUNT_PRICE",
"DETAIL_PAGE_URL",
"PRODUCT_PROVIDER_CLASS",
320 "RESERVED",
"DEDUCTED",
"RESERVE_QUANTITY",
"DIMENSIONS",
"TYPE",
"SET_PARENT_ID"
324 while ($arShoppingCartItem = $dbShoppingCartItems->Fetch())
325 $arTmp[] = $arShoppingCartItem;
330 $arOldShoppingCart =
array();
334 array(
"NAME" =>
"ASC"),
343 "ID",
"LID",
"CALLBACK_FUNC",
"MODULE",
"PRODUCT_ID",
"PRODUCT_PRICE_ID",
"PRICE",
344 "QUANTITY",
"DELAY",
"CAN_BUY",
"PRICE",
"WEIGHT",
"NAME",
"CURRENCY",
345 "CATALOG_XML_ID",
"VAT_RATE",
"NOTES",
"DISCOUNT_PRICE",
"DETAIL_PAGE_URL",
"PRODUCT_PROVIDER_CLASS",
346 "RESERVED",
"DEDUCTED",
"BARCODE_MULTI",
"DIMENSIONS",
"TYPE",
"SET_PARENT_ID"
349 while ($arOldShoppingCartItem = $dbs->Fetch())
350 $arOldShoppingCart[$arOldShoppingCartItem[
"ID"]] = $arOldShoppingCartItem;
354 $shoppingCart =
array($shoppingCart);
356 if (!empty($arCoupons))
358 if (!is_array($arCoupons))
359 $arCoupons =
array($arCoupons);
362 foreach ($arCoupons as &$coupon)
363 $couponResult = DiscountCouponsManager::add($coupon);
364 unset($coupon, $couponResult);
367 if(!is_bool($enableCustomCurrency))
369 $enableCustomCurrency =
false;
375 foreach ($shoppingCart as $itemIndex => $arShoppingCartItem)
377 if ((array_key_exists(
"CALLBACK_FUNC", $arShoppingCartItem) && !empty($arShoppingCartItem[
"CALLBACK_FUNC"]))
378 || (array_key_exists(
"PRODUCT_PROVIDER_CLASS", $arShoppingCartItem) && !empty($arShoppingCartItem[
"PRODUCT_PROVIDER_CLASS"])))
383 $quantity = $arShoppingCartItem[
"QUANTITY"] - $arOldShoppingCart[$arShoppingCartItem[
"ID_TMP"]][
"QUANTITY"];
385 $quantity = $arShoppingCartItem[
"QUANTITY"];
387 $customPrice = (isset($arShoppingCartItem[
'CUSTOM_PRICE']) && $arShoppingCartItem[
'CUSTOM_PRICE'] ==
'Y');
388 $existBasketID = (isset($arShoppingCartItem[
'ID']) && (int)$arShoppingCartItem[
'ID'] > 0);
394 $basketID = $arShoppingCartItem[
'ID'];
396 elseif (isset($arShoppingCartItem[
"ID_TMP"]))
398 $basketID = $arShoppingCartItem[
"ID_TMP"];
402 $basketID =
'tmp_'.$emptyID;
405 $providerParams =
array(
406 "PRODUCT_ID" => $arShoppingCartItem[
"PRODUCT_ID"],
407 "QUANTITY" => ($quantity > 0) ? $quantity : $arShoppingCartItem[
"QUANTITY"],
411 "BASKET_ID" => $basketID,
412 "CHECK_QUANTITY" => ($quantity > 0) ?
"Y" :
"N",
413 "CHECK_COUPONS" => (
'Y' == $arShoppingCartItem[
'CAN_BUY'] && (!array_key_exists(
'DELAY', $arShoppingCartItem) ||
'Y' != $arShoppingCartItem[
'DELAY']) ?
'Y' :
'N'),
414 "CHECK_PRICE" => ($customPrice ?
"N" :
"Y")
416 if (isset($arShoppingCartItem[
'NOTES']))
417 $providerParams[
'NOTES'] = $arShoppingCartItem[
'NOTES'];
418 $arFieldsTmp = $productProvider::GetProductData($providerParams);
419 unset($providerParams);
424 $arShoppingCartItem[
"CALLBACK_FUNC"],
425 $arShoppingCartItem[
"MODULE"],
426 $arShoppingCartItem[
"PRODUCT_ID"],
432 if (!empty($arFieldsTmp) && is_array($arFieldsTmp))
435 unset($arFieldsTmp[
'PRICE'], $arFieldsTmp[
'CURRENCY']);
439 if (!empty($arFieldsTmp) && is_array($arFieldsTmp))
441 $arFieldsTmp[
"CAN_BUY"] =
"Y";
442 $arFieldsTmp[
"SUBSCRIBE"] =
"N";
443 $arFieldsTmp[
'TYPE'] = (int)$arShoppingCartItem[
'TYPE'];
444 $arFieldsTmp[
'SET_PARENT_ID'] = $arShoppingCartItem[
'SET_PARENT_ID'];
449 $arFieldsTmp =
array(
"CAN_BUY" =>
"N");
452 if ($isOrderConverted !=
'N')
455 Sale\Compatible\DiscountCompatibility::init();
456 $basketCode = (Sale\Compatible\DiscountCompatibility::usedByClient() ? $arShoppingCartItem[
'ID'] : $itemIndex);
457 Sale\Compatible\DiscountCompatibility::setBasketItemData($basketCode, $arFieldsTmp);
462 $arFieldsTmp[
"IGNORE_CALLBACK_FUNC"] =
"Y";
464 CSaleBasket::Update($arShoppingCartItem[
"ID"], $arFieldsTmp);
468 array(
"ID" => $arShoppingCartItem[
"ID"]),
472 "ID",
"CALLBACK_FUNC",
"MODULE",
"PRODUCT_ID",
"QUANTITY",
"DELAY",
"CAN_BUY",
"PRICE",
"TYPE",
"SET_PARENT_ID",
473 "WEIGHT",
"NAME",
"CURRENCY",
"CATALOG_XML_ID",
"VAT_RATE",
"NOTES",
"DISCOUNT_PRICE",
"DETAIL_PAGE_URL",
"PRODUCT_PROVIDER_CLASS",
"DIMENSIONS"
483 foreach ($arFieldsTmp as
$key =>
$val)
486 if (
$orderId != 0 &&
$key ==
"QUANTITY" && $arOldShoppingCart[$arShoppingCartItem[
"ID_TMP"]][
"RESERVED"] ==
"Y" && $quantity > 0)
488 $arShoppingCartItem[
$key] =
$val + $arOldShoppingCart[$arShoppingCartItem[
"ID_TMP"]][
"QUANTITY"];
498 if ($arShoppingCartItem[
"CAN_BUY"] ==
"Y")
500 if(!$enableCustomCurrency)
503 if ($baseLangCurrency != $arShoppingCartItem[
"CURRENCY"])
506 if (
is_set($arShoppingCartItem,
"DISCOUNT_PRICE"))
507 $arShoppingCartItem[
"DISCOUNT_PRICE"] =
CCurrencyRates::ConvertCurrency($arShoppingCartItem[
"DISCOUNT_PRICE"], $arShoppingCartItem[
"CURRENCY"], $baseLangCurrency);
508 $arShoppingCartItem[
"CURRENCY"] = $baseLangCurrency;
512 $arShoppingCartItem[
"PRICE"] = \Bitrix\Sale\PriceMaths::roundPrecision($arShoppingCartItem[
"PRICE"]);
514 $arShoppingCartItem[
"QUANTITY"] = floatval($arShoppingCartItem[
"QUANTITY"]);
515 $arShoppingCartItem[
"WEIGHT"] = floatval($arShoppingCartItem[
"WEIGHT"]);
516 $arShoppingCartItem[
"DIMENSIONS"] = unserialize($arShoppingCartItem[
"DIMENSIONS"], [
'allowed_classes' =>
false]);
517 $arShoppingCartItem[
"VAT_RATE"] = floatval($arShoppingCartItem[
"VAT_RATE"]);
520 if ($arShoppingCartItem[
"VAT_RATE"] > 0)
521 $arShoppingCartItem[
"VAT_VALUE"] = \Bitrix\Sale\PriceMaths::roundPrecision(($arShoppingCartItem[
"PRICE"] / ($arShoppingCartItem[
"VAT_RATE"] + 1)) * $arShoppingCartItem[
"VAT_RATE"]);
524 if ($arShoppingCartItem[
"DISCOUNT_PRICE"] > 0)
525 $arShoppingCartItem[
"DISCOUNT_PRICE_PERCENT"] = $arShoppingCartItem[
"DISCOUNT_PRICE"] * 100 / ($arShoppingCartItem[
"DISCOUNT_PRICE"] + $arShoppingCartItem[
"PRICE"]);
526 $arResult[$itemIndex] = $arShoppingCartItem;
529 if (isset($arShoppingCartItem))
530 unset($arShoppingCartItem);
532 if (!empty($arCoupons) && is_array($arCoupons))
534 foreach(
GetModuleEvents(
"sale",
"OnClearCouponList",
true) as $arEvent)
559 public static function DoChangeProductQuantity($arBasketItem, $deltaQuantity, $isOrderReserved =
false, $isOrderDeducted =
false, $arStoreBarcodeOrderFormData =
array(), $arAdditionalParams =
array())
563 if (!array_key_exists(
"CHECK_QUANTITY", $arAdditionalParams) || $arAdditionalParams[
"CHECK_QUANTITY"] !=
"N")
564 $arAdditionalParams[
"CHECK_QUANTITY"] =
"Y";
569 "DoChangeProductQuantity - Started",
571 "arBasketItem" => $arBasketItem,
572 "deltaQuantity" => $deltaQuantity,
573 "isOrderReserved" => intval($isOrderReserved),
574 "isOrderDeducted" => intval($isOrderDeducted),
575 "arStoreBarcodeOrderFormData" => $arStoreBarcodeOrderFormData,
576 "checkQuantity" => $arAdditionalParams[
"CHECK_QUANTITY"]
585 $productProvider::OrderProduct(
587 "PRODUCT_ID" => $arBasketItem[
"PRODUCT_ID"],
588 "QUANTITY" => ($deltaQuantity <= 0 ? $arBasketItem[
'QUANTITY'] : $deltaQuantity),
590 "USER_ID" => $arAdditionalParams[
"USER_ID"],
591 "SITE_ID" => $arAdditionalParams[
"SITE_ID"],
592 "CHECK_QUANTITY" => $arAdditionalParams[
"CHECK_QUANTITY"],
593 "BASKET_ID" => $arBasketItem[
'ID']
596 if ($deltaQuantity == 0 && $arAdditionalParams[
"CHECK_QUANTITY"] ==
'N')
599 if ($isOrderDeducted)
601 $quantityPreviouslyLeftToReserve = ($arBasketItem[
"RESERVED"] ==
"Y") ? floatval($arBasketItem[
"RESERVE_QUANTITY"]) : 0;
606 "Call ::ReserveBasketProduct",
608 "arBasketItemID" => $arBasketItem[
"ID"],
609 "deltaQuantity" => $deltaQuantity,
610 "quantityPreviouslyLeftToReserve" => $quantityPreviouslyLeftToReserve,
611 "isOrderDeducted" => $isOrderDeducted
617 $arRes = CSaleBasket::ReserveBasketProduct($arBasketItem[
"ID"], $deltaQuantity + $quantityPreviouslyLeftToReserve, $isOrderDeducted);
618 if (array_key_exists(
"ERROR",
$arRes))
627 "Call ::DeductBasketProduct",
629 "arBasketItemID" => $arBasketItem[
"ID"],
630 "deltaQuantity" => $deltaQuantity,
631 "arStoreBarcodeOrderFormData" => $arStoreBarcodeOrderFormData
637 $arDeductResult = CSaleBasket::DeductBasketProduct($arBasketItem[
"ID"], $deltaQuantity, $arStoreBarcodeOrderFormData);
638 if (array_key_exists(
"ERROR", $arDeductResult))
640 CSaleOrder::SetMark($arAdditionalParams[
"ORDER_ID"], Loc::getMessage(
"SKGB_DEDUCT_ERROR",
array(
"#MESSAGE#" => $arDeductResult[
"ERROR"][
"MESSAGE"])));
641 $APPLICATION->ThrowException(Loc::getMessage(
"SKGB_DEDUCT_ERROR",
array(
"#MESSAGE#" => $arDeductResult[
"ERROR"][
"MESSAGE"])),
"DEDUCTION_ERROR");
645 else if ($isOrderReserved && !$isOrderDeducted)
647 if ($arBasketItem[
"RESERVED"] ==
"Y")
649 $quantityPreviouslyLeftToReserve = floatval($arBasketItem[
"RESERVE_QUANTITY"]);
654 "Call ::ReserveBasketProduct",
656 "arBasketItemID" => $arBasketItem[
"ID"],
657 "deltaQuantity" => $deltaQuantity,
658 "quantityPreviouslyLeftToReserve" => $quantityPreviouslyLeftToReserve
664 $arRes = CSaleBasket::ReserveBasketProduct($arBasketItem[
"ID"], $deltaQuantity + $quantityPreviouslyLeftToReserve);
665 if (array_key_exists(
"ERROR",
$arRes))
676 "Call ::ReserveBasketProduct",
678 "arBasketItemID" => $arBasketItem[
"ID"],
679 "deltaQuantity" => $deltaQuantity
685 $arRes = CSaleBasket::ReserveBasketProduct($arBasketItem[
"ID"], $deltaQuantity);
686 if (array_key_exists(
"ERROR",
$arRes))
698 "Call ::ReserveBasketProduct",
700 "arBasketItemID" => $arBasketItem[
"ID"],
701 "deltaQuantity" => $deltaQuantity
707 if ($arBasketItem[
"RESERVED"] ==
"Y")
709 $quantityPreviouslyLeftToReserve = floatval($arBasketItem[
"RESERVE_QUANTITY"]);
711 $arRes = CSaleBasket::ReserveBasketProduct($arBasketItem[
"ID"], $deltaQuantity + $quantityPreviouslyLeftToReserve);
712 if (array_key_exists(
"ERROR",
$arRes))
722 if ($deltaQuantity < 0)
725 $arBasketItem[
"CANCEL_CALLBACK_FUNC"],
726 $arBasketItem[
"MODULE"],
727 $arBasketItem[
"PRODUCT_ID"],
732 else if ($deltaQuantity > 0)
735 $arBasketItem[
"ORDER_CALLBACK_FUNC"],
736 $arBasketItem[
"MODULE"],
737 $arBasketItem[
"PRODUCT_ID"],
740 $arAdditionalParams[
"USER_ID"],
741 $arAdditionalParams[
"SITE_ID"]
744 else if ($deltaQuantity == 0)
747 $arBasketItem[
"ORDER_CALLBACK_FUNC"],
748 $arBasketItem[
"MODULE"],
749 $arBasketItem[
"PRODUCT_ID"],
750 $arBasketItem[
'QUANTITY'],
752 $arAdditionalParams[
"USER_ID"],
753 $arAdditionalParams[
"SITE_ID"]
774 public static function DoSaveOrderBasket(
$orderId,
$siteId,
$userId, &$arShoppingCart, &$arErrors, $arCoupons =
array(), $arStoreBarcodeOrderFormData =
array(), $bSaveBarcodes =
false)
780 $currentUserID = (int)
$USER->GetID();
789 "arShoppingCart" => $arShoppingCart,
790 "bSaveBarcodes" => $bSaveBarcodes,
791 "arStoreBarcodeOrderFormData" => $arStoreBarcodeOrderFormData
797 $isOrderConverted = Option::get(
"main",
"~sale_converted_15",
'Y');
803 if (empty($arShoppingCart) || !is_array($arShoppingCart))
805 $arErrors[] =
array(
"CODE" =>
"PARAM",
"TEXT" => Loc::getMessage(
'SKGB_SHOPPING_CART_EMPTY'));
809 $isOrderReserved =
false;
810 $isOrderDeducted =
false;
816 array(
"ID",
"RESERVED",
"DEDUCTED")
818 if ($arOrder = $dbOrderTmp->Fetch())
820 if ($arOrder[
"RESERVED"] ==
"Y")
821 $isOrderReserved =
true;
822 if ($arOrder[
"DEDUCTED"] ==
"Y")
823 $isOrderDeducted =
true;
826 $arOldItems =
array();
835 "CANCEL_CALLBACK_FUNC",
838 "PRODUCT_PROVIDER_CLASS",
845 while ($arItem = $dbItems->Fetch())
847 $arOldItems[$arItem[
"ID"]] =
array(
848 "QUANTITY" => $arItem[
"QUANTITY"],
849 "CANCEL_CALLBACK_FUNC" => $arItem[
"CANCEL_CALLBACK_FUNC"],
850 "PRODUCT_PROVIDER_CLASS" => $arItem[
"PRODUCT_PROVIDER_CLASS"],
851 "MODULE" => $arItem[
"MODULE"],
852 "PRODUCT_ID" => $arItem[
"PRODUCT_ID"],
853 "RESERVED" => $arItem[
"RESERVED"],
854 "RESERVE_QUANTITY" => $arItem[
"RESERVE_QUANTITY"],
855 "TYPE" => $arItem[
"TYPE"],
856 "SET_PARENT_ID" => $arItem[
"SET_PARENT_ID"]
860 if (!empty($arCoupons))
862 if (!is_array($arCoupons))
863 $arCoupons =
array($arCoupons);
866 foreach ($arCoupons as &$coupon)
867 $couponResult = DiscountCouponsManager::add($coupon);
868 unset($coupon, $couponResult);
871 $FUSER_ID = Sale\Fuser::getIdByUserId((
int)
$userId);
873 $arTmpSetParentId =
array();
876 if ($isOrderConverted ==
'N')
879 usort($arShoppingCart,
array(
"CSaleBasketHelper",
"cmpSetData"));
881 foreach ($arShoppingCart as &$arItem)
883 $arItemKeys = array_keys($arItem);
885 foreach ($arItemKeys as $fieldName)
887 if(array_key_exists(
"~".$fieldName, $arItem))
889 if ((is_array($arItem[
"~".$fieldName]) && !empty($arItem[
"~".$fieldName]))
890 || (!is_array($arItem[
"~".$fieldName]) && $arItem[
"~".$fieldName] <>
''))
892 $arItem[$fieldName] = $arItem[
"~".$fieldName];
894 unset($arItem[
"~".$fieldName]);
898 $arItem = array_filter($arItem,
array(
"CSaleBasketHelper",
"filterFields"));
903 foreach ($arShoppingCart as $arItem)
905 if (mb_strpos($arItem[
"SET_PARENT_ID"],
"tmp") !==
false)
906 $arTmpSetParentId[$arItem[
"SET_PARENT_ID"]] = $arItem[
"SET_PARENT_ID"];
910 $orderBasketPool =
array();
913 foreach ($arShoppingCart as &$arItem)
916 foreach ($arItem as $tmpKey => $tmpVal)
918 if (is_array($tmpVal) && !in_array($tmpKey,
array(
"STORES",
"CATALOG",
"PROPS")))
919 $arItem[$tmpKey] = serialize($tmpVal);
926 if (array_key_exists(
"ID", $arItem) && (
int)$arItem[
"ID"] > 0)
928 $arItem[
"ID"] = (int)$arItem[
"ID"];
934 if (array_key_exists($arItem[
"ID"], $arOldItems))
937 if ($isOrderConverted ==
'N')
941 $arAdditionalParams =
array(
947 $quantity = $arItem[
"QUANTITY"] - $arOldItems[$arItem[
"ID"]][
"QUANTITY"];
949 $arAdditionalParams[
"CHECK_QUANTITY"] = ($quantity > 0) ?
"Y" :
"N";
953 self::DoChangeProductQuantity(
958 $arStoreBarcodeOrderFormData[$arItem[
"ID"]],
964 $arAdditionalParams[
'CHECK_QUANTITY'] =
'N';
965 self::DoChangeProductQuantity(
970 $arStoreBarcodeOrderFormData[$arItem[
"ID"]],
977 unset($arOldItems[$arItem[
"ID"]]);
982 if ($isOrderConverted ==
'N')
986 self::DoChangeProductQuantity(
991 $arStoreBarcodeOrderFormData[$arItem[
"ID"]],
998 if(intval($arItem[
"FUSER_ID"]) <= 0)
1001 $arItem[
"FUSER_ID"] = $arFuserItems[
"ID"];
1005 unset($arItem[
"QUANTITY"]);
1009 if ($isOrderConverted !=
'N')
1011 $fields =
array(
"IGNORE_CALLBACK_FUNC" =>
"Y") + $arItem;
1013 $orderBasketPool[$arItem[
"ID"]] =
array(
"ORDER_ID" =>
$orderId);
1024 $r = \Bitrix\Sale\Compatible\BasketCompatibility::update($arItem[
"ID"],
$fields);
1026 if (!$r->isSuccess(
true))
1028 foreach($r->getErrorMessages() as
$error)
1038 CSaleBasket::Update($arItem[
"ID"],
array(
"ORDER_ID" =>
$orderId,
"IGNORE_CALLBACK_FUNC" =>
"Y") + $arItem);
1047 unset($arItem[
"ID"]);
1052 $oldSetParentId = -1;
1055 $oldSetParentId = $arItem[
"SET_PARENT_ID"];
1056 $arItem[
"MANUAL_SET_ITEMS_INSERTION"] =
"Y";
1061 $arItem[
"SET_PARENT_ID"] = $arTmpSetParentId[$arItem[
"SET_PARENT_ID"]];
1064 $arItem[
"ID"] = CSaleBasket::Add(
array(
"ORDER_ID" =>
$orderId,
"IGNORE_CALLBACK_FUNC" =>
"Y") + $arItem);
1070 if (isset($arItem[
"MANUAL_SET_ITEMS_INSERTION"]))
1071 $arTmpSetParentId[$oldSetParentId] = $arItem[
"ID"];
1075 if ($arItem[
"BARCODE_MULTI"] ==
"N")
1077 if (is_array($arItem[
"STORES"]))
1079 foreach ($arItem[
"STORES"] as $arStore)
1081 $arStoreBarcodeFields =
array(
1082 "BASKET_ID" => $arItem[
"ID"],
1084 "STORE_ID" => $arStore[
"STORE_ID"],
1085 "QUANTITY" => $arStore[
"QUANTITY"],
1086 "CREATED_BY" => ($currentUserID > 0 ? $currentUserID :
''),
1087 "MODIFIED_BY" => ($currentUserID > 0 ? $currentUserID :
'')
1096 if (!empty($arItem[
"STORES"]) && is_array($arItem[
"STORES"]))
1098 foreach ($arItem[
"STORES"] as $arStore)
1100 if (isset($arStore[
"BARCODE"]) && isset($arStore[
"BARCODE_FOUND"]))
1102 foreach ($arStore[
"BARCODE"] as $barcodeId => $barcodeValue)
1105 if ($barcodeValue <>
'' && $arStore[
"BARCODE_FOUND"][$barcodeId] ==
"Y")
1107 $arStoreBarcodeFields =
array(
1108 "BASKET_ID" => $arItem[
"ID"],
1109 "BARCODE" => $barcodeValue,
1110 "STORE_ID" => $arStore[
"STORE_ID"],
1112 "CREATED_BY" => ($currentUserID > 0 ? $currentUserID :
''),
1113 "MODIFIED_BY" => ($currentUserID > 0 ? $currentUserID :
'')
1127 self::DoChangeProductQuantity(
1129 $arItem[
"QUANTITY"],
1138 $arItem[
"FUSER_ID"] = $FUSER_ID;
1144 self::DoChangeProductQuantity(
1146 $arItem[
"QUANTITY"],
1155 $arItem[
"FUSER_ID"] = $FUSER_ID;
1157 $arItem[
"ID"] = CSaleBasket::Add(
array(
"ORDER_ID" =>
$orderId,
"IGNORE_CALLBACK_FUNC" =>
"Y") + $arItem);
1164 if ($isOrderConverted !=
'N' && !empty($orderBasketPool))
1167 $r = Sale\Compatible\BasketCompatibility::setBasketFields($orderBasketPool);
1168 if (!$r->isSuccess(
true))
1170 foreach($r->getErrorMessages() as
$error)
1183 $arSetParentsIDs =
array();
1184 foreach ($arOldItems as
$key => $arOldItem)
1186 $arOldItem[
"ID"] =
$key;
1190 $arSetParentsIDs[] = $arOldItem[
"ID"];
1195 if ($isOrderConverted ==
'N')
1198 self::DoChangeProductQuantity(
1200 -$arOldItem[
"QUANTITY"],
1203 $arStoreBarcodeOrderFormData[$arOldItem[
"ID"]],
1209 CSaleBasket::Delete(
$key);
1212 foreach ($arSetParentsIDs as $setParentID)
1213 CSaleBasket::Delete($setParentID);
1225 static $orderList =
array();
1234 $APPLICATION->ThrowException(Loc::getMessage(
'BT_MOD_SALE_BASKET_ERR_ID_ABSENT'),
"ID");
1240 if (!array_key_exists(
'CUSTOM_PRICE',
$arFields))
1251 $APPLICATION->ThrowException(Loc::getMessage(
'BT_MOD_SALE_BASKET_ERR_PRODUCT_ID_ABSENT'),
"PRODUCT_ID");
1255 if (!array_key_exists(
'IGNORE_CALLBACK_FUNC',
$arFields) ||
'Y' !=
$arFields[
'IGNORE_CALLBACK_FUNC'])
1257 if ((array_key_exists(
"CALLBACK_FUNC",
$arFields) && !empty(
$arFields[
"CALLBACK_FUNC"]))
1258 || (array_key_exists(
"PRODUCT_PROVIDER_CLASS",
$arFields) && !empty(
$arFields[
"PRODUCT_PROVIDER_CLASS"]))
1265 if (array_key_exists(
"IBXSaleProductProvider", class_implements($productProvider)))
1267 $providerParams =
array(
1268 "PRODUCT_ID" =>
$arFields[
"PRODUCT_ID"],
1276 $providerParams[
'NOTES'] =
$arFields[
'NOTES'];
1277 $arPrice = $productProvider::GetProductData($providerParams);
1278 unset($providerParams);
1280 elseif (get_parent_class($productProvider) ==
'Bitrix\Sale\SaleProviderBase')
1304 if (!empty($arPrice) && is_array($arPrice))
1306 if (isset($arPrice[
'BASE_PRICE']))
1309 if (isset($arPrice[
'DISCOUNT_PRICE']))
1312 if (isset($arPrice[
'PRICE']))
1316 $arFields[
"CURRENCY"] = $arPrice[
"CURRENCY"];
1318 $arFields[
"PRODUCT_PRICE_ID"] = $arPrice[
"PRODUCT_PRICE_ID"];
1322 if (isset($arPrice[
'DISCOUNT_LIST']))
1323 $arFields[
'DISCOUNT_LIST'] = $arPrice[
'DISCOUNT_LIST'];
1354 $APPLICATION->ThrowException(Loc::getMessage(
'BT_MOD_SALE_BASKET_ERR_CURRENCY_ABSENT'),
"CURRENCY");
1360 $APPLICATION->ThrowException(Loc::getMessage(
'BT_MOD_SALE_BASKET_ERR_SITE_ID_ABSENT'),
"LID");
1366 if (!isset($orderList[
$arFields[
"ORDER_ID"]]))
1375 if ($arOrder = $rsOrders->Fetch())
1377 $orderList[
$arFields[
"ORDER_ID"]] =
true;
1380 if (!isset($orderList[
$arFields[
"ORDER_ID"]]))
1382 $APPLICATION->ThrowException(str_replace(
"#ID#",
$arFields[
"ORDER_ID"], Loc::getMessage(
"SKGB_NO_ORDER")),
"ORDER_ID");
1392 $APPLICATION->ThrowException(str_replace(
"#ID#",
$arFields[
"CURRENCY"], Loc::getMessage(
"SKGB_NO_CURRENCY")),
"CURRENCY");
1397 if (empty(self::$currencyList))
1399 $currencyIterator = Currency\CurrencyTable::getList(
array(
1400 'select' =>
array(
'CURRENCY'),
1402 while (
$currency = $currencyIterator->fetch())
1405 if (!isset(self::$currencyList[
$arFields[
'CURRENCY']]))
1407 $APPLICATION->ThrowException(str_replace(
"#ID#",
$arFields[
"CURRENCY"], Loc::getMessage(
"SKGB_NO_CURRENCY")),
"CURRENCY");
1416 if (!$dbSite->Fetch())
1418 $APPLICATION->ThrowException(str_replace(
"#ID#",
$arFields[
"LID"], Loc::getMessage(
"SKGB_NO_SITE")),
"LID");
1425 $existPrice = array_key_exists(
'PRICE',
$arFields);
1426 $existCurrency = array_key_exists(
'CURRENCY',
$arFields) && (string)
$arFields[
'CURRENCY'] !=
'';
1427 if (!$existPrice || !$existCurrency)
1435 if (!$existCurrency)
1444 if ($basket = $basketIterator->Fetch())
1450 if (!$existCurrency)
1451 $arFields[
'CURRENCY'] = $basket[
'CURRENCY'];
1453 unset($basket, $basketIterator,
$select);
1455 unset($existSiteId);
1457 unset($existCurrency, $existPrice);
1462 if (!isset(self::$currencySiteList[
$arFields[
'LID']]))
1464 $siteCurrency = self::$currencySiteList[
$arFields[
'LID']];
1465 if ($siteCurrency !=
$arFields[
'CURRENCY'])
1472 unset($siteCurrency);
1488 $APPLICATION->ThrowException(Loc::getMessage(
'BT_MOD_SALE_BASKET_ERR_NAME_ABSENT'),
"NAME");
1497 $APPLICATION->ThrowException(Loc::getMessage(
'BT_MOD_SALE_BASKET_ERR_FUSER_ID_ABSENT'),
"FUSER_ID");
1501 if (array_key_exists(
"TYPE",
$arFields))
1508 if (array_key_exists(
'~TYPE',
$arFields))
1513 if (array_key_exists(
'CATALOG_XML_ID',
$arFields))
1520 if (array_key_exists(
'~CATALOG_XML_ID',
$arFields))
1527 if (array_key_exists(
'PROPS',
$arFields))
1535 $clearPropList =
array();
1536 foreach (
$arFields[
'PROPS'] as $basketProperty)
1538 if (empty($basketProperty) || !is_array($basketProperty) || !isset($basketProperty[
'NAME']))
1540 $basketProperty[
'NAME'] = (string)$basketProperty[
'NAME'];
1541 if ($basketProperty[
'NAME'] ==
'')
1543 $propCode = (isset($basketProperty[
'CODE']) ? (string)$basketProperty[
'CODE'] :
'');
1544 $propValue = (isset($basketProperty[
'VALUE']) ? (string)$basketProperty[
'VALUE'] :
'');
1546 'NAME' => $basketProperty[
'NAME'],
1547 'SORT' => (isset($basketProperty[
'SORT']) ? (
int)$basketProperty[
'SORT'] : 100)
1549 if ($propCode !=
'')
1550 $clearProp[
'CODE'] = $propCode;
1551 if ($propValue !=
'')
1552 $clearProp[
'VALUE'] = $propValue;
1553 $clearPropList[] = $clearProp;
1554 unset($clearProp, $propValue, $propCode);
1556 unset($basketProperty);
1557 if (!empty($clearPropList))
1561 unset($clearPropList);
1575 if (!CSaleBasket::CheckFields(
"UPDATE",
$arFields,
$ID))
1578 foreach(
GetModuleEvents(
"sale",
"OnBeforeBasketUpdateAfterCheck",
true) as $arEvent)
1582 $arOldFields =
false;
1585 $strUpdate =
$DB->PrepareUpdate(
"b_sale_basket",
$arFields);
1586 if (!empty($strUpdate))
1597 $arOldFields = $oldOrderIterator->Fetch();
1600 $strSql =
"update b_sale_basket set ".$strUpdate.
", DATE_UPDATE = ".
$DB->GetNowFunction().
" where ID = ".
$ID;
1601 $DB->Query($strSql);
1605 $updateHistory =
false;
1610 $sql =
"delete from b_sale_basket_props where BASKET_ID = ".$ID;
1612 $bProductXml =
false;
1613 $bCatalogXml =
false;
1616 if (!isset($prop[
'CODE']))
1618 if ($prop[
"CODE"] ==
"PRODUCT.XML_ID")
1619 $bProductXml =
true;
1621 if ($prop[
"CODE"] ==
"CATALOG.XML_ID")
1622 $bCatalogXml =
true;
1624 if ($bProductXml && $bCatalogXml)
1628 $sql .=
" and CODE <> 'PRODUCT.XML_ID'";
1630 $sql .=
" and CODE <> 'CATALOG.XML_ID'";
1632 if (!$bProductXml || !$bCatalogXml)
1634 $sql =
"delete from b_sale_basket_props where BASKET_ID = ".$ID.
" and CODE IS NULL";
1640 if (!isset($prop[
"NAME"]))
1642 $prop[
"NAME"] = (string)$prop[
"NAME"];
1643 if($prop[
"NAME"] !=
'')
1645 $arInsert =
$DB->PrepareInsert(
"b_sale_basket_props", $prop);
1646 $strSql =
"INSERT INTO b_sale_basket_props(BASKET_ID, ".$arInsert[0].
") VALUES(".
$ID.
", ".$arInsert[1].
")";
1647 $DB->Query($strSql);
1665 $isOrderConverted = Option::get(
"main",
"~sale_converted_15",
'Y');
1673 if ($isOrderConverted ==
'N')
1675 foreach(
GetModuleEvents(
"sale",
"OnBeforeBasketUpdate",
true) as $arEvent)
1682 return CSaleBasket::Delete(
$ID);
1687 if ($isOrderConverted !=
'N')
1698 $r = \Bitrix\Sale\Compatible\BasketCompatibility::update(
$ID,
$arFields);
1699 if (!$r->isSuccess())
1701 foreach($r->getErrorMessages() as
$error)
1715 $oldQuantity =
false;
1716 if (!isset($arBasket[
'TYPE']) || !isset($arBasket[
'SET_PARENT_ID']))
1723 array(
'ID',
'TYPE',
'SET_PARENT_ID',
'QUANTITY')
1725 if (!($basket = $basketIterator->Fetch()))
1727 $arBasket[
'TYPE'] = (int)$basket[
'TYPE'];
1728 $arBasket[
'SET_PARENT_ID'] = (int)$basket[
'SET_PARENT_ID'];
1729 $arBasket[
'QUANTITY'] = $basket[
'QUANTITY'];
1730 $oldQuantity = $basket[
'QUANTITY'];
1731 unset($basket, $basketIterator);
1735 if ($oldQuantity ===
false)
1742 array(
'ID',
'QUANTITY')
1744 if (!($basket = $basketIterator->Fetch()))
1746 $arBasket[
'QUANTITY'] = $basket[
'QUANTITY'];
1747 $oldQuantity = $basket[
'QUANTITY'];
1748 unset($basket, $basketIterator);
1750 if ($oldQuantity !=
$arFields[
'QUANTITY'])
1754 array(
"SET_PARENT_ID" =>
$ID,
'TYPE' =>
false),
1757 array(
'ID',
'QUANTITY',
'SET_PARENT_ID',
'TYPE')
1759 while ($arItem = $dbSetItems->Fetch())
1761 $newQuantity = $arItem[
'QUANTITY'] / $arBasket[
'QUANTITY'] *
$arFields[
'QUANTITY'];
1762 CSaleBasket::Update(
1764 array(
'QUANTITY' => $newQuantity,
'SET_PARENT_ID' => (
int)$arItem[
'SET_PARENT_ID'],
'TYPE' => (
int)$arItem[
'TYPE'])
1767 unset($arItem, $dbSetItems);
1779 public static function Init($bVar =
false, $bSkipFUserInit =
false)
1781 $bSkipFUserInit = ($bSkipFUserInit !==
false);
1798 $bSkipFUserInit = ($bSkipFUserInit !==
false);
1812 $strSql =
"SELECT * FROM b_sale_basket WHERE ID = ".$ID;
1824 $callbackFunc = trim((
string)$callbackFunc);
1825 $module = trim((
string)$module);
1826 $productID = intval($productID);
1830 if ($callbackFunc <>
'')
1832 if ($module <>
'' && $module !=
"main")
1833 CModule::IncludeModule($module);
1835 $arArgs =
array($productID);
1836 $numArgs = func_num_args();
1838 for (
$i = 3;
$i < $numArgs;
$i++)
1839 $arArgs[] = func_get_arg(
$i);
1841 $result = call_user_func_array($callbackFunc, $arArgs);
1864 public static function ReReadPrice($callbackFunc =
"", $module =
"", $productID = 0, $quantity = 0, $renewal =
"N", $productProvider =
"")
1868 return $productProvider::GetProductData(
array(
1869 "PRODUCT_ID" => $productID,
1870 "QUANTITY" => $quantity,
1871 "RENEWAL" => $renewal
1878 public static function OnOrderProduct($callbackFunc =
"", $module =
"", $productID = 0, $quantity = 0, $productProvider =
"")
1882 $productProvider::GetProductData(
array(
1883 "PRODUCT_ID" => $productID,
1884 "QUANTITY" => $quantity
1893 public static function UpdatePrice(
$ID, $callbackFunc =
'', $module =
'', $productID = 0, $quantity = 0, $renewal =
'N', $productProvider =
'', $notes =
'')
1898 $callbackFunc = trim((
string)$callbackFunc);
1899 $productID = (int)$productID;
1900 $module = trim((
string)$module);
1901 $quantity = (float)$quantity;
1902 $renewal = ((string)$renewal ==
'Y' ?
'Y' :
'N');
1903 $productProvider = trim((
string)$productProvider);
1904 $notes = trim((
string)$notes);
1905 $getQuantity =
false;
1908 if ($callbackFunc ==
'' && $productProvider ==
'')
1910 $getQuantity =
true;
1911 $select[
'CALLBACK_FUNC'] =
true;
1912 $select[
'PRODUCT_PROVIDER_CLASS'] =
true;
1914 if ($productID <= 0)
1916 $getQuantity =
true;
1926 unset($getQuantity);
1937 $basket = $basketIterator->Fetch();
1940 if (isset(
$select[
'CALLBACK_FUNC']))
1941 $callbackFunc = trim((
string)$basket[
'CALLBACK_FUNC']);
1942 if (isset(
$select[
'PRODUCT_PROVIDER_CLASS']))
1943 $productProvider = trim((
string)$basket[
'PRODUCT_PROVIDER_CLASS']);
1945 $module = trim((
string)$basket[
'MODULE']);
1946 if (isset(
$select[
'PRODUCT_ID']))
1947 $productID = (int)$basket[
'PRODUCT_ID'];
1948 if (isset(
$select[
'QUANTITY']))
1949 $quantity = (float)$basket[
'QUANTITY'];
1951 $notes = $basket[
'NOTES'];
1952 unset($basket, $basketIterator);
1956 "MODULE" => $module,
1957 "PRODUCT_PROVIDER_CLASS" => $productProvider,
1961 $arFields = $providerName::GetProductData([
1962 "PRODUCT_ID" => $productID,
1963 "QUANTITY" => $quantity,
1964 "RENEWAL" => $renewal,
1999 public static function OrderBasket(
$orderID, $fuserID = 0, $strLang =
SITE_ID, $arDiscounts = False)
2005 $fuserID = (int)$fuserID;
2011 $isOrderConverted = Option::get(
"main",
"~sale_converted_15",
'Y');
2015 if (empty($arOrder))
2022 array(
'ID',
'USER_ID',
'RECURRING_ID',
'LID',
'RESERVED')
2024 if (!($arOrder = $rsOrders->Fetch()))
2026 $arOrder[
'RECURRING_ID'] = (int)$arOrder[
'RECURRING_ID'];
2028 $boolRecurring = $arOrder[
'RECURRING_ID'] > 0;
2032 array(
"PRICE" =>
"DESC"),
2033 array(
"FUSER_ID" => $fuserID,
"LID" => $strLang,
"ORDER_ID" => 0),
2037 'ID',
'ORDER_ID',
'PRODUCT_ID',
'MODULE',
2038 'CAN_BUY',
'DELAY',
'ORDER_CALLBACK_FUNC',
'PRODUCT_PROVIDER_CLASS',
2039 'QUANTITY',
'CUSTOM_PRICE'
2042 while ($arBasket = $dbBasketList->Fetch())
2045 if ($arBasket[
"DELAY"] ==
"N" && $arBasket[
"CAN_BUY"] ==
"Y")
2047 if (!empty($arBasket[
"ORDER_CALLBACK_FUNC"]) || !empty($arBasket[
"PRODUCT_PROVIDER_CLASS"]))
2053 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2054 "QUANTITY" => $arBasket[
"QUANTITY"],
2055 'BASKET_ID' => $arBasket[
'ID']
2059 $arQuery[
'RENEWAL'] =
'Y';
2060 $arQuery[
'USER_ID'] = $arOrder[
'USER_ID'];
2061 $arQuery[
'SITE_ID'] = $strLang;
2063 $arFields = $productProvider::OrderProduct($arQuery);
2070 $arBasket[
"ORDER_CALLBACK_FUNC"],
2071 $arBasket[
"MODULE"],
2072 $arBasket[
"PRODUCT_ID"],
2073 $arBasket[
"QUANTITY"],
2075 $arOrder[
'USER_ID'],
2082 $arBasket[
"ORDER_CALLBACK_FUNC"],
2083 $arBasket[
"MODULE"],
2084 $arBasket[
"PRODUCT_ID"],
2085 $arBasket[
"QUANTITY"]
2094 $arBasket[
'CUSTOM_PRICE'] = (string)$arBasket[
'CUSTOM_PRICE'];
2095 if ($arBasket[
'CUSTOM_PRICE'] ==
'Y')
2097 if (array_key_exists(
'PRICE',
$arFields))
2099 if (array_key_exists(
'DISCOUNT_PRICE',
$arFields))
2101 if (array_key_exists(
'CURRENCY',
$arFields))
2103 if (array_key_exists(
'DISCOUNT_VALUE',
$arFields))
2105 if (array_key_exists(
'DISCOUNT_NAME',
$arFields))
2107 if (array_key_exists(
'DISCOUNT_COUPON',
$arFields))
2109 if (array_key_exists(
'DISCOUNT_LIST',
$arFields))
2111 if (array_key_exists(
'DISCOUNT',
$arFields))
2120 $removeCoupon = DiscountCouponsManager::deleteApplyByProduct(
array(
2121 'MODULE' => $arBasket[
'MODULE'],
2122 'PRODUCT_ID' => $arBasket[
'PRODUCT_ID'],
2123 'BASKET_ID' => $arBasket[
'ID']
2134 if ($isOrderConverted !=
'N')
2138 \Bitrix\Sale\Compatible\DiscountCompatibility::init();
2140 \Bitrix\Sale\Compatible\DiscountCompatibility::setRepeatSave(
true);
2142 CSaleBasket::Update($arBasket[
"ID"],
$arFields);
2152 if ($isOrderConverted !=
'N' && $found)
2154 $registry = Sale\Registry::getInstance(Sale\Registry::REGISTRY_TYPE_ORDER);
2157 $orderClass = $registry->getOrderClassName();
2162 \Bitrix\Sale\Compatible\DiscountCompatibility::setRepeatSave(
false);
2163 $discounts =
$order->getDiscount();
2170 if ($arOrder[
'RESERVED'] !=
"Y" && COption::GetOptionString(
"sale",
"product_reserve_condition") ==
"O")
2172 if (!CSaleOrder::ReserveOrder(
$orderID,
"Y"))
2180 CSaleBasket::OrderDelivery(
$orderID, $bPaid, $recurringID);
2183 public static function OrderDelivery(
$orderID, $bPaid, $recurringID = 0)
2191 $bPaid = ($bPaid ? True : False);
2193 $recurringID = intval($recurringID);
2195 $arOrder = CSaleOrder::GetByID(
$orderID);
2199 array(
"NAME" =>
"ASC"),
2203 while ($arBasket = $dbBasketList->Fetch())
2205 if ($arBasket[
"PAY_CALLBACK_FUNC"] <>
'' || $arBasket[
"PRODUCT_PROVIDER_CLASS"] <>
'')
2213 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2214 "USER_ID" => $arOrder[
"USER_ID"],
2217 'BASKET_ID' => $arBasket[
'ID']
2223 $arBasket[
"PAY_CALLBACK_FUNC"],
2224 $arBasket[
"MODULE"],
2225 $arBasket[
"PRODUCT_ID"],
2226 $arOrder[
"USER_ID"],
2229 $arBasket[
"QUANTITY"]
2239 if ($recurringID > 0)
2244 elseif ($recurringID > 0)
2254 $productProvider::DeliverProduct(
array(
2255 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2256 "USER_ID" => $arOrder[
"USER_ID"],
2259 'BASKET_ID' => $arBasket[
'ID']
2265 $arBasket[
"PAY_CALLBACK_FUNC"],
2266 $arBasket[
"MODULE"],
2267 $arBasket[
"PRODUCT_ID"],
2268 $arOrder[
"USER_ID"],
2271 $arBasket[
"QUANTITY"]
2278 "USER_ID" => $arOrder[
"USER_ID"],
2279 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2280 "MODULE" => $arBasket[
"MODULE"]
2283 while ($arRecur = $dbRecur->Fetch())
2301 $bCancel = (bool)$bCancel;
2303 $isOrderConverted =
Option::get(
"main",
"~sale_converted_15",
'Y');
2305 if ($isOrderConverted !=
'N')
2307 \Bitrix\Sale\Compatible\OrderCompatibility::cancel(
$orderID, $bCancel?
'Y':
'N');
2311 $arOrder = CSaleOrder::GetByID(
$orderID);
2315 array(
"NAME" =>
"ASC"),
2318 while ($arBasket = $dbBasketList->Fetch())
2320 if ($arBasket[
"CANCEL_CALLBACK_FUNC"] <>
'' && $arBasket[
"PRODUCT_PROVIDER_CLASS"] ==
'')
2323 $arBasket[
"CANCEL_CALLBACK_FUNC"],
2324 $arBasket[
"MODULE"],
2325 $arBasket[
"PRODUCT_ID"],
2326 $arBasket[
"QUANTITY"],
2342 public static function OrderReservation(
$orderID, $bUndoReservation =
false)
2348 if ($bUndoReservation)
2359 $arSetData =
array();
2361 $arOrder = CSaleOrder::GetByID(
$orderID);
2365 if (is_object($obStackExp))
2374 while ($arBasket = $dbBasketList->Fetch())
2376 if ($bUndoReservation && $arBasket[
"RESERVED"] ==
"N" && COption::GetOptionString(
"catalog",
"enable_reservation") !=
"N")
2383 $arSetData[$arBasket[
"PRODUCT_ID"]] = $arBasket[
"SET_PARENT_ID"];
2394 "Call ::ReserveProduct",
2396 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2397 "QUANTITY_ADD" => $arBasket[
"QUANTITY"],
2398 "UNDO_RESERVATION" => ($bUndoReservation) ?
"Y" :
"N"
2404 if ($arOrder[
"DEDUCTED"] ==
"Y")
2406 $res =
array(
"RESULT" =>
true,
"QUANTITY_RESERVED" => 0);
2413 $res = $productProvider::ReserveProduct(
array(
2414 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2415 "QUANTITY_ADD" => $arBasket[
"QUANTITY"],
2416 "UNDO_RESERVATION" => ($bUndoReservation) ?
"Y" :
"N",
2422 $arResult[$arBasket[
"PRODUCT_ID"]] =
$res[
"QUANTITY_RESERVED"];
2424 $arUpdateFields =
array(
"RESERVED" => ($bUndoReservation) ?
"N" :
"Y");
2426 if (!$bUndoReservation && isset(
$res[
"QUANTITY_NOT_RESERVED"]))
2427 $arUpdateFields[
"RESERVE_QUANTITY"] =
$res[
"QUANTITY_NOT_RESERVED"];
2430 CSaleHelper::WriteToLog(
"Product #".$arBasket[
"PRODUCT_ID"].
" reserved successfully",
array(
"arUpdateFields" => $arUpdateFields),
"OR4");
2432 if (!isset(
$res[
"QUANTITY_RESERVED"]) || (isset(
$res[
"QUANTITY_RESERVED"]) &&
$res[
"QUANTITY_RESERVED"] != 0))
2433 CSaleBasket::Update($arBasket[
"ID"], $arUpdateFields);
2440 CSaleBasket::Update($arBasket[
"ID"],
array(
"RESERVED" =>
"N"));
2448 "Call ::ReserveProduct - Exception",
2450 "ID" => $arBasket[
"PRODUCT_ID"],
2451 "MESSAGE" => $ex->GetString(),
2452 "CODE" => $ex->GetID(),
2458 $arResult[
"ERROR"][$arBasket[
"PRODUCT_ID"]][
"ID"] = $arBasket[
"PRODUCT_ID"];
2459 $arResult[
"ERROR"][$arBasket[
"PRODUCT_ID"]][
"MESSAGE"] = $ex->GetString();
2460 $arResult[
"ERROR"][$arBasket[
"PRODUCT_ID"]][
"CODE"] = $ex->GetID();
2464 if (is_object($obStackExp))
2486 public static function ReserveBasketProduct($basketID, $deltaQuantity, $isOrderDeducted =
false)
2493 "ReserveBasketProduct: reserving product #".$basketID,
2495 "basketId" => $basketID,
2496 "deltaQuantity" => $deltaQuantity
2504 $basketID = (int)$basketID;
2511 $deltaQuantity = (float)$deltaQuantity;
2512 if ($deltaQuantity < 0)
2514 $deltaQuantity = abs($deltaQuantity);
2515 $bUndoReservation =
true;
2519 $bUndoReservation =
false;
2532 "Call ::ReserveProduct",
2534 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2535 "QUANTITY_ADD" => $deltaQuantity,
2536 "UNDO_RESERVATION" => ($bUndoReservation) ?
"Y" :
"N",
2537 "ORDER_DEDUCTED" => ($isOrderDeducted) ?
"Y" :
"N"
2543 $res = $productProvider::ReserveProduct(
array(
2544 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2545 "QUANTITY_ADD" => $deltaQuantity,
2546 "UNDO_RESERVATION" => ($bUndoReservation) ?
"Y" :
"N",
2547 "ORDER_DEDUCTED" => ($isOrderDeducted) ?
"Y" :
"N"
2550 $updateResult =
true;
2559 if ($bUndoReservation)
2561 $updateResult = CSaleBasket::Update($arBasket[
"ID"],
array(
"RESERVED" =>
"N"));
2563 elseif (!isset(
$res[
"QUANTITY_RESERVED"]) || (isset(
$res[
"QUANTITY_RESERVED"]) &&
$res[
"QUANTITY_RESERVED"] != 0))
2565 $updateResult = CSaleBasket::Update($arBasket[
"ID"],
array(
"RESERVED" =>
"Y"));
2570 $arResult[
"ERROR"][
"PRODUCT_ID"] = $arBasket[
"PRODUCT_ID"];
2571 $updateResult =
false;
2576 if (isset(
$res[
"QUANTITY_NOT_RESERVED"]))
2578 CSaleBasket::Update($arBasket[
"ID"],
array(
"RESERVE_QUANTITY" =>
$res[
"QUANTITY_NOT_RESERVED"]));
2582 if (!$updateResult && $ex =
$APPLICATION->GetException())
2584 $arResult[
"ERROR"][
"MESSAGE"] = $ex->GetString();
2585 $arResult[
"ERROR"][
"CODE"] = $ex->GetID();
2605 public static function DeductBasketProduct($basketID, $deltaQuantity, $arStoreBarcodeData =
array())
2611 "basketId" => $basketID,
2612 "deltaQuantity" => $deltaQuantity,
2613 "storeBarcodeData" => $arStoreBarcodeData
2622 $basketID = (int)$basketID;
2629 $deltaQuantity = (float)$deltaQuantity;
2630 if ($deltaQuantity < 0)
2632 $deltaQuantity = abs($deltaQuantity);
2633 $bUndoDeduction =
true;
2637 $bUndoDeduction =
false;
2649 "Call ::DeductProduct",
2651 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2652 "QUANTITY" => (empty($arStoreBarcodeData)) ? $deltaQuantity : 0,
2653 "UNDO_DEDUCTION" => ($bUndoDeduction) ?
"Y" :
"N",
2655 "PRODUCT_RESERVED" => $arBasket[
"RESERVED"],
2656 "STORE_DATA" => $arStoreBarcodeData
2662 if ($bUndoDeduction)
2666 array(
"BASKET_ID" => $arBasket[
"ID"]),
2669 array(
"ID",
"BASKET_ID",
"BARCODE",
"QUANTITY",
"STORE_ID")
2671 while (
$arRes = $dbStoreBarcode->GetNext())
2672 $arStoreBarcodeData[] =
$arRes;
2675 $res = $productProvider::DeductProduct(
array(
2676 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2677 "QUANTITY" => (empty($arStoreBarcodeData)) ? $deltaQuantity : 0,
2678 "UNDO_DEDUCTION" => ($bUndoDeduction) ?
"Y" :
"N",
2680 "PRODUCT_RESERVED" => $arBasket[
"RESERVED"],
2681 "STORE_DATA" => $arStoreBarcodeData
2693 $arResult[
"ERROR"][
"PRODUCT_ID"] = $arBasket[
"PRODUCT_ID"];
2697 $arResult[
"ERROR"][
"MESSAGE"] = $ex->GetString();
2698 $arResult[
"ERROR"][
"CODE"] = $ex->GetID();
2723 public static function OrderDeduction(
$orderID, $bUndoDeduction =
false, $recurringID = 0, $bAutoDeduction =
true, $arStoreBarcodeOrderFormData =
array())
2726 static $storesCount = NULL;
2727 static $bAutoDeductionAllowed = NULL;
2728 $bRealDeductionAllowed =
true;
2729 $defaultDeductionStore = 0;
2730 $arSavedStoreBarcodeData =
array();
2734 $isOrderConverted = Option::get(
"main",
"~sale_converted_15",
'Y');
2739 "OrderDeduction: started",
2742 "bUndoDeduction" => intval($bUndoDeduction),
2743 "bAutoDeduction" => intval($bAutoDeduction),
2744 "arStoreBarcodeOrderFormData" => $arStoreBarcodeOrderFormData
2758 if ($isOrderConverted !=
'N')
2760 $ship = !$bUndoDeduction;
2762 $r = \Bitrix\Sale\Compatible\OrderCompatibility::shipment(
$orderID, $ship, $arStoreBarcodeOrderFormData);
2763 if (!$r->isSuccess(
true))
2765 foreach($r->getErrorMessages() as
$error)
2788 array(
'ID',
'LID',
'PRODUCT_ID',
'PRODUCT_PROVIDER_CLASS',
'MODULE',
'BARCODE_MULTI',
'QUANTITY',
'RESERVED',
'TYPE',
'SET_PARENT_ID')
2792 while ($arBasket = $dbBasketList->Fetch())
2803 if (is_null($storesCount))
2804 $storesCount = intval($productProvider::GetStoresCount(
array(
"SITE_ID" => $arBasket[
"LID"])));
2809 if (is_null($bAutoDeductionAllowed))
2813 if ($storesCount == 1 || $storesCount == -1 || intval($defaultDeductionStore) > 0)
2814 $bAutoDeductionAllowed =
true;
2816 $bAutoDeductionAllowed =
false;
2822 if ($bAutoDeduction && !$bAutoDeductionAllowed && !$bUndoDeduction)
2827 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_AUTO_DEDUCT_WRONG_STORES_QUANTITY"),
"DDCT_WRONG_STORES_QUANTITY");
2828 $bRealDeductionAllowed =
false;
2830 else if ($bAutoDeduction && $arBasket[
"BARCODE_MULTI"] ==
"Y" && !$bUndoDeduction)
2835 $APPLICATION->ThrowException(Loc::getMessage(
"DDCT_AUTO_DEDUCT_BARCODE_MULTI",
array(
"#PRODUCT_ID#" => $arBasket[
"PRODUCT_ID"])),
"DDCT_CANT_DEDUCT_BARCODE_MULTI");
2836 $bRealDeductionAllowed =
false;
2841 if ($bUndoDeduction && $storesCount > 0)
2845 array(
"BASKET_ID" => $arBasket[
"ID"]),
2848 array(
"ID",
"BASKET_ID",
"BARCODE",
"QUANTITY",
"STORE_ID")
2850 while ($arStoreBarcode = $dbStoreBarcode->Fetch())
2852 $arSavedStoreBarcodeData[$arBasket[
"ID"]][] = $arStoreBarcode;
2858 "OrderDeduction: CSaleStoreBarcode data (stores) to return products to",
2860 "arSavedStoreBarcodeData" => $arSavedStoreBarcodeData
2868 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2870 "PRODUCT_RESERVED" => $arBasket[
"RESERVED"],
2871 "UNDO_DEDUCTION" => ($bUndoDeduction) ?
"Y" :
"N"
2874 if ($bUndoDeduction)
2876 if ($storesCount > 0)
2879 $arFields[
"STORE_DATA"] = $arSavedStoreBarcodeData[$arBasket[
"ID"]];
2883 $arFields[
"QUANTITY"] = $arBasket[
"QUANTITY"];
2889 if ($storesCount == 1)
2893 if ($bAutoDeduction)
2895 $arProductStore = $productProvider::GetProductStores(
array(
2896 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2897 "SITE_ID" => $arBasket[
"LID"],
2898 'BASKET_ID' => $arBasket[
'ID']
2900 if ($arProductStore)
2904 "STORE_ID" => $arProductStore[0][
"STORE_ID"],
2905 "QUANTITY" => $arBasket[
"QUANTITY"],
2906 "AMOUNT" => $arProductStore[0][
"AMOUNT"]
2917 $arFields[
"STORE_DATA"] = $arStoreBarcodeOrderFormData[$arBasket[
"ID"]];
2920 else if (intval($defaultDeductionStore) > 0)
2924 if ($bAutoDeduction)
2926 $arProductStore = $productProvider::GetProductStores(
array(
2927 "PRODUCT_ID" => $arBasket[
"PRODUCT_ID"],
2928 "SITE_ID" => $arBasket[
"LID"],
2929 'BASKET_ID' => $arBasket[
'ID']
2931 if ($arProductStore)
2933 foreach ($arProductStore as $storeData)
2935 if ($storeData[
"STORE_ID"] == intval($defaultDeductionStore))
2939 "STORE_ID" => $storeData[
"STORE_ID"],
2940 "QUANTITY" => $arBasket[
"QUANTITY"],
2941 "AMOUNT" => $storeData[
"AMOUNT"]
2955 $arFields[
"STORE_DATA"] = $arStoreBarcodeOrderFormData[$arBasket[
"ID"]];
2958 else if ($storesCount > 1)
2961 $arFields[
"STORE_DATA"] = $arStoreBarcodeOrderFormData[$arBasket[
"ID"]];
2965 $arFields[
"QUANTITY"] = $arBasket[
"QUANTITY"];
2973 $eventParams =
array(
2975 'RECURRING_ID' => $recurringID,
2976 'AUTO_DEDUCTION' => $bAutoDeduction,
2977 'STORE_DATA' => $arStoreBarcodeOrderFormData
2990 unset($eventParams);
2998 $arItems[] = $arBasket;
3005 $bRealDeductionAllowed =
false;
3014 $arResult[
"ERROR"][
"MESSAGE"] = $ex->GetString();
3015 $arResult[
"ERROR"][
"CODE"] = $ex->GetID();
3018 if (!$bRealDeductionAllowed)
3024 if ($bRealDeductionAllowed)
3026 $bProductsDeductedSuccessfully =
true;
3027 $arDeductedItems =
array();
3028 foreach ($arItems as $arItem)
3033 $arItem[
"FIELDS"][
"EMULATE"] =
"N";
3039 $res = $productProvider::DeductProduct($arItem[
"FIELDS"]);
3043 $arDeductedItems[] = $arItem;
3045 if (!$bUndoDeduction && $storesCount > 0)
3047 if ($bAutoDeduction)
3049 $storeList = array_keys(
$res[
"STORES"]);
3051 $arStoreBarcodeFields =
array(
3052 "BASKET_ID" => $arItem[
"ID"],
3054 "STORE_ID" => $storeId,
3055 "QUANTITY" => $arItem[
"QUANTITY"],
3056 "CREATED_BY" => ((intval(
$GLOBALS[
"USER"]->GetID())>0) ? intval(
$GLOBALS[
"USER"]->GetID()) :
""),
3057 "MODIFIED_BY" => ((intval(
$GLOBALS[
"USER"]->GetID())>0) ? intval(
$GLOBALS[
"USER"]->GetID()) :
""),
3061 CSaleHelper::WriteToLog(
"Call CSaleStoreBarcode::Add (auto deduction = true)",
array(
"arStoreBarcodeFields" => $arStoreBarcodeFields),
"OD11");
3067 if ($bUndoDeduction)
3070 while ($arStoreBarcode = $dbStoreBarcode->GetNext())
3074 $tmpRes = ($bUndoDeduction) ?
"N" :
"Y";
3075 CSaleBasket::Update($arItem[
"ID"],
array(
"DEDUCTED" => $tmpRes));
3078 if ($bUndoDeduction)
3081 CSaleBasket::Update($arItem[
"SET_PARENT_ID"],
array(
"DEDUCTED" =>
"N"));
3086 CSaleBasket::Update($arItem[
"SET_PARENT_ID"],
array(
"DEDUCTED" =>
"Y"));
3094 CSaleBasket::Update($arItem[
"ID"],
array(
"DEDUCTED" =>
"N"));
3095 $bProductsDeductedSuccessfully =
false;
3099 $arResult[
"ERROR"][
"MESSAGE"] = $ex->GetString();
3100 $arResult[
"ERROR"][
"CODE"] = $ex->GetID();
3111 if ($bProductsDeductedSuccessfully)
3118 foreach ($arDeductedItems as $arItem)
3123 if ($storesCount > 0)
3126 "PRODUCT_ID" => $arItem[
"PRODUCT_ID"],
3127 "QUANTITY" => $arItem[
"QUANTITY"],
3128 "UNDO_DEDUCTION" =>
"Y",
3130 "PRODUCT_RESERVED" => $arItem[
"FIELDS"][
"PRODUCT_RESERVED"],
3131 "STORE_DATA" => $arItem[
"FIELDS"][
"STORE_DATA"]
3137 "PRODUCT_ID" => $arItem[
"PRODUCT_ID"],
3138 "QUANTITY" => $arItem[
"QUANTITY"],
3139 "UNDO_DEDUCTION" =>
"Y",
3140 "PRODUCT_RESERVED" => $arItem[
"FIELDS"][
"PRODUCT_RESERVED"],
3148 "Call ::DeductProduct - Revert deduction",
array(
3149 "storesCount" => $storesCount,
3160 CSaleBasket::Update($arItem[
"ID"],
array(
"DEDUCTED" =>
"N"));
3163 CSaleBasket::Update($arItem[
"SET_PARENT_ID"],
array(
"DEDUCTED" =>
"N"));
3182 public static function TransferBasket($FROM_FUSER_ID, $TO_FUSER_ID)
3184 $FROM_FUSER_ID = (int)$FROM_FUSER_ID;
3185 $TO_FUSER_ID = (int)$TO_FUSER_ID;
3187 if ($TO_FUSER_ID > 0 && $FROM_FUSER_ID > 0)
3192 $registry = Sale\Registry::getInstance(Sale\Registry::REGISTRY_TYPE_ORDER);
3195 $basketClass = $registry->getBasketClassName();
3197 $basketToFUser = $basketClass::loadItemsForFUser($TO_FUSER_ID,
SITE_ID);
3198 $basketFromFUser = $basketClass::loadItemsForFUser($FROM_FUSER_ID,
SITE_ID);
3200 if ($basketFromFUser->count() > 0)
3203 foreach ($basketFromFUser as $basketItemFrom)
3206 $basketItemFromProperties =
3207 (
$tmp = $basketItemFrom->getPropertyCollection())
3208 ?
$tmp->getPropertyValues()
3211 $basketItems = $basketToFUser->getExistsItems(
3212 $basketItemFrom->getField(
'MODULE'),
3213 $basketItemFrom->getField(
'PRODUCT_ID'),
3214 $basketItemFromProperties
3217 if (
count($basketItems) === 1)
3219 $basketItem = current($basketItems);
3220 $basketItem->setField(
'QUANTITY', $basketItem->getQuantity() + $basketItemFrom->getQuantity());
3221 $basketItemFrom->delete();
3229 $basketItemFrom->setFieldNoDemand(
'FUSER_ID', $TO_FUSER_ID);
3233 $basketToFUser->save();
3234 $basketFromFUser->save();
3236 Sale\BasketComponentHelper::updateFUserBasket($TO_FUSER_ID,
SITE_ID);
3237 Sale\BasketComponentHelper::updateFUserBasket($FROM_FUSER_ID,
SITE_ID);
3239 Sale\Discount\RuntimeCache\FuserCache::getInstance()->clean();
3249 $fuserID = (int)$fuserID;
3256 $isOrderConverted =
Option::get(
"main",
"~sale_converted_15",
'Y');
3258 if ($isOrderConverted !=
'N')
3266 array(
"ALL_PRICE" =>
"DESC"),
3268 "FUSER_ID" => $fuserID,
3270 "ORDER_ID" =>
"NULL",
3276 "ID",
"MODULE",
"PRODUCT_ID",
"QUANTITY",
3277 "CALLBACK_FUNC",
"PRODUCT_PROVIDER_CLASS",
3278 "CAN_BUY",
"DELAY",
"NOTES",
3279 "TYPE",
"SET_PARENT_ID"
3282 while ($arItem = $dbBasketItems->Fetch())
3284 $basketItems[] = $arItem;
3287 if (!empty($basketItems) && is_array($basketItems))
3289 $basketItems =
getRatio($basketItems);
3291 foreach ($basketItems as $basketItem)
3294 $basketItem[
'CALLBACK_FUNC'] = (string)$basketItem[
'CALLBACK_FUNC'];
3295 $basketItem[
'PRODUCT_PROVIDER_CLASS'] = (string)$basketItem[
'PRODUCT_PROVIDER_CLASS'];
3297 if (strval(trim($basketItem[
'PRODUCT_PROVIDER_CLASS'])) !==
'' || strval(trim($basketItem[
'CALLBACK_FUNC'])) !==
'')
3299 $basketItem[
'MODULE'] = (string)$basketItem[
'MODULE'];
3300 $basketItem[
'PRODUCT_ID'] = (int)$basketItem[
'PRODUCT_ID'];
3301 $basketItem[
'QUANTITY'] = (float)$basketItem[
'QUANTITY'];
3306 "PRODUCT_ID" => $basketItem[
"PRODUCT_ID"],
3307 "QUANTITY" => $basketItem[
"QUANTITY"],
3309 "CHECK_COUPONS" => (
'Y' == $basketItem[
'CAN_BUY'] &&
'N' == $basketItem[
'DELAY'] ?
'Y' :
'N'),
3311 "BASKET_ID" => $basketItem[
"ID"],
3312 "NOTES" => $basketItem[
"NOTES"]
3318 $basketItem[
"CALLBACK_FUNC"],
3319 $basketItem[
"MODULE"],
3320 $basketItem[
"PRODUCT_ID"],
3321 $basketItem[
"QUANTITY"],
3328 if ($isOrderConverted !=
'N' && $basketItem[
'DELAY'] ==
'N')
3336 $fields[
'TYPE'] = (int)$basketItem[
'TYPE'];
3337 $fields[
'SET_PARENT_ID'] = (int)$basketItem[
'SET_PARENT_ID'];
3347 if (array_key_exists(
'MEASURE_RATIO', $basketItem))
3349 $basketItemQuantity = floatval($basketItem[
'QUANTITY']);
3350 $basketItemRatio = floatval($basketItem[
'MEASURE_RATIO']);
3352 $mod =
roundEx(($basketItemQuantity / $basketItemRatio - round($basketItemQuantity / $basketItemRatio)), 6);
3356 $fields[
'QUANTITY'] = floor(ceil($basketItemQuantity) / $basketItemRatio) * $basketItemRatio;
3362 CSaleBasket::Update($basketItem[
'ID'],
$fields);
3385 $basketClass = $registry->getBasketClassName();
3388 $basket = $basketClass::loadItemsForFUser($fuserID,
$siteID);
3389 if ($basket->count() > 0)
3395 $basket->refreshData(
$select);
3396 $warnings =
array();
3400 $r = Sale\BasketComponentHelper::correctQuantityRatio($basket);
3401 if (!$r->isSuccess())
3403 foreach ($r->getErrors() as
$error)
3405 if (
$error instanceof Sale\ResultWarning)
3419 $r = $basket->save();
3420 if (!$r->isSuccess())
3422 $result->addErrors($r->getErrors());
3426 $basketList =
array();
3428 foreach ($basket as $basketItem)
3430 $basketList[$basketItem->getId()] = $basketItem->getFieldValues();
3435 if (!empty($warnings))
3437 $result->addWarnings($warnings);
3452 if (!is_array($newProperties) || !is_array($oldProperties))
3455 if (empty($newProperties) && empty($oldProperties))
3457 $compareNew =
array();
3458 $compareOld =
array();
3460 foreach ($newProperties as &$property)
3462 if (!isset($property[
'VALUE']))
3464 $property[
'VALUE'] = (string)$property[
'VALUE'];
3465 if ($property[
'VALUE'] ==
'')
3469 if (isset($property[
'CODE']))
3471 $property[
'CODE'] = (string)$property[
'CODE'];
3472 if ($property[
'CODE'] !=
'')
3473 $propertyID = $property[
'CODE'];
3475 if ($propertyID ==
'' && isset($property[
'NAME']))
3477 $property[
'NAME'] = (string)$property[
'NAME'];
3478 if ($property[
'NAME'] !=
'')
3479 $propertyID = $property[
'NAME'];
3481 if ($propertyID ==
'')
3483 $compareNew[$propertyID] = $property[
'VALUE'];
3487 foreach ($oldProperties as &$property)
3489 if (!isset($property[
'VALUE']))
3491 $property[
'VALUE'] = (string)$property[
'VALUE'];
3492 if ($property[
'VALUE'] ==
'')
3496 if (isset($property[
'CODE']))
3498 $property[
'CODE'] = (string)$property[
'CODE'];
3499 if ($property[
'CODE'] !=
'')
3500 $propertyID = $property[
'CODE'];
3502 if ($propertyID ==
'' && isset($property[
'NAME']))
3504 $property[
'NAME'] = (string)$property[
'NAME'];
3505 if ($property[
'NAME'] !=
'')
3506 $propertyID = $property[
'NAME'];
3508 if ($propertyID ==
'')
3510 $compareOld[$propertyID] = $property[
'VALUE'];
3515 if (
count($compareNew) ==
count($compareOld))
3518 foreach($compareNew as
$key =>
$val)
3520 if (!isset($compareOld[
$key]) || $compareOld[
$key] !=
$val)
3527 unset($compareOld, $compareNew);
3536 public static function getRoundFields()
3538 $isOrderConverted = Option::get(
"main",
"~sale_converted_15",
'Y');
3539 if ($isOrderConverted !=
'N')
3543 $basketItemClassName = $registry->getBasketItemClassName();
3544 return $basketItemClassName::getRoundFields();
3549 'DISCOUNT_PRICE_PERCENT',