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


[дополнение] Разная скидка для разных категорий


  • Вы не можете ответить в тему
Сообщений в теме: 13

#1 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 24 March 2013 - 01:47 PM

Спонсор дополнения - dgimmibos

Штатно в ShopCMS скидку можно задать только либо для группы клиентов, либо по сумме заказа, либо комбинируя эти две скидки (сумма скидок или максимальная из них).

Это дополнение при использовании варианта Системы скидок "Скидка группы пользователя" (т.е. без комбинирования) дает возможность задать скидку отдельно для каждой категории товаров. Задается штатная скидка для группы, но можно задать категории товаров с другой скидкой.

В ShopCMS исходно алгоритм таков, что скидка во всех вариантах считается от общей суммы заказа, т.е. уже на этапе оформления корзины в заказ. При этом клиент везде видит цены "как для всех", а свою скидку только при оформлении заказа. Это в чем-то удобно, в чем-то нет.

В случае разной скидки по разным категориям такой вариант не подходит, т.к. скидку надо считать для каждого товара по отдельности и наиболее простым показалось изначально работать с ценой, куда уже заложена скидка. Это привело к некоторому (в результате не особо и большому) усложнению алгоритма. Бонусом идут "свои цены для каждого клиента". Другими словами, зарегистрировавшийся клиент сразу и везде видит именно свою цену. Хотя, конечно, если разная скидка в разных категориях не нужна, то то же самое можно сделать куда проще.

Собственно, это все вводная для понимания. Общий алгоритм прост:

1. Пишем функцию, принимающую переменные ("цена","категория") и возвращающую исправленную в соответствии с клиентом (клиент есть в элементе массива $_SESSION['log']) новую цену. Используем эту функцию везде, где из SQL-таблицы товаров считываются параметры товара (цена и прочее). Что-то типа цена=функция("цена","категория"). В большинстве случаев это

$row['Price']=функция($row['Price'],$row['categoryID']);

Обычно для получения информации о товаре используется функция GetProduct(),
куда и надо первым делом вставить эту строку сразу после

