Перейти к содержимому

Цена на витрине не та - разбор причин

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

С чего начать

Смотрим все цены товара как они лежат в базе:

$rows = \Bitrix\Catalog\Model\Price::getList([
'select' => ['ID', 'CATALOG_GROUP_ID', 'PRICE', 'CURRENCY', 'QUANTITY_FROM', 'QUANTITY_TO'],
'filter' => ['=PRODUCT_ID' => $productId],
])->fetchAll();
print_r($rows);
// две записи с одним типом цены - дубль: какая победит, предсказать нельзя
// пустые границы количества означают цену без ступеней

Список цен отвечает сразу на три вопроса: есть ли цена нужного типа, нет ли дублей и заданы ли границы количества. Дальше разбор идёт от того, что видно в этих строках.

Проверяем, у кого именно лежит цена:

$offers = \CCatalogSKU::getOffersList($productId);
print_r(array_keys($offers[$productId] ?? []));
// у товара с вариантами цену показывает предложение, а не родительская карточка
// пустой список означает обычный товар: тогда цена лежит у самого элемента

Товар с торговыми предложениями цену родителя не показывает. Цена, добавленная карточке, остаётся невидимой, и товар выглядит как позиция без цены при полной таблице цен в базе.

Смотрим права групп на типы цен:

$rows = \Bitrix\Catalog\GroupAccessTable::getList([
'filter' => ['=CATALOG_GROUP_ID' => $priceTypeId],
])->fetchAll();
print_r($rows);
// в корзине берётся наименьшая доступная цена, даже если тип скрыт в каталоге
// ACCESS: 'Y' - группе тип цены доступен, записи нет - недоступен

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

Проверяем расчёт цены для нужного количества:

$optimal = \CCatalogProduct::GetOptimalPrice($productId, 3);
if (!$optimal) {
// при ступенчатых ценах для этого количества подходящей цены нет
$optimal = \CCatalogProduct::GetNearestQuantityPrice($productId, 3);
}
print_r($optimal['RESULT_PRICE'] ?? null); // здесь цена уже со скидками

Расчёт учитывает права покупателя, скидки и границы количества сразу. Свой подсчёт по строке из таблицы цен даёт другое число, и расхождение обнаруживается уже на первом заказе.

Причины

  1. Цена добавлена родителю, а не торговому предложению примерно 30% случаев

    ПризнакУ товара с вариантами цена не показывается, при выборе варианта остаётся пустой.

    ПроверкаСмотрим список предложений товара и проверяем, у кого из них есть записи о ценах.

    Что делатьПишем цену предложению: у товара с вариантами цену показывает именно оно.

  2. Группе доступен другой тип цены примерно 25% случаев

    ПризнакВ каталоге одна цена, в корзине и на оформлении заказа заметно другая.

    ПроверкаСмотрим права групп на типы цен и сравниваем их с типом, который выводит витрина.

    Что делатьПриводим права в порядок: покупателю достаётся наименьшая доступная ему цена.

  3. Дубль цены на один тип примерно 20% случаев

    ПризнакЦена меняется скачками между обменами или после запуска своего скрипта.

    ПроверкаИщем в списке цен две записи с одинаковым типом у одного товара.

    Что делатьУдаляем лишнюю запись, а в коде записи цен сначала ищем существующую, потом обновляем.

  4. Цена задана ступенями по количеству примерно 15% случаев

    ПризнакЦена есть, но для конкретного количества расчёт возвращает пусто.

    ПроверкаСмотрим границы количества у записей цены и сверяем их с запрошенным количеством.

    Что делатьЗакрываем разрывы в ступенях или подбираем ближайшую подходящую по количеству цену.

  5. Цену изменила скидка или правило корзины примерно 10% случаев

    ПризнакЦена в карточке и в корзине различается ровно на величину скидки.

    ПроверкаСмотрим действующие скидки и правила работы с корзиной для этой группы покупателей.

    Что делатьПравим условия скидки: считать цену своими руками мимо скидок - худший из вариантов.

Частые вопросы

Почему у товара вообще нет цены?

Либо элемент не заведён как товар в торговом каталоге, либо цена добавлена не тому объекту. Проверяют обе версии по списку цен и списку предложений.

Откуда берётся цена в корзине?

Из доступных покупателю типов цен: берётся наименьшая. Тип цены, скрытый на витрине, но разрешённый группе, в корзину попадает.

Почему после обмена цена скачет?

Обычно из-за дублей: у товара две записи одного типа цены, и обмен обновляет то одну, то другую. Дубли ищут выборкой по товару и типу цены.

Как правильно менять цену из кода?

Сначала искать существующую запись по товару и типу цены, потом обновлять её. Добавление без поиска создаёт вторую запись и превращается в скачущую цену.

Считать скидку своими руками можно?

Нежелательно: свой расчёт пропускает права покупателя, купоны, ступенчатые цены и настройки округления. Расхождение с корзиной обнаружится на первом же заказе.

Смежное

Первоисточник