
Генерация купонов в админке
Купон можно сгенерировать в двух местах - на странице редактирования скидки и странице редактирования купона. На странице редактирования купона нельзя было повлиять на формат генерации купона. Теперь функция генерации вынесена в include.php модуля:
string function CatalogGenerateCoupon() |
Новые события
Класс CCatalogDiscount
Добавлены события в методы:
CCatalogDiscount::Add - событие OnDiscountAdd. Событие вызывается ПОСЛЕ добавления скидки. Параметры вызова обработчиков:
function MyDiscountAdd($ID,$arFields) |
CCatalogDiscount::Update - событие OnDiscountUpdate. Событие вызывается ПОСЛЕ изменения скидки. Параметры вызова обработчиков аналогичны OnDiscountAdd:
function MyDiscountUpdate($ID,$arFields) |
CCatalogDiscount:: Delete - событие OnDiscountDelete. Событие вызывается ПОСЛЕ удаления скидки. Параметры вызова обработчиков:
function MyDiscountDelete($ID) |
На первый случай события можно использовать для cброса кеша компонентов catalog.* после изменения скидок.
Класс CCatalogProduct
События добавлены в ответ на пожелания партнеров управлять алгоритмом выбора оптимальной цены для товара в корзине.
Многострадальный метод CCatalogProduct::GetOptimalPrice (поиск оптимальной цены) - событие OnGetOptimalPrice - свой собственный обработчик для поиска оптимальной цены товара. Формат вызова:
function MyGetOptimalPrice($productID, $quantity = 1, $arUserGroups = array(), $renewal = "N", $arPrices = array(), $siteID = false, $arDiscountCoupons = false) |
Внимание! В обновлении ограничение на число обработчиков снято.
array( 'PRICE' => array( 'ID' => ID ценового предложения, 'CATALOG_GROUP_ID' => ID типа цены, 'PRICE' => значение цены, 'CURRENCY' => код валюты, 'ELEMENT_IBLOCK_ID' => ID элемента инфоблока, к которому относится цена, 'VAT_RATE' => ID НДС, 'VAT_INCLUDED' => включен или нет НДС в цену,' ), 'DISCOUNT_PRICE' => цена со скидкой, 'DISCOUNT' => array( 'ID' => ID скидки, 'SITE_ID' => ID сайта, 'ACTIVE' => активность, 'ACTIVE_FROM' => дата начала активности, 'ACTIVE_TO' => дата окончания активности, 'RENEWAL' => скидка на продление, 'NAME' => название скидки, 'SORT' => сортировка, 'MAX_DISCOUNT' => максимальная абсолютная величина скидки, 'VALUE_TYPE' => тип скидки, 'VALUE' => величина скидки, 'CURRENCY' => валюта, 'COUPON' => купон, 'COUPON_ONE_TIME' => одноразовость купона, 'COUPON_ACTIVE' => активность купона, ) ) |
Событие OnGetOptimalPriceResult - изменение результатов CCatalogProduct::GetOptimalPrice. Подключается только если не отработало событие OnGetOptimalPrice. Формат вызова обработчиков:
boolean MyGetOptimalPriceResult(&$arResult) |
Метод CCatalogProduct::GetNearestQuantityPrice - поиск ближайшего к указанному количеству товара. Событий так же два - OnGetNearestQuantityPrice и OnGetNearestQuantityPriceResult. Первое служит для подключения собственного обработчика, второе - для модификации результата метода. Точно так же, если есть обработчик на OnGetNearestQuantityPrice, обработчики OnGetNearestQuantityPriceResult не подключаются. Формат вызова:
int function MyGetNearestQuantityPrice($productID, $quantity = 1, $arUserGroups = array()) boolean function MyGetNearestQuantityPriceResult(&$quantity) |
function MyCountPriceWithDiscount($price, $currency, $arDiscounts) boolean CountPriceWithDiscountResult(&$currentPrice_min) |
Исправления
Исправлена ошибка экспорта в Яндекс.Товары, возникающего при выборе конкретного типа цен для выгрузки.
Исправлены ошибки метода CCatalogProduct::GetList() для Oracle и MS SQL.
Улучшена работа метода CCatalogProduct::GetOptimalPrice().
И все же, для событий ПОСЛЕ надо суффикс After добавлять. Имхо.
А за возможность выбора оптимальной цены огромное спасибо!
К тому же, один обработчик может и вовсе не отработать (проверить условие и ничего не вернуть, к примеру).
Вот реальный пример двух партнерских решений, которые должны быть ОБА, но будут конфликтовать и одно не будет работать:
1. Товар в подарочной упаковке (товар тот же, но стоит дороже, другой тип цены).
2. Товар с сервисом установки (точно так же - другой тип цены).
Плюс есть многосайтовость - на одном может применяться один обработчик, на другом другой.
В общем, ограничение ооооочень сильно как-нибудь кому-нибудь потратит нервы
как раз сейчас проект в разработке, на котором свое ценообразование
если успею дождаться обновления - поробую
по этому чуть подробнее можно?:
AddEventHandler("catalog", "OnGetOptimalPrice", "recalculateBasketPrice"); function recalculateBasketPrice($intProductID, $quantity, $arUserGroups, $renewal, $arPrices, $siteID, $arDiscountCoupons){ $dbBasketItems = CSaleBasket::GetList( array( "NAME" => "ASC", "ID" => "ASC" ), array( "FUSER_ID" => CSaleBasket::GetBasketUserID(), "LID" => SITE_ID, "ORDER_ID" => "NULL", "DELAY" => "N", "CAN_BUY" => "Y" ) ); $arBasketItems = array(); while ($arItems = $dbBasketItems->Fetch()) { if (strlen($arItems["CALLBACK_FUNC"]) > 0) { CSaleBasket::UpdatePrice($arItems["ID"], $arItems["QUANTITY"]); $arItems = CSaleBasket::GetByID($arItems["ID"]); } $arBasketItems[] = $arItems; } // текущая сумма заказа $summ = 0; foreach ($arBasketItems as $arBasketItem) { $summ += $arBasketItem["PRICE"] * $arBasketItem["QUANTITY"]; } /** * 25 - Розница * 23 - Мелкий опт * 24 - Опт */ $priceID = 25; if($summ > 100000) { $priceID = 23; } elseif($summ > 300000) { $priceID = 24; } $dbNewPrice = CPrice::GetListEx(array(), array( 'PRODUCT_ID'=>$intProductID, 'CATALOG_GROUP_ID' => $priceID )); if($newPrice = $dbNewPrice->Fetch()){ return array( 'PRICE' => $newPrice, 'DISCOUNT_PRICE' => false, 'DISCOUNT' => array(), 'DISCOUNT_LIST' => array(), ); } return false; }Правила работы с корзиной - это хорошо, но часто их не достаточно, и нужно сконструировать свое, более сложное правило.
Задача применения своего алгоритма изменения цены в корзине тянется уже несколько лет, и до сих пор нет ни одного рабочего решения, кроме описанного выше Еленой, и решения на хабре: .
Если по Вашему данное решение не оптимальное - напишите, пожалуйста, как правильно.
Задача ведь простая, у товара есть три типа цены (розничная, мелкий опт, оптовая), и нужно в зависимости от произвольных условий (например, суммы товаров в корзине) подставлять тот или иной тип цены.
Т.е. у меня все цены в торговых предложениях и этот метод их не находит или я что-то делаю не так?
'DISCOUNT_PRICE' => false,
'DISCOUNT' => array(),
'DISCOUNT_LIST' => array(),
вот в этой части кода как правильно вывести скидки
в рознице результат
в безнале
розница добавляется в корзину, цена по безналу нет. и еще при переходе из безнала в розницу, товар который хотели добавить в корзину безнала появляется в корзине розницы.