while ($row = db_fetch_assoc($g)) {


2. Не везде используется GetProduct. Очень много где (например, в home.php, да и в большинстве сторонних модулей) делается прямой запрос к SQL-таблице продуктов за ценой и прочими атрибутами товара. В каждом таком месте надо сделать ровно то же самое. Например, в home.php аж четыре раза - для спецпредложений, для новинок, для популярных и для случайных. Причем для популярных и случайных еще и categoryID придется в SQL-запрос добавить, т.к. штатно его там нет, а он нужен для вычисления скидки на продукт.

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

Конкретика:

0. переписываем файлы

custord_custgroup.php -> core/includes/admin/sub/
custord_custgroup.tpl.html -> core/tpl/admin/

После этого уже можно (да и нужно) попробовать зайти в админку в "Группы покупателей" и попробовать посоздавать разные скидки у разных групп для разных категорий.


1. В файле discount_functions.php

1.1. в функции dscCalculateDiscount

заменяем



case 2:
if ( !is_bool($customerID=regGetIdByLogin($log)) )
{
$customer_group = GetCustomerGroupByCustomerId( $customerID );
if ( $customer_group )
$discount["discount_percent"] = $customer_group["custgroup_discount"];
else
$discount["discount_percent"] = 0;
}
else
return $discount;
break;


на


case 2:
return $discount;
break;


1.2 в конец файла (до ?> естественно) дописываем


function CatDiscount ($price,$categoryID)
{
if (CONF_DISCOUNT_TYPE == 2 && !strpos($_SERVER['REQUEST_URI'],ADMIN_FILE) && isset($_SESSION["log"]) && !is_bool($customerID=regGetIdByLogin($_SESSION["log"])) && $customer_group = GetCustomerGroupByCustomerId( $customerID ))
{
if ($row = db_fetch_assoc(db_query("SELECT discount FROM ".DB_PRFX."custgroups_category WHERE categoryID=$categoryID AND custgroupID=".$customer_group['custgroupID']." LIMIT 1")))
return $price*(1-$row['discount']/100);
else
return $price*(1-$customer_group['custgroup_discount']/100);
}
else
return $price;
}



2. в файле product_functions.php

2.1 в функции GetProduct

перед строкой


$product['date_added']=format_datetime( $product['date_added'] );


вставляем


$product['Price'] = CatDiscount($product['Price'],$product['categoryID']);


2.2 в функции GetExtraParametrs

перед строкой


while( $_Rowue = db_fetch_assoc($q2) ){


вставляем


if (CONF_DISCOUNT_TYPE == 2 && isset($_SESSION["log"]) && !is_bool($customerID=regGetIdByLogin($_SESSION["log"])) && $customer_group = GetCustomerGroupByCustomerId( $customerID ))
{
$change = ($row = db_fetch_assoc(db_query("SELECT discount FROM ".PRODUCTS_TABLE.
" JOIN ".DB_PRFX."custgroups_category USING (categoryID)
WHERE productID=".$_Row['productID']." AND custgroupID=".$customer_group['custgroupID'].
" LIMIT 1"))) ? (1-$row['discount']/100) : 1;
}
else $change=1;


строку


$_Row['values_to_select'][$i]['price_surplus'] = show_priceWithOutUnit($_Rowue['price_surplus']);


заменяем на


$_Row['values_to_select'][$i]['price_surplus'] = show_priceWithOutUnit((float)$_Rowue['price_surplus']*$change);


2.3 в функции prdSearchProductByTemplate

перед ВТОРЫМ вхождением строки


if ( isset($callBackParam["extraParametrsTemplate"]) ){


вставляем


$row["Price"] = CatDiscount ($row["Price"],$row["categoryID"]);



3. в файле cart_functions.php в функции GetPriceProductWithOption

вместо строк


$q=db_query("select Price from ".PRODUCTS_TABLE." where productID=".(int)$productID);
$r=db_fetch_row($q);
$base_price = (float)$r[0];


вставляем


$q=db_query("select Price, categoryID from ".PRODUCTS_TABLE." where productID=".(int)$productID);
$r=db_fetch_assoc($q);
$base_price = CatDiscount ((float)$r['Price'],$r['categoryID']);
$change = $base_price/(float)$r['Price'];


вместо строки


$full_price += $r1["price_surplus"];


вставляем


$full_price += $r1["price_surplus"]*$change;



4. в файле home.php

4.1 в коде под строкой

//special offers

ниже строк


while ($row = db_fetch_row($q))
{


вставляем


$row[3] = CatDiscount($row[3],$row['categoryID']);



4.2 в коде под строкой


$cifra = 8; //количество последних товаров для выбора


строку


$q = db_query("select s.productID, s.name, s.Price, s.enabled, t.filename FROM ".PRODUCTS_TABLE." AS s LEFT JOIN ".PRODUCT_PICTURES."


заменяем на


$q = db_query("select s.productID, s.name, s.Price, s.enabled, t.filename, s.categoryID FROM ".PRODUCTS_TABLE." AS s LEFT JOIN ".PRODUCT_PICTURES."


ниже строк


while ($row = db_fetch_row($q))
{


вставляем


$row['Price'] = CatDiscount($row['Price'],$row['categoryID']);



4.3 в коде под следующей строкой


$cifra = 8; //количество последних товаров для выбора


строку


$q = db_query("select s.productID, s.name, s.Price, s.enabled, t.filename FROM ".PRODUCTS_TABLE." AS s LEFT JOIN ".PRODUCT_PICTURES."


заменяем на


$q = db_query("select s.productID, s.name, s.Price, s.enabled, t.filename, s.categoryID FROM ".PRODUCTS_TABLE." AS s LEFT JOIN ".PRODUCT_PICTURES."


ниже строк


while ($row = db_fetch_row($q))
{


вставляем


$row['Price'] = CatDiscount($row['Price'],$row['categoryID']);


5. в файле pricelist.php

перед строкой


if ($row1[2] < 0){


вставляем


$row1[2] = CatDiscount($row1[2],$row[0]);



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

Прикрепленные файлы


  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#2 etdnepr

    Продвинутый пользователь

  • Download User
  • PipPipPip
  • 101 сообщений
Репутация: 0
Начинающий

Отправлено 01 April 2013 - 11:06 PM

Добрый день! Разъясните плиз... В штатном варианте можно назначить разные группы покупателей и давать им разные скидки. Клиент получает скидку , которая соответствуем группе, к которой он отнесен и видит он ее на последнем этапе оформления заказа.
После внесения предложенных изменений каждый зарегистрировавшийся клиент будет видеть на сайте цену с учетом конкретно его скидки сразу или видеть цену с учетом скидки группы? Спасибо за ответ.
  • 0

#3 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 01 April 2013 - 11:48 PM

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

А что такое "конкретно его скидка" и чем она отличается от групповой? Я опять что-то пропустил и в ShopCMS можно не только занести клиента в группу с определенной скидкой, но и дать клиенту индивидуальную?
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#4 etdnepr

    Продвинутый пользователь

  • Download User
  • PipPipPip
  • 101 сообщений
Репутация: 0
Начинающий

Отправлено 02 April 2013 - 09:04 AM

)))) Вот я и удивился... Я так понимаю , что с помощью предложенного Вами дополнения мы достигаем то, что клиент после авторизации видит цену со скидкой для его группы, в отличии от штатного варианта, когда скидка видна на последнем этапе оформления заказа, Правильно я понял?
  • 0

#5 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 02 April 2013 - 09:46 AM

Да.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#6 Salp

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 218 сообщений
Репутация: 54
Продвинутый

Отправлено 15 August 2013 - 08:58 AM

В custord_custgroup.tpl.html для более удобного отображения заменил:
<tr><td colspan="4"><table class="adn"><tr><td class="separ"><img src="data/admin/pixel.gif" alt="" class="sep"></td></tr><tr><td class="se5"></td></tr></table></td></tr>

на
<tr><td colspan="4"><table class="adn"><tr><td class="separ"><img src="data/admin/pixel.gif" alt="" class="sep"></td></tr>{if %i.last%}<tr><td class="se5"></td></tr>{/if}</table></td></tr>

  • 0

#7 jiykka

    Пользователь

  • Download User
  • PipPip
  • 29 сообщений
Репутация: 0
Начинающий

Отправлено 05 July 2016 - 08:57 PM

Сделал все вышеуказанное, в админке появилась возможность в группе пользователей назначать скидку.
Скидка отображается только в подробном описании - а как сделать в product_brief?
Спасибо=)
  • 0

#8 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 05 July 2016 - 09:50 PM

Скидка отображается только в подробном описании - а как сделать в product_brief?

Для product_brief.tpl.html, т.е. для category.php цену товара с обычной на скидочную подменяет п.2.3 инструкции.
Проверил. Похоже, этот пункт некорректен. Вставку надо делать после ВТОРОГО вхождения указанной строки.
Т.е. когда уже выполнен SQL-запрос и $row['Price'] уже существует.
Исправил инструкцию.
  • 1
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#9 jiykka

    Пользователь

  • Download User
  • PipPip
  • 29 сообщений
Репутация: 0
Начинающий

Отправлено 05 July 2016 - 10:47 PM

Скидка отображается только в подробном описании - а как сделать в product_brief?

Для product_brief.tpl.html, т.е. для category.php цену товара с обычной на скидочную подменяет п.2.3 инструкции.
Проверил. Похоже, этот пункт некорректен. Вставку надо делать после ВТОРОГО вхождения указанной строки.
Т.е. когда уже выполнен SQL-запрос и $row['Price'] уже существует.
Исправил инструкцию.

Так же не меняется. В detailed есть в brief нет:(
и перед и после 2го вхождения ничего не меняется.
  • 0

#10 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 05 July 2016 - 11:00 PM

Так же не меняется.

Ну чудес-то не бывает.
1. цены в категории (т.е. для шаблона product_brief) формируются в category.php путем вызова (в конечном итоге) функции prdSearchProductByTemplate.
2. в этой функции есть SQL-запрос

$q = db_query( $sqlQuery );

3. ниже цикл по формированию массива данных (в том числе и прайса)

while( $row = db_fetch_row($q) )

Вот в этом цикле в самом начале и надо заменить $row["Price"] на прайс со скидкой.

Если Вы в этом цикле перед

if ( isset($callBackParam["extraParametrsTemplate"]) ){

прописываете описанную в п.2.3 инструкции строку подмены, то цена долна измениться.
Если не изменилась, значит Вы что-то делаете не так или не там.
Например, все изменения делаете в функции prdSearchProductByTemplateAdmin, которая практически копия prdSearchProductByTemplate и стоит раньше по коду.
  • 1
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#11 jiykka

    Пользователь

  • Download User
  • PipPip
  • 29 сообщений
Репутация: 0
Начинающий

Отправлено 06 July 2016 - 10:57 AM

Так же не меняется.

Ну чудес-то не бывает.
1. цены в категории (т.е. для шаблона product_brief) формируются в category.php путем вызова (в конечном итоге) функции prdSearchProductByTemplate.
2. в этой функции есть SQL-запрос

$q = db_query( $sqlQuery );

3. ниже цикл по формированию массива данных (в том числе и прайса)

while( $row = db_fetch_row($q) )

Вот в этом цикле в самом начале и надо заменить $row["Price"] на прайс со скидкой.

Если Вы в этом цикле перед

if ( isset($callBackParam["extraParametrsTemplate"]) ){

прописываете описанную в п.2.3 инструкции строку подмены, то цена долна измениться.
Если не изменилась, значит Вы что-то делаете не так или не там.
Например, все изменения делаете в функции prdSearchProductByTemplateAdmin, которая практически копия prdSearchProductByTemplate и стоит раньше по коду.


Благодарю за подробный ответ. Получается что это уже третье вхождение этой строки (по крайней мере у меня так). Теперь все заработало!
  • 0

#12 jiykka

    Пользователь

  • Download User
  • PipPip
  • 29 сообщений
Репутация: 0
Начинающий

Отправлено 23 August 2016 - 06:45 PM

Товарищ Badisoft, скажите, вы выкладывали дополнение Вывод в категории и описании двух цен - со скидкой и без
Он не дружит с данным модулем как стало ясно после его установки т.к. в product_brief вывод отображается некорректно а в product_detailed вообще ничего не меняется.
Вопрос - нельзя ли их - модули эти как то подружить? Дабы человек после регистрации мог видеть перечеркнутую старую цену для незарегистрированных смертных и свою цену.
Благодарю.
  • 0

#13 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 23 August 2016 - 07:01 PM

Вопрос - нельзя ли их - модули эти как то подружить?

Можно.
Но готового решения у меня нет, т.к. задача ни разу не ставилась.
Как устроены оба модуля (один 2012-го года, второй 2013-го) я уже не помню, т.е. даже советом не помогу.
Так что, увы, либо разбираться самому, либо заказывать желаемое на коммерческой основе.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#14 antaNT

    Продвинутый пользователь

  • Download User
  • PipPipPip
  • 33 сообщений
Репутация: 1
Начинающий

Отправлено 30 August 2018 - 07:16 AM

полагаю пункт 2.3 "2.3 в функции prdSearchProductByTemplate

перед ВТОРЫМ вхождением строки" имеется ввиду всетаки ТРЕТЬЕ условие if (isset($callBackParam["extraParametrsTemplate"])) {




if ($offset &gt;= 0 &amp;&amp; $offset &lt;= $products_count) {
while ($row = db_fetch_row($q)) {

# [ДОПОЛНЕНИЕ] РАЗНАЯ СКИДКА ДЛЯ РАЗНЫХ КАТЕГОРИЙ
$row["Price"] = CatDiscount ($row["Price"],$row["categoryID"]);
# END[ДОПОЛНЕНИЕ] РАЗНАЯ СКИДКА ДЛЯ РАЗНЫХ КАТЕГОРИЙ

if (isset($callBackParam["extraParametrsTemplate"])) {

function GetPriceProductWithOption($variants, $productID) {
# [ДОПОЛНЕНИЕ] РАЗНАЯ СКИДКА ДЛЯ РАЗНЫХ КАТЕГОРИЙ
$full_price = 0;
$base_price = 0;

# $row = db_fetch_assoc(db_query("SELECT Price FROM " . PRODUCTS_TABLE . " WHERE productID=$productID LIMIT 1"));
$row = db_fetch_assoc(db_query("SELECT Price, categoryID FROM " . PRODUCTS_TABLE . " WHERE productID=$productID LIMIT 1"));

$base_price = CatDiscount ((float)$row['Price'],$row['categoryID']);
$change = $base_price/(float)$row['Price'];

if (!$variants) {
#return $row['Price']
$full_price = $base_price;
return $full_price;
}

$row1 = db_fetch_assoc(db_query("SELECT SUM(price_surplus) AS price_surplus FROM " . PRODUCTS_OPTIONS_SET_TABLE . " WHERE productID=$productID AND variantID IN (" . implode(',', $variants) . ")"));
#return $row['Price'] + $row1['price_surplus'];
$full_price = $base_price + $row1['price_surplus']*$change;
return $full_price;
# END [ДОПОЛНЕНИЕ] РАЗНАЯ СКИДКА ДЛЯ РАЗНЫХ КАТЕГОРИЙ
}
  • 0