Как можно добавить товар в корзину, указав свою цену?

Здравствуйте! У меня возникла проблема с добавлением товара по своей цене. Я пытаюсь сделать это следующим образом: 

```php
AddEventHandler('sale', 'OnSaleBasketItemRefreshData', 'BeforeBasketAddHandler');

function BeforeBasketAddHandler($BasketItem): void
{
    $BasketItem->setField("PRODUCT_PROVIDER_CLASS",  \App\CatalogProductProvider::class);
}
```

И у меня есть класс, который выглядит так:

```php
use Bitrix\Sale\Result;

class CatalogProductProvider extends \Bitrix\Catalog\Product\CatalogProvider
{
    public function getProductData(array $products): \Bitrix\Sale\Result
    {
        $result = parent::getProductData($products);

        $data = $result->getData();

        $key = array_keys($product['PRICE_LIST'])[0];
        $product['PRICE_LIST'][$key]['BASE_PRICE'] = (float)1000;
        $product['PRICE_LIST'][$key]['PRICE'] = (float)1000;
        $product['PRICE_LIST'][$key]['CUSTOM_PRICE'] = 'Y'; // для подстраховки

        $result->setData($data);

        return $result;
    }
}
```

Однако, цена остаётся прежней. Я заметил, что, в отличие от имени, которое я могу изменить, цена почему-то не обновляется. Возможно, после выполнения моего кода, цена пересчитывается заново или извлекается ещё раз. Как мне решить эту проблему?
  • 30 января 2025 г. 21:34
Ответы на вопрос 1
Ваша задача заключается в том, чтобы изменить цену товара в корзине, используя свою цену. Давайте попробуем разобраться с вашим кодом и предложить решение.

Проблема, с которой вы столкнулись, скорее всего связана с тем, что при добавлении товара в корзину происходит повторный пересчет данных, и ваше изменение цены не сохраняется. Вам необходимо выполнить изменения, так чтобы они применялись еще до того, как данные будут пересчитаны.

Вот обновленное решение, которое должно помочь вам в этом:

1. Проверьте, что метод `getProductData` действительно вызывается и получает данные о товаре.
2. Убедитесь, что вы правильно изменяете структуру данных, которая затем используется для добавления товара в корзину.

Попробуйте следующий код:

### Обновленный класс `CatalogProductProvider`

```php
use Bitrix\Sale\Result;
use Bitrix\Catalog\Product\CatalogProvider;

class CatalogProductProvider extends CatalogProvider
{
    public function getProductData(array $products): Result
    {
        $result = parent::getProductData($products);
        $data = $result->getData();

        foreach ($products as $productId => $product) {
            if (isset($data[$productId]['PRICE_LIST'])) {
                $key = array_keys($data[$productId]['PRICE_LIST'])[0];

                // Задаем свою цену
                $data[$productId]['PRICE_LIST'][$key]['BASE_PRICE'] = (float)1000;
                $data[$productId]['PRICE_LIST'][$key]['PRICE'] = (float)1000;
                $data[$productId]['PRICE_LIST'][$key]['CUSTOM_PRICE'] = 'Y'; // Указываем, что цена назначена вручную
            }
        }

        $result->setData($data);
        return $result;
    }
}
```

### Обработка события в `BeforeBasketAddHandler`

Убедитесь, что ваша обработка события работает корректно:

```php
AddEventHandler('sale', 'OnSaleBasketItemRefreshData', 'BeforeBasketAddHandler');

function BeforeBasketAddHandler($BasketItem): void
{
    $BasketItem->setField("PRODUCT_PROVIDER_CLASS", \App\CatalogProductProvider::class);
}
```

### Дополнительные проверки

1. Убедитесь, что у вас нет других обработчиков, которые могут изменять цену товара после вашего кода.
2. Проверьте, что другие части вашего кода (например, методы, связанные с корзиной) не вызывают повторное перерасчет или перезапись цены после выполнения `getProductData`.
3. Проверьте, что ваши изменения действительно будут вызваны при добавлении товара в корзину, и следите за вызовами, чтобы понимать порядок исполнения.

Эти изменения должны помочь вам установить свою цену для товара в корзине. Если проблема сохраняется, попробуйте отладить код, добавляя логи (или используя debugger), чтобы понять, когда и как цены изменяются.
Похожие вопросы