Две цены у товара

Уроки и советы по работе с TSVshop
vladsvd
Сообщения: 1
Зарегистрирован: 25 фев 2013, 18:55

Две цены у товара

Сообщение vladsvd » 25 фев 2013, 19:12

Вечер добрый.
Есть не совсем стандартная задача.
Магазин торгует под заказ. У каждого товара есть цена. Допустим товар стоит 100 рублей - товара нет в наличии. Если человек сразу оплатит товар по безналу ( и не только!!), он получит товар после поступления за 80 рублей (то есть с него надо снять всего 80 а не 100). Если же человек дожидался поступления товара и только тогда добавил в корзину , тогда снимаем с него обычную цену 100 рублей...

1.Тут возникает два вопроса. надо вести учёт, сколько единиц товаров у нас есть.
2. И возможность менеджеру поставить статус оплачено, и должно в зависимости от ситуации взяться либо первая цена либо вторая.
Пример: Допустим человек сделал заказ до поступления товара, и принёс деньги и сделал предоплату физически в магазин тоже до поступления товара. менеджер меняет статус на оплачено , и с человека берётся не 100 а 80 рублей

Возможно ли это?

admin
Администратор
Сообщения: 148
Зарегистрирован: 08 фев 2013, 13:53

Re: Две цены у товара

Сообщение admin » 26 фев 2013, 13:13

Здравствуйте.
Да, задача нестандартная, поэтому потребуется кое-что сделать. Но вполне возможно без использования хаков модуля. Чтобы это реализовать, нужно сделать следующее:

1) Вести учет наличия конкретного товара (вносить кол-во вручную, а также уменьшать количество при покупке).
2) При добавлении товара в корзину смотрим на количество на складе - если 0, то берем вторую цену.
3) При изменении статуса заказа на ОПЛАЧЕНО автоматически проверять условие: если кол-во товара равно 0, то берем вторую цену, если кол-во больше одного (т.е. он в наличии), значит цена стандартная.

Теперь техническая часть.

Создаем нужные TV

1) Создаем TV для количества товаров: назовем его inventory и свяжем с шаблоном карточки товара.
2) Создаем TV для второй цены товара: назовем его price2 и тоже свяжем с шаблоном карточки товара.

В inventory менеджер будет вносить количество товара в наличии. 0 - при его отсутствии.

Создаем плагин

