Добро пожаловать на сайт <БагБД>, где вы можете задавать вопросы о программировании и разработке на Битрикс и Битрикс24, и получать быстрые и квалифицированные ответы от профессионалов!

Подписка на товар

00 голосов
6
Привет всем. Мне нужно сделать подписку на товар, например, чтобы при изменении цены товара
или количества пользователю отправлялось письмо.

При клике на ссылку возле товара, клиенту выводится форма для ввода E-mail.
После отправки E-mail и id товара сохраняется в БД в созданной вручную таблице.
Далее я пишу обработчик в init.php, тестовый.

AddEventHandler("catalog", "OnBeforePriceUpdate", "myPriceUpdateHandler";);

function myPriceUpdateHandler($ID, &$arFields)
    {
        $handl=fopen("777.txt","w+";);       
        fwrite($handl,$arFields["PRODUCT_ID"].";".$arFields["PRICE"].";".$arFields["CATALOG_GROUP_ID"].";".$arFields["EXTRA_ID"]."ok";);   
        fclose($handl);
   
    }

и пытаюсь посмотреть, что же занесется. Для этого я у любого товара меняю Базовую цену.
Но ничего не происходит и не записывается.
Что я делаю не так? Как мне написать обработчик события изменения цены
и количества на товар, скидки на товар?

Помогите пожалуйста
спросил 22 Июль, 13 от JIauJIa (280 баллов)

6 Ответы

00 голосов
Во-первых, логично отправлять письмо пользователю в случае ИЗМЕНЕНИЯ цены, а не просто ее обновления. Еще логичней отправлять, если цена снизилась, а не просто изменилась. Для этого вам надо иметь значение цены ДО обновления и ПОСЛЕ обновления. А уже потом цену до и после сравнивать, если уменьшилась, то отправляем письмо. То же самое с наличием. Пользователю пофигу, что товара было 30 на складе, а потом стало 40. Логично, что пользователю интересен товар, которого не было в наличии, а потом появился. Поэтому тот же принцип - сначала проверяем остаток ДО, потом ПОСЛЕ и сравниваем, если до было = 0, а после стало >0, тогда отправляем пользователю письмо. Теперь реализация.
Код
AddEventHandler("catalog", "OnBeforePriceUpdate", "CheckPriceBeforeSend"); // Найдем изначальную цену
AddEventHandler("catalog", "OnPriceUpdate", "SendAfterCheck"); // Проверим изменение количества и цены, отправим письма

Существует несколько вариантов, как передать предыдущие параметры до изменения в функцию после изменения цены/количества. Самый простой мне показался через константы. Как вариант, можно передавать через глобальные переменные.
Код
   function CheckPriceBeforeSend (&$id) {
      CModule::IncludeModule("catalog");
      $price = CPrice::GetByID($id);
      define("OLD_PRICE_".$id, $price['PRICE']);
      define("OLD_CURRENCY_".$id, $price['CURRENCY']);
   } 
Ну и после сохранения изменений проверяем выполнение условий, если тру, то отправляем почтовое событие.
Код
   function SendAfterCheck (&$id) {       $new_price = CPrice::GetByID($id);       $all_const = get_defined_constants();       $price = $all_const['OLD_PRICE_'.$id];             if ($price!=$new_price['PRICE']) { // цена изменилась             CModule::IncludeModule("iblock");          $rsEl = CIBlockElement::GetByID($new_price['PRODUCT_ID']);          $item = $rsEl->Fetch();          $rs = CUser::GetList($by="", $order="",             array(                'UF_PRICE_ALERT'=>$item['ID']             ),             array('SELECT'=>array("UF_PRICE_ALERT"))          );          // Перебираем всех найденных пользователей          while ($customer = $rs->GetNext()) {             if (in_array($item['ID'], $customer['UF_PRICE_ALERT']) AND $price>$new_price['PRICE']) {                CEvent::Send("PRODUCT_PRICE_CHANGE", $item['LID'], array(                   'EMAIL' => $customer['EMAIL'],                   'USER_NAME' => $customer['NAME'],                   'ITEM_NAME' => $item['NAME'],                   'ITEM_LINK' => $item['DETAIL_PAGE_URL'],
                  'ITEM_NEW_PRICE' => $new_price['PRICE'],
                  'ITEM_OLD_PRICE' => $price,
               ), "N");             }          }       }    } 
Поясню еще по коду. UF_PRICE_ALERT - это пользовательское поле пользователя, множественное целое число. Для каждого пользователя в нем хранится список ID товаров, на которые он подписался. PRODUCT_PRICE_CHANGE - код почтового события, ну там шаблоны писем, все дела.
ответил 22 Июль, 13 от HolyRage (280 баллов)
00 голосов
Вячеслав, просьба отредактировать свое сообщение, чтобы был перенос строк нормальные, а то всё уехало. И по ходу тут в визуальном редакторе со вставкой кода какие-то проблемы, мой код тоже уехал. Чтобы его прочитать целиком, скопируйте и вставьте хоть в блокнот что ли.
ответил 15 Сен, 13 от HolyRage (280 баллов)
00 голосов
Ок, я сейчас попробую реализовать. Спасибо, Александр. Если что, обращусь тут еще
ответил 13 Дек, 13 от JIauJIa (280 баллов)
00 голосов
Единственный нюанс. Мне нужно сделать такую подписку не для зарегистрированных пользователей, а для всех, кто захотел и оставил E-mail (без регистрации).
ответил 27 Март, 14 от JIauJIa (280 баллов)
00 голосов
Вот, попробовал так:

Код
function SendAfterCheck (&$id) {       
            $new_price = CPrice::GetByID($id);       
            $all_const = get_defined_constants();       
            $price = $all_const['OLD_PRICE_'.$id];             
            global $DB;
            
            if ($price!=$new_price['PRICE']) { 
                    // цена изменилась             
                    CModule::IncludeModule("iblock");          
                    $rsEl = CIBlockElement::GetByID($new_price['PRODUCT_ID']);          
                    $item = $rsEl->Fetch(); X 
                    
                    $query = $DB->Query("SEL ECT E_MAIL FR  product_subscribers WHERE ID_PRODUCT=".$new_price['PRODUCT_ID']);
                    $result = $query->Fetch();
                    mail($result["E_MAIL"], "Уведомление РѕС‚ сайта newpochta.ru", "Сообщение СЃ сайта newpochta.ru. Р’С‹ подписались РЅР° обновления товара.");                    
            }    
}   
 



Не сработало....
ответил 20 Июль, 14 от JIauJIa (280 баллов)
00 голосов
И еще, я что-то не нашел события OnPriceUpdate
ответил 21 Ноя, 14 от JIauJIa (280 баллов)

Похожие вопросы

0 голосов
3 ответов
спросил 18 Фев, 14 от fdsc (180 баллов)
0 голосов
5 ответов
0 голосов
2 ответов
спросил 08 Авг, 13 от Eliga (360 баллов)
0 голосов
1 ответ
спросил 07 Июнь, 13 от VitaliyKR (360 баллов)
0 голосов
9 ответов
спросил 11 Март, 13 от 0ksana (240 баллов)