18 private function checkParams(array $fields):
Sale\Result
22 if (empty($fields[
'SITE_ID']))
32 if (empty($fields[
'FUSER_ID']) || (
int)$fields[
'FUSER_ID'] <= 0)
42 if (empty($fields[
'BASKET_ID']) || (
int)$fields[
'BASKET_ID'] <= 0)
52 if (empty($fields[
'PRODUCT_ID']) || (
int)$fields[
'PRODUCT_ID'] <= 0)
56 'productId not found',
65 public function run(array $fields)
69 $changeBasketItemResult = $this->changeBasketItem($fields);
70 if (!$changeBasketItemResult->isSuccess())
72 $this->
addErrors($changeBasketItemResult->getErrors());
76 $changeBasketItemData = $changeBasketItemResult->getData();
78 $basketItem = $changeBasketItemData[
'basketItem'];
79 return Sale\Helpers\Controller\Action\Entity\Order::getOrderProductByBasketItem($basketItem);
82 public function changeBasketItem(array $fields):
Sale\Result
86 $checkParamsResult = $this->checkParams($fields);
87 if (!$checkParamsResult->isSuccess())
89 $result->addErrors($checkParamsResult->getErrors());
93 $basketId = $fields[
'BASKET_ID'];
94 $productId = $fields[
'PRODUCT_ID'];
95 $fuserId = $fields[
'FUSER_ID'];
96 $siteId = $fields[
'SITE_ID'];
98 $basket = $this->getBasketByFuserId($fuserId, $siteId);
100 $currentBasketItem = $basket->getItemByBasketCode($basketId);
101 if (!$currentBasketItem)
105 'basket item load error',
112 $currentOfferId = $currentBasketItem->getProductId();
113 $parent = \CCatalogSku::getProductList($currentOfferId, 0);
114 if (empty($parent[$currentOfferId]))
118 'parent product load error',
125 $parent = $parent[$currentOfferId];
127 $offerPropertyCodeList = self::getOfferPropertyCodeList();
129 $newProduct = self::selectOfferById($parent[
'IBLOCK_ID'], $parent[
'ID'], $productId, $offerPropertyCodeList);
134 'product load error',
141 $setFieldsResult = $currentBasketItem->setFields([
142 'PRODUCT_ID' => $newProduct[
'ID'],
143 'NAME' => $newProduct[
'NAME'],
144 'PRODUCT_XML_ID' => $newProduct[
'XML_ID'],
146 if (!$setFieldsResult->isSuccess())
148 foreach ($setFieldsResult->getErrors() as $error)
152 $error->getMessage(),
160 $refreshBasketResult = $basket->refresh(
161 Sale\
Basket\RefreshFactory::createSingle($currentBasketItem->getBasketCode())
163 if (!$refreshBasketResult->isSuccess())
165 foreach ($refreshBasketResult->getErrors() as $error)
169 $error->getMessage(),
177 $basketProperties = self::getBasketProperties($parent[
'IBLOCK_ID'], $newProduct[
'ID'], $offerPropertyCodeList);
178 $basketProperties[
'PRODUCT.XML_ID'] = [
179 'NAME' =>
'Product XML_ID',
180 'CODE' =>
'PRODUCT.XML_ID',
181 'VALUE' => $currentBasketItem->getField(
'PRODUCT_XML_ID'),
184 self::setBasketProperties($currentBasketItem, $basketProperties);
186 $saveBasketResult = $basket->save();
187 if ($saveBasketResult->isSuccess())
191 'basketItem' => $currentBasketItem,
197 foreach ($saveBasketResult->getErrors() as $error)
202 $error->getMessage(),
212 private function getBasketByFuserId($fuserId, $siteId):
Sale\BasketBase
217 $basketClassName = $registry->getBasketClassName();
218 return $basketClassName::loadItemsForFUser($fuserId, $siteId);
221 private static function getOfferPropertyCodeList(): array
225 if (Main\Loader::includeModule(
'iblock') &&
Iblock\Model\PropertyFeature::isEnabledFeatures())
227 $iterator = Catalog\CatalogIblockTable::getList([
228 'select' => [
'IBLOCK_ID'],
229 'filter' => [
'!=PRODUCT_IBLOCK_ID' => 0],
231 while ($row = $iterator->fetch())
233 $list = Catalog\Product\PropertyCatalogFeature::getOfferTreePropertyCodes(
238 if (!empty($list) && is_array($list))
246 $result = array_merge(...$result);
253 private static function selectOfferById(
int $iblockId,
int $parentId,
int $productId, array $offerPropertyCodeList = [])
255 $offers = \CCatalogSku::getOffersList(
260 'ACTIVE_DATE' =>
'Y',
261 'CATALOG_AVAILABLE' =>
'Y',
262 'CHECK_PERMISSIONS' =>
'Y',
263 'MIN_PERMISSION' =>
'R',
265 [
'ID',
'IBLOCK_ID',
'XML_ID',
'NAME'],
266 [
'CODE' => $offerPropertyCodeList]
269 if (empty($offers[$parentId][$productId]))
275 'ID' => $offers[$parentId][$productId][
'ID'],
276 'IBLOCK_ID' => $offers[$parentId][$productId][
'IBLOCK_ID'],
277 'NAME' => $offers[$parentId][$productId][
'NAME'],
278 'XML_ID' => $offers[$parentId][$productId][
'XML_ID'],
279 'PROPERTIES' => $offers[$parentId][$productId][
'PROPERTIES'],
282 if (mb_strpos($result[
'XML_ID'],
'#') ===
false)
284 $parentData = Iblock\ElementTable::getList([
285 'select' => [
'ID',
'XML_ID'],
286 'filter' => [
'ID' => $parentId],
288 if (!empty($parentData))
290 $result[
'XML_ID'] = $parentData[
'XML_ID'].
'#'.$result[
'XML_ID'];
297 private static function getBasketProperties(
int $iblockId,
int $productId, array $offerPropertyCodeList)
299 $newProperties = \CIBlockPriceTools::GetOfferProperties(
302 $offerPropertyCodeList
305 $basketProperties = [];
306 foreach ($newProperties as $row)
309 foreach ($offerPropertyCodeList as $code)
311 if ($code === $row[
'CODE'])
323 $basketProperties[$row[
'CODE']] = [
324 'NAME' => $row[
'NAME'],
325 'CODE' => $row[
'CODE'],
326 'VALUE' => $row[
'VALUE'],
327 'SORT' => $row[
'SORT'],
331 return $basketProperties;
334 private static function setBasketProperties(
Sale\
BasketItem $basketItem, array $basketProperties)
336 $properties = $basketItem->getPropertyCollection();
339 $oldProperties = $properties->getPropertyValues();
340 if (empty($oldProperties))
342 $oldProperties = $basketProperties;
346 $oldProperties = self::updateOffersProperties($oldProperties, $basketProperties);
349 $properties->redefine($oldProperties);
353 private static function updateOffersProperties($oldProps, $newProps): array
355 if (!is_array($oldProps) || !is_array($newProps))
362 if (empty($newProps))
367 if (empty($oldProps))
372 foreach (array_keys($oldProps) as $code)
374 $oldValue = $oldProps[$code];
377 $propId = (isset($oldValue[
'CODE']) ? (string)$oldValue[
'CODE'] :
'').
':'.$oldValue[
'NAME'];
379 foreach ($newProps as $newKey => $newValue)
381 $newId = (isset($newValue[
'CODE']) ? (string)$newValue[
'CODE'] :
'').
':'.$newValue[
'NAME'];
382 if ($newId === $propId)
392 $oldValue[
'VALUE'] = $newProps[$key][
'VALUE'];
393 unset($newProps[$key]);
396 $result[$code] = $oldValue;
400 if (!empty($newProps))
402 foreach (array_keys($newProps) as $code)
404 $result[$code] = $newProps[$code];