В ядре модуля есть 3 события, которые подходят к нашей задаче: TSVshopOnOrderSuccess, TSVshopOnAddItem и TSVshopOnOrderStatusUpdate (см. описание событий тут: http://tsvshop.tsv.org.ua/dokumentacziya/dlya-razrabotchikov/sistemnyie-sobyitiya.html)

Итак, код плагина:

Код: Выделить всё

/*
Плагин для продажи товара за вторую (меньшую цену), когда он не в наличии и пользователь сделал предроплату
 
Конфигурация:
&tvprice=Название TV для первой цены;string;price &tvprice2=Название TV для второй цены;string;price2 &tvinventory=Название TV учета кол-ва товара;string;tvinventory &templateid=ID шаблона карточки товара;string; &eventstatus=Статус заказа, когда учитывается вторая цена;string;Оплачено

События:
TSVshopOnOrderSuccess, TSVshopOnAddItem, TSVshopOnOrderStatusUpdate
*/


$e = &$modx->Event;

//Подключаем конфиг и ядро корзины
include(MODX_BASE_PATH."assets/snippets/tsvshop/include/config.inc.php");
include(MODX_BASE_PATH."assets/snippets/tsvshop/include/cart.inc.php");
include(MODX_BASE_PATH."assets/snippets/tsvshop/admin/includes/core.inc.php");

// Определяем переменные
$tvprice = (!empty($tvprice)) ? $tvprice : 'price'; // название TV для первой (большей) цены
$tvprice2 = (!empty($tvprice2)) ? $tvprice2 : 'price2'; // название TV для второй (меньшей) цены
$tvinventory = (!empty($tvinventory)) ? $tvinventory : 'inventory';  // название TV для учета количества товара на складе
$templateid = (!empty($templateid)) ? $templateid : '';  // ИД шаблона карточки товара
$eventstatus = (!empty($eventstatus)) ? $eventstatus : 'Оплачено'; // статус, при котором учитывается вторая цена
$timestamp=time();
if (empty($templateid)) return;

$dborders=$modx->getFullTableName('shop_order');
$tvtable = $modx->getFullTableName('site_tmplvar_contentvalues');
$dborders_details=$modx->getFullTableName('shop_order_detail');
$idorder = intval($idorder);
$status = $modx->db->escape($newstatus);

if ($e->name == 'TSVshopOnOrderSuccess') {
    // Здесь мы уменьшаем количество каждого товара на складе.
    // весь заказ находится в массиве $_SESSION['tsvshopfin']
    // $_SESSION['tsvshopfin']['orders'] - массив заказанных товаров (то что нам нужно)
    // $_SESSION['tsvshopfin']['result'] - массив с данными о заказе
   
    // пробегаем по всему массиву и уменьшаем в TV inventory количество товара
    foreach ($_SESSION['tsvshopfin']['orders'] as $order) {
        if (!empty($order['url']) && !empty($tvinventory)) {
          $count = $modx->getTemplateVar($tvinventory,'value',$order['url']);
          $count = (!empty($count['value']) && ($count['value']-$order['qty'])>0) ? ($count['value']-$order['qty']) : 0;
          $modx->db->update(array('value'=>$count),$tvtable,'contentid = '.$order['url'].' AND tmplvarid='.$templateid);
        }
    }
}

if ($e->name == 'TSVshopOnAddItem') {
   // Срабатывает при добавлении товара в корзину
   // Здесь мы будем проверять, есть ли товар в наличии при добавлении в корзину.
   // Если его кол-во равно 0 или пусто, значит применяем вторую цену.
   // Здесь нам доступен массив $_SESSION['tsvshopfin']['orders'] - берем его
   $i=0;
   foreach ($_SESSION['tsvshopfin']['orders'] as $order) {
     $count = $modx->getTemplateVar($tvinventory,'value',$order['url']);
     $price2 = $modx->getTemplateVar($tvprice2,'value',$order['url']);
     if (empty($count['value']) && !empty($price2)) {
       $_SESSION['tsvshopfin']['orders'][$i]['price'] = floatval($price2['value']);
     }
     $i++;
   }
}

if ($e->name == 'TSVshopOnOrderStatusUpdate') {
  // Срабатывает при изменении статуса заказа либо вручную, либо при оплате через сайт.
  // принимает 2 переменные $idorder - ИД заказа, $status - новый статус
  // Вначале все проверки: отлавливаем ТОЛЬКО статус ОПЛАЧЕНО (или другой, указанный в конфигурации) - стальные игнорируем
  if (!empty($idorder) && !empty($status) && $status == $eventstatus) {
   
    $subtotal = 0;
    $total = 0
    // считываем данные заказа из БД
    $res=$modx->db->query("SELECT * FROM ".$dborders_details." WHERE numorder = ".intval($idorder));
      while ($row=$modx->db->getRow($res)) {
        // Если товара пока еще нету в наличии - значит цена №2.
        $count = $modx->getTemplateVar($tvinventory,'value',$row['url']);
        $count = intval($count['value']);
        $price2 = $modx->getTemplateVar($tvprice2,'value',$order['url']);
        $price = $modx->getTemplateVar($tvprice,'value',$order['url']);
        $priceitog = (empty($count)) ? floatval($tvprice2['value']) : floatval($tvprice['value']);
        if ($priceitog!=$row['price']) {
       
          // пересчитываем все цены: цену товара (учитывая его кол-во и скидки)
          $tmpprice = tsv_CalcPrice($priceitog, $row['quantity'], $row['opt']);
          $summa = (tsv_CalcPrice($priceitog, $row['quantity'], $row['opt'])*$row['quantity']);
          $subtotal = $subtotal + $summa;
          // записываем это все дело в БД
          $modx->db->update(array('price'=>$tmpprice),$dborders_details,'numorder = '.$idorder);
        }
      }
      if ($priceitog!=$row['price']) {
        // теперь нужно обновить сумму заказа
        $res=$modx->db->getRow($modx->db->query("SELECT * FROM ".$dborders." WHERE numorder = ".intval($idorder)));
     
        $total = (($subtotal - floatval($row['discountsize'])) + (floatval($row['nalog']) + floatval($row['shipping'])));
        // если изменилась итоговая сумма заказа, обновляем ее тоже в БД
        if (!empty($total)) {
          $modx->db->update(array('total'=>$total),$dborders,'numorder = '.$idorder);
        }
      }
  }
}


События и конфигурация плагина указаны в начале кода.

Сразу хочу сказать, что код не тестировался, поэтому возможны ошибки. Но думаю, принцип решения задачи ясен. Если будут вопросы - пишите.

ekcreate
Сообщения: 76
Зарегистрирован: 04 мар 2016, 12:08

Re: Две цены у товара

Сообщение ekcreate » 04 мар 2016, 12:10

Добрый день, а не подскажите как сделать что бы для не зарегиных и пользователей определенной группы были разные цены? тоже вроде как две цены! если это не сложно
Заранее спасибо!

ekcreate
Сообщения: 76
Зарегистрирован: 04 мар 2016, 12:08

Re: Две цены у товара

Сообщение ekcreate » 04 мар 2016, 12:13

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

admin
Администратор
Сообщения: 148
Зарегистрирован: 08 фев 2013, 13:53

Re: Две цены у товара

Сообщение admin » 04 мар 2016, 16:45

Здравствуйте. Спасибо за вопрос.
Это можно решить с помощью плагина. Для этого нужно:

1) Создать у товара TV с ценой для авторизованных пользователей.
2) Сделать небольшой плагин для события TSVshopOnAddItem, который определяет, авторизован ли пользователь, и если да, то заменяет текущую цену на цену из созданного в пункте 1 TV-параметра.

