Пример #1
0
 /**
  * Updates information about basket products after changes have been made in the order_new form
  * (saves newly added basket items, changes their quantity, saves barcodes etc)
  *
  * @param int $orderId - order ID
  * @param string $siteId - site ID
  * @param bool $userId - user ID
  * @param array $arShoppingCart - array of basket items
  * @param array $arErrors
  * @param array $arCoupons
  * @param array $arStoreBarcodeOrderFormData - array of stores and barcodes for deduction (from order_new form)
  * @param bool $bSaveBarcodes - flat to save given barcode data. Used if the order is already deducted or at least has saved other barcodes
  * @return bool
  */
 public static function DoSaveOrderBasket($orderId, $siteId, $userId, &$arShoppingCart, &$arErrors, $arCoupons = array(), $arStoreBarcodeOrderFormData = array(), $bSaveBarcodes = false)
 {
     global $DB, $USER, $APPLICATION;
     $currentUserID = 0;
     if (isset($USER) && $USER instanceof CUser) {
         $currentUserID = (int) $USER->GetID();
     }
     if (defined("SALE_DEBUG") && SALE_DEBUG) {
         CSaleHelper::WriteToLog("DoSaveOrderBasket - Started", array("orderId" => $orderId, "siteId" => $siteId, "userId" => $userId, "arShoppingCart" => $arShoppingCart, "bSaveBarcodes" => $bSaveBarcodes, "arStoreBarcodeOrderFormData" => $arStoreBarcodeOrderFormData), "DSOB1");
     }
     $isOrderConverted = \Bitrix\Main\Config\Option::get("main", "~sale_converted_15", 'N');
     $orderId = (int) $orderId;
     if ($orderId <= 0) {
         return false;
     }
     if (empty($arShoppingCart) || !is_array($arShoppingCart)) {
         $arErrors[] = array("CODE" => "PARAM", "TEXT" => Loc::getMessage('SKGB_SHOPPING_CART_EMPTY'));
         return false;
     }
     $isOrderReserved = false;
     $isOrderDeducted = false;
     $dbOrderTmp = CSaleOrder::GetList(array(), array("ID" => $orderId), false, false, array("ID", "RESERVED", "DEDUCTED"));
     if ($arOrder = $dbOrderTmp->Fetch()) {
         if ($arOrder["RESERVED"] == "Y") {
             $isOrderReserved = true;
         }
         if ($arOrder["DEDUCTED"] == "Y") {
             $isOrderDeducted = true;
         }
     }
     $arOldItems = array();
     $dbItems = CSaleBasket::GetList(array(), array("ORDER_ID" => $orderId), false, false, array("ID", "QUANTITY", "CANCEL_CALLBACK_FUNC", "MODULE", "PRODUCT_ID", "PRODUCT_PROVIDER_CLASS", "RESERVED", "RESERVE_QUANTITY", "TYPE", "SET_PARENT_ID"));
     while ($arItem = $dbItems->Fetch()) {
         $arOldItems[$arItem["ID"]] = array("QUANTITY" => $arItem["QUANTITY"], "CANCEL_CALLBACK_FUNC" => $arItem["CANCEL_CALLBACK_FUNC"], "PRODUCT_PROVIDER_CLASS" => $arItem["PRODUCT_PROVIDER_CLASS"], "MODULE" => $arItem["MODULE"], "PRODUCT_ID" => $arItem["PRODUCT_ID"], "RESERVED" => $arItem["RESERVED"], "RESERVE_QUANTITY" => $arItem["RESERVE_QUANTITY"], "TYPE" => $arItem["TYPE"], "SET_PARENT_ID" => $arItem["SET_PARENT_ID"]);
     }
     if (!empty($arCoupons)) {
         if (!is_array($arCoupons)) {
             $arCoupons = array($arCoupons);
         }
         foreach (GetModuleEvents("sale", "OnSetCouponList", true) as $arEvent) {
             ExecuteModuleEventEx($arEvent, array($userId, $arCoupons, array()));
         }
         foreach ($arCoupons as &$coupon) {
             $couponResult = DiscountCouponsManager::add($coupon);
         }
         unset($coupon, $couponResult);
     }
     $arFUserListTmp = CSaleUser::GetList(array("USER_ID" => $userId));
     if (empty($arFUserListTmp)) {
         $arFields = array("=DATE_INSERT" => $DB->GetNowFunction(), "=DATE_UPDATE" => $DB->GetNowFunction(), "USER_ID" => $userId, "CODE" => md5(time() . randString(10)));
         $FUSER_ID = CSaleUser::_Add($arFields);
     } else {
         $FUSER_ID = $arFUserListTmp["ID"];
     }
     $arTmpSetParentId = array();
     //TODO: is orders converted?
     if ($isOrderConverted != "Y") {
         // re-sort basket data so newly added Set parents come before Set items (used to correctly add Set items to the table)
         usort($arShoppingCart, array("CSaleBasketHelper", "cmpSetData"));
         foreach ($arShoppingCart as &$arItem) {
             $arItemKeys = array_keys($arItem);
             foreach ($arItemKeys as $fieldName) {
                 if (array_key_exists("~" . $fieldName, $arItem)) {
                     if (is_array($arItem["~" . $fieldName]) && !empty($arItem["~" . $fieldName]) || !is_array($arItem["~" . $fieldName]) && strlen($arItem["~" . $fieldName]) > 0) {
                         $arItem[$fieldName] = $arItem["~" . $fieldName];
                     }
                     unset($arItem["~" . $fieldName]);
                 }
             }
             $arItem = array_filter($arItem, array("CSaleBasketHelper", "filterFields"));
         }
         unset($arItem);
         foreach ($arShoppingCart as $arItem) {
             if (strpos($arItem["SET_PARENT_ID"], "tmp") !== false) {
                 $arTmpSetParentId[$arItem["SET_PARENT_ID"]] = $arItem["SET_PARENT_ID"];
             }
         }
     }
     $orderBasketPool = array();
     // iterate over basket data to save it to basket or change quantity (and reserve/deduct accordingly)
     foreach ($arShoppingCart as &$arItem) {
         foreach ($arItem as $tmpKey => $tmpVal) {
             if (is_array($tmpVal) && !in_array($tmpKey, array("STORES", "CATALOG", "PROPS"))) {
                 $arItem[$tmpKey] = serialize($tmpVal);
             }
         }
         if (defined("SALE_DEBUG") && SALE_DEBUG) {
             CSaleHelper::WriteToLog("DoSaveOrderBasket - Item", array("arItem" => $arItem), "DSOB2");
         }
         if (array_key_exists("ID", $arItem) && (int) $arItem["ID"] > 0) {
             $arItem["ID"] = (int) $arItem["ID"];
             if (defined("SALE_DEBUG") && SALE_DEBUG) {
                 CSaleHelper::WriteToLog("DoSaveOrderBasket - Product #" . $arItem["ID"] . " already in the basket", array(), "DSOB3");
             }
             // product already in the basket, change quantity
             if (array_key_exists($arItem["ID"], $arOldItems)) {
                 //TODO: is order converted?
                 if ($isOrderConverted != "Y") {
                     if (!CSaleBasketHelper::isSetParent($arItem)) {
                         $arAdditionalParams = array("ORDER_ID" => $orderId, "USER_ID" => $userId, "SITE_ID" => $siteId);
                         $quantity = $arItem["QUANTITY"] - $arOldItems[$arItem["ID"]]["QUANTITY"];
                         $arAdditionalParams["CHECK_QUANTITY"] = $quantity > 0 ? "Y" : "N";
                         if ($quantity != 0) {
                             self::DoChangeProductQuantity($arItem, $quantity, $isOrderReserved, $isOrderDeducted, $arStoreBarcodeOrderFormData[$arItem["ID"]], $arAdditionalParams);
                         } else {
                             $arAdditionalParams['CHECK_QUANTITY'] = 'N';
                             self::DoChangeProductQuantity($arItem, $quantity, $isOrderReserved, $isOrderDeducted, $arStoreBarcodeOrderFormData[$arItem["ID"]], $arAdditionalParams);
                         }
                     }
                 }
                 unset($arOldItems[$arItem["ID"]]);
             } else {
                 //TODO: is order converted?
                 if ($isOrderConverted != "Y") {
                     if ($arItem["QUANTITY"] != 0 && !CSaleBasketHelper::isSetParent($arItem)) {
                         self::DoChangeProductQuantity($arItem, $arItem["QUANTITY"], $isOrderReserved, $isOrderDeducted, $arStoreBarcodeOrderFormData[$arItem["ID"]], array("ORDER_ID" => $orderId, "USER_ID" => $userId, "SITE_ID" => $siteId));
                     }
                 }
             }
             if (IntVal($arItem["FUSER_ID"]) <= 0) {
                 $arFuserItems = CSaleUser::GetList(array("USER_ID" => intval($userId)));
                 $arItem["FUSER_ID"] = $arFuserItems["ID"];
             }
             if (CSaleBasketHelper::isSetItem($arItem)) {
                 // quantity for set items will be changed when parent item is updated
                 unset($arItem["QUANTITY"]);
             }
             //TODO: is order converted?
             if ($isOrderConverted == "Y") {
                 $fields = array("IGNORE_CALLBACK_FUNC" => "Y") + $arItem;
                 $orderBasketPool[$arItem["ID"]] = array("ORDER_ID" => $orderId);
                 /** @var \Bitrix\Sale\Result $r */
                 $r = \Bitrix\Sale\Compatible\BasketCompatibility::update($arItem["ID"], $fields);
                 if (!$r->isSuccess(true)) {
                     foreach ($r->getErrorMessages() as $error) {
                         $APPLICATION->ThrowException($error);
                     }
                     return false;
                 }
             } else {
                 CSaleBasket::Update($arItem["ID"], array("ORDER_ID" => $orderId, "IGNORE_CALLBACK_FUNC" => "Y") + $arItem);
             }
         } else {
             if (defined("SALE_DEBUG") && SALE_DEBUG) {
                 CSaleHelper::WriteToLog("DoSaveOrderBasket - new product in the basket", array(), "DSOB4");
             }
             unset($arItem["ID"]);
             /** @var $productProvider IBXSaleProductProvider */
             if ($productProvider = CSaleBasket::GetProductProvider($arItem)) {
                 $oldSetParentId = -1;
                 if (CSaleBasketHelper::isSetParent($arItem) && array_key_exists($arItem["SET_PARENT_ID"], $arTmpSetParentId)) {
                     $oldSetParentId = $arItem["SET_PARENT_ID"];
                     $arItem["MANUAL_SET_ITEMS_INSERTION"] = "Y";
                 }
                 if (CSaleBasketHelper::isSetItem($arItem) && array_key_exists($arItem["SET_PARENT_ID"], $arTmpSetParentId)) {
                     $arItem["SET_PARENT_ID"] = $arTmpSetParentId[$arItem["SET_PARENT_ID"]];
                 }
                 $arItem["ID"] = CSaleBasket::Add(array("ORDER_ID" => $orderId, "IGNORE_CALLBACK_FUNC" => "Y") + $arItem);
                 if (isset($arItem["MANUAL_SET_ITEMS_INSERTION"])) {
                     $arTmpSetParentId[$oldSetParentId] = $arItem["ID"];
                 }
                 if ($bSaveBarcodes) {
                     if ($arItem["BARCODE_MULTI"] == "N") {
                         if (is_array($arItem["STORES"])) {
                             foreach ($arItem["STORES"] as $arStore) {
                                 $arStoreBarcodeFields = array("BASKET_ID" => $arItem["ID"], "BARCODE" => "", "STORE_ID" => $arStore["STORE_ID"], "QUANTITY" => $arStore["QUANTITY"], "CREATED_BY" => $currentUserID > 0 ? $currentUserID : '', "MODIFIED_BY" => $currentUserID > 0 ? $currentUserID : '');
                                 CSaleStoreBarcode::Add($arStoreBarcodeFields);
                             }
                         }
                     } else {
                         if (!empty($arItem["STORES"]) && is_array($arItem["STORES"])) {
                             foreach ($arItem["STORES"] as $arStore) {
                                 if (isset($arStore["BARCODE"]) && isset($arStore["BARCODE_FOUND"])) {
                                     foreach ($arStore["BARCODE"] as $barcodeId => $barcodeValue) {
                                         // save only non-empty and valid barcodes TODO - if errors?
                                         if (strlen($barcodeValue) > 0 && $arStore["BARCODE_FOUND"][$barcodeId] == "Y") {
                                             $arStoreBarcodeFields = array("BASKET_ID" => $arItem["ID"], "BARCODE" => $barcodeValue, "STORE_ID" => $arStore["STORE_ID"], "QUANTITY" => 1, "CREATED_BY" => $currentUserID > 0 ? $currentUserID : '', "MODIFIED_BY" => $currentUserID > 0 ? $currentUserID : '');
                                             CSaleStoreBarcode::Add($arStoreBarcodeFields);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
                 if ($arItem["QUANTITY"] != 0 && !CSaleBasketHelper::isSetParent($arItem)) {
                     self::DoChangeProductQuantity($arItem, $arItem["QUANTITY"], $isOrderReserved, $isOrderDeducted, $arItem["STORES"], array("ORDER_ID" => $orderId, "USER_ID" => $userId, "SITE_ID" => $siteId));
                 }
                 if ($FUSER_ID > 0) {
                     $arItem["FUSER_ID"] = $FUSER_ID;
                 }
             } else {
                 if ($arItem["QUANTITY"] != 0 && !CSaleBasketHelper::isSetParent($arItem)) {
                     self::DoChangeProductQuantity($arItem, $arItem["QUANTITY"], $isOrderReserved, $isOrderDeducted, $arItem["STORES"], array("ORDER_ID" => $orderId, "USER_ID" => $userId, "SITE_ID" => $siteId));
                 }
                 if ($FUSER_ID > 0) {
                     $arItem["FUSER_ID"] = $FUSER_ID;
                 }
                 $arItem["ID"] = CSaleBasket::Add(array("ORDER_ID" => $orderId, "IGNORE_CALLBACK_FUNC" => "Y") + $arItem);
                 //$arItem["ID"] = CSaleBasket::Add(array("CALLBACK_FUNC" => false, "ORDER_ID" => $orderId, "IGNORE_CALLBACK_FUNC" => "Y") + $arItem);
             }
         }
     }
     unset($arItem);
     if ($isOrderConverted == "Y" && !empty($orderBasketPool)) {
         /** @var Sale\Result $r */
         $r = Sale\Compatible\BasketCompatibility::setBasketFields($orderBasketPool);
         if (!$r->isSuccess(true)) {
             foreach ($r->getErrorMessages() as $error) {
                 $APPLICATION->ThrowException($error);
             }
             return false;
         }
     }
     if (defined("SALE_DEBUG") && SALE_DEBUG) {
         CSaleHelper::WriteToLog("Items left in the old basket:", array("arOldItems" => $arOldItems), "DSOB5");
     }
     // if some items left in the table which are not present in the updated basket, delete them
     $arSetParentsIDs = array();
     foreach ($arOldItems as $key => $arOldItem) {
         $arOldItem["ID"] = $key;
         if (CSaleBasketHelper::isSetParent($arOldItem)) {
             $arSetParentsIDs[] = $arOldItem["ID"];
             continue;
         } else {
             // the quantity is negative, so the product is canceled
             self::DoChangeProductQuantity($arOldItem, -$arOldItem["QUANTITY"], $isOrderReserved, $isOrderDeducted, $arStoreBarcodeOrderFormData[$arOldItem["ID"]], array("ORDER_ID" => $orderId, "USER_ID" => $userId, "SITE_ID" => $siteId));
         }
         CSaleBasket::Delete($key);
     }
     foreach ($arSetParentsIDs as $setParentID) {
         CSaleBasket::Delete($setParentID);
     }
     foreach (GetModuleEvents("sale", "OnDoBasketOrder", true) as $arEvent) {
         ExecuteModuleEventEx($arEvent, array($orderId));
     }
     return true;
 }