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


Правила форума

Внимание!!! Если не можете скачать, пожалуйста ознакомьтесь с условиями получения доступа с файлам форума. Правила форума


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


Сообщений в теме: 13

#1 badisoft

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

  • Assistent vsupport.ru
  • PipPipPip
  • 5 074 сообщений
Репутация: 785
Мастер

Отправлено 24 марта 2013 - 13:47

Спонсор дополнения - 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. Аналогичные действия проделываем и в других блоках-модулях, если вдруг у зарегистрированного пользователя где-то вылезет цена без скидки. Или пишем в соответствующую тему форума.

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


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

#2 etdnepr

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

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

Отправлено 01 апреля 2013 - 23:06

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

#3 badisoft

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

  • Assistent vsupport.ru
  • PipPipPip
  • 5 074 сообщений
Репутация: 785
Мастер

Отправлено 01 апреля 2013 - 23:48

Просмотр сообщенияetdnepr сказал:

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

#4 etdnepr

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

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

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

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

#5 badisoft

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

  • Assistent vsupport.ru
  • PipPipPip
  • 5 074 сообщений
Репутация: 785
Мастер

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

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

#6 Salp

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

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

Отправлено 15 августа 2013 - 08:58

В 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>


#7 jiykka

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

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

Отправлено 05 июля 2016 - 20:57

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

#8 badisoft

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

  • Assistent vsupport.ru
  • PipPipPip
  • 5 074 сообщений
Репутация: 785
Мастер

Отправлено 05 июля 2016 - 21:50

Просмотр сообщенияjiykka сказал:

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

#9 jiykka

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

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

Отправлено 05 июля 2016 - 22:47

Просмотр сообщенияbadisoft (05 июля 2016 - 21:50) писал:

Просмотр сообщенияjiykka сказал:

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

#10 badisoft

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

  • Assistent vsupport.ru
  • PipPipPip
  • 5 074 сообщений
Репутация: 785
Мастер

Отправлено 05 июля 2016 - 23:00

Просмотр сообщенияjiykka сказал:

Так же не меняется.
Ну чудес-то не бывает.
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 и стоит раньше по коду.
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#11 jiykka

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

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

Отправлено 06 июля 2016 - 10:57

Просмотр сообщенияbadisoft (05 июля 2016 - 23:00) писал:

Просмотр сообщенияjiykka сказал:

Так же не меняется.
Ну чудес-то не бывает.
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 и стоит раньше по коду.

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

#12 jiykka

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

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

Отправлено 23 августа 2016 - 18:45

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

#13 badisoft

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

  • Assistent vsupport.ru
  • PipPipPip
  • 5 074 сообщений
Репутация: 785
Мастер

Отправлено 23 августа 2016 - 19:01

Просмотр сообщенияjiykka сказал:

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

#14 antaNT

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

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

Отправлено 30 августа 2018 - 07:16

полагаю пункт 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 [ДОПОЛНЕНИЕ] РАЗНАЯ СКИДКА ДЛЯ РАЗНЫХ КАТЕГОРИЙ
}