В отношении самого плагина, приведу пример (писал наскорую, не тестировал, но думаю, что будет работать):

Код: Выделить всё

// вешаем на событие TSVshopOnAddItem
global $tsvshop, $modx, $session;
$e = & $modx->Event;
include (MODX_BASE_PATH . "assets/snippets/tsvshop/include/config.inc.php");
include (MODX_BASE_PATH . "assets/snippets/tsvshop/include/cart.inc.php");
$tvnewprice = '25'; //номер ТВ с ценой для авторизованных

//Если срабатывает событие
if ($e->name == 'TSVshopOnAddItem') {
   if ($modx->getLoginUserId()) { // если авторизован
      $newprice = $modx->getTemplateVar($tvnewprice,'*',$_SESSION[$session]['orders'][$item]['url']); // процент скидки товара
      if (!empty($newprice['value'])) {
         $_SESSION[$session]['orders'][$item]['price'] = $newprice['value'];
      }
   }
}


ekcreate
Сообщения: 76
Зарегистрирован: 04 мар 2016, 12:08

Re: Две цены у товара

Сообщение ekcreate » 10 мар 2016, 11:24

Добрый день, при добавление в корзину добавляет с новой ценой вроде
а как сделать что б именно для группы group1 например менял цену
и еще как в карточке товара правильно заменить цену?
заранее спасибо за ответ

admin
Администратор
Сообщения: 148
Зарегистрирован: 08 фев 2013, 13:53

Re: Две цены у товара

Сообщение admin » 12 мар 2016, 20:31

Чтобы цена менялась только для определенной группы пользователей, нужно еще добавить проверку группы пользователей. Ниже привожу измененный код плагина.

С заменой цены в карточке товара немного сложнее, сейчас подмена цены не предусмотрена. Внесем это в новую версию модуля. Ну а пока именно для карточки товара придется немного подкорректировать код сниппета. Итак:

1) Приложенный файл tsvshop.inc.php разместите вместо старого в папке /assets/snippets/tsvshop/include/ (сохранив на всякий случай старый файл) - я его запаковал в архив.
tsvshop.inc.zip
(2.77 КБ) 144 скачивания

2) Заменяем код плагина вот на этот новый (он решает сразу обе ваши задачи):

Код: Выделить всё

// вешаем на событие TSVshopOnAddItem
global $tsvshop, $modx, $session;
$e = & $modx->Event;
include (MODX_BASE_PATH . "assets/snippets/tsvshop/include/config.inc.php");
include (MODX_BASE_PATH . "assets/snippets/tsvshop/include/cart.inc.php");
$tvnewprice = '25'; //номер ТВ с ценой для авторизованных
$group = 'Название группы'; //впишите нужно название группы

//Если срабатывает событие
if ($e->name == 'TSVshopOnAddItem') {
   $usergroups = $modx->getUserDocGroups(true);
   if ($modx->getLoginUserId() && in_array($group,$usergroups)) { // если авторизован
      $newprice = $modx->getTemplateVar($tvnewprice,'*',$_SESSION[$session]['orders'][$item]['url']); // процент скидки товара
      if (!empty($newprice['value'])) {
         $_SESSION[$session]['orders'][$item]['price'] = $newprice['value'];
      }
   }
}

//Если срабатывает событие
if ($e->name == 'TSVshopOnViewItemCard') {
   $usergroups = $modx->getUserDocGroups(true);
   if ($modx->getLoginUserId() && in_array($group,$usergroups)) { // если авторизован
      $newprice = $modx->getTemplateVar($tvnewprice,'*',$_SESSION[$session]['orders'][$item]['url']); // процент скидки товара
      if (!empty($newprice['value'])) {
         $e->output(serialize(array('price'=>$newprice['value'])));
      }
   }
}


Опять же, если будут проблемы, пишите, постараюсь помочь

ekcreate
Сообщения: 76
Зарегистрирован: 04 мар 2016, 12:08

Re: Две цены у товара

Сообщение ekcreate » 14 мар 2016, 10:52

спасибо, сделал все как вы описали, в корзине с новой ценой на карте товара не меняент(

ekcreate
Сообщения: 76
Зарегистрирован: 04 мар 2016, 12:08

Re: Две цены у товара

Сообщение ekcreate » 14 мар 2016, 10:58

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

ekcreate
Сообщения: 76
Зарегистрирован: 04 мар 2016, 12:08

Re: Две цены у товара

Сообщение ekcreate » 14 мар 2016, 13:35

не могу понять какое это событие будет в TSV


Вернуться в «Как сделать ... ?»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость