Скидка группы на товар, имеющий специальную цену для этой группы
- Дмитрий
- Автор темы
- Не в сети
- Новый участник
Less
Больше
- Сообщений: 4
- Спасибо получено: 0
8 года 8 мес. назад #7553
от Дмитрий
Дмитрий создал тему: Скидка группы на товар, имеющий специальную цену для этой группы
Добрый день! VirtueMart 1.1.2. При создании группы покупателей и скидки для неё подсказка гласит: "Положительное значение Х означает: если товару не назначена цена для ЭТОЙ группы покупателей, то цена по умолчанию уменьшается на Х %". Однако, в реальности магазин берёт специальную цену товара для группы и применяет к ней скидку для этой группы.
Пример: Цена товара 100, группа "А" имеет скидку на все товары 10%, на данный товар нужна фиксированная цена для всех постоянных клиентов - 95, вне зависимости от размера их постоянной скидки, поэтому мы создаём специальную цену на данный товар для группы "А" - 95, но магазин берёт цену для группы 95 и применяет к ней групповую скидку 10%, результат - 85,5.
Как я понимаю, нужно внести дополнительную проверку на наличие у товара спец цены для группы.
В Ps_product.php в районе 1720 строки происходит подсчет цены со скидкой группы, уже задано условие для проверки нет ли на товар обычной скидки, чтобы не суммировалась со скидкой группы. Работает замечательно. Как правильно добавить условие на наличие спец цены для группы? "Если на товар есть цена для данной группы, то"
В представленном фрагменте кода, насколько я понимаю, как раз проверяется наличие цены на товар для данной группы.
Похоже, что тут проверка на наличие цены идёт
Пытаюсь понять, куда надо вставить
чтобы групповая скидка работала избирательно.
Очень прошу помочь!
Пример: Цена товара 100, группа "А" имеет скидку на все товары 10%, на данный товар нужна фиксированная цена для всех постоянных клиентов - 95, вне зависимости от размера их постоянной скидки, поэтому мы создаём специальную цену на данный товар для группы "А" - 95, но магазин берёт цену для группы 95 и применяет к ней групповую скидку 10%, результат - 85,5.
Как я понимаю, нужно внести дополнительную проверку на наличие у товара спец цены для группы.
В Ps_product.php в районе 1720 строки происходит подсчет цены со скидкой группы, уже задано условие для проверки нет ли на товар обычной скидки, чтобы не суммировалась со скидкой группы. Работает замечательно. Как правильно добавить условие на наличие спец цены для группы? "Если на товар есть цена для данной группы, то"
В представленном фрагменте кода, насколько я понимаю, как раз проверяется наличие цены на товар для данной группы.
ВНИМАНИЕ: Спойлер!
Code:
/**
* Returns the price for a specific shopper group,
* Returns nothing, when the shopper group has no price
*
* @param int $product_id
* @param int $shopper_group_id
* @param boolean $check_multiple_prices
* @param string $additionalSQL
* @return mixed
*/
function getPriceByShopperGroup( $product_id, $shopper_group_id, $check_multiple_prices=false, $additionalSQL='' )
{
global $auth;
static $resultcache = array();
$db = new ps_DB;
$vendor_id = $_SESSION['ps_vendor_id'];
if( empty( $shopper_group_id )) {
ps_shopper_group::makeDefaultShopperGroupInfo();
$shopper_group_id = $GLOBALS['vendor_info'][$vendor_id]['default_shopper_group_id'];
}
$whereClause='WHERE product_id=%s AND shopper_group_id=%s ';
$whereClause = sprintf( $whereClause, intval($product_id), intval($shopper_group_id) );
$q = "SELECT `product_price`, `product_price_id`, `product_currency` FROM `#__{vm}_product_price` $whereClause $additionalSQL";
$sig = sprintf("%u\n", crc32($q));
if( !isset($resultcache[$sig]))
{
$db->query($q);
if( !$db->next_record() ) return false;
$discount_info = $this->get_discount( $product_id );
if ($discount_info [amount] > 0 )
{
$price_info["product_price"]= $db->f("product_price");
}
else
{
$price_info["product_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100);
}
$price_info["product_currency"] = $db->f("product_currency");
$price_info["product_base_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100);
$price_info["product_has_multiple_prices"] = $db->num_rows() > 1;
$price_info["product_price_id"] = $db->f("product_price_id");
$price_info["item"]=true;
$GLOBALS['product_info'][$product_id]['price'] = $price_info;
// Store the result for later
$resultcache[$sig] = $price_info;
return $GLOBALS['product_info'][$product_id]['price'];
}
else
{
return $resultcache[$sig];
}
}
Похоже, что тут проверка на наличие цены идёт
Code:
if( !isset($resultcache[$sig]))
Code:
$price_info["product_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100)
Очень прошу помочь!
Пожалуйста Войти или Зарегистрируйтесь, чтобы присоединиться к беседе.
- Wedal
- Не в сети
- Администратор
Less
Больше
- Сообщений: 2868
- Спасибо получено: 659
8 года 8 мес. назад #7554
от Wedal
Wedal ответил в теме Скидка группы на товар, имеющий специальную цену для этой группы
Дмитрий, тяжело разобраться без отладки, но похоже, что код верный и логика правильная. Код:
на первый взгляд бессмысленный: если скидка есть, то оставляем цену неизменной, а если ее нет, то добавляем скидку для группы. Но на самом деле $price_info["product_price"] - это уже цена для группы. Т.е. та самая, которую вы ищите. В этом случае код обретает смысл в логике: "Не учитываем скидку для товара из группы, если для него задана цена."
Но заметьте, ниже есть еще строчка:
Т.е. здесь в переменную базовой цены записывается цена для группы со скидкой группы. Видимо на сайте у вас используется именно базовая цена, а не основная.
Если все так, то нужно убрать эту строчку ниже и перенести ее в код вот так:
Не представляю, будет ли это работать и что сломает где-нибудь в другом месте, но попробовать стоит .
Code:
$discount_info = $this->get_discount( $product_id );
if ($discount_info [amount] > 0 )
{
$price_info["product_price"]= $db->f("product_price");
}
else
{
$price_info["product_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100);
}
Но заметьте, ниже есть еще строчка:
Code:
$price_info["product_base_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100);
Если все так, то нужно убрать эту строчку ниже и перенести ее в код вот так:
Code:
$discount_info = $this->get_discount( $product_id );
if ($discount_info [amount] > 0 )
{
$price_info["product_price"]= $db->f("product_price");
$price_info["product_base_price"]= $db->f("product_price");
}
else
{
$price_info["product_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100);
$price_info["product_base_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100);
}
Не представляю, будет ли это работать и что сломает где-нибудь в другом месте, но попробовать стоит .
Пожалуйста Войти или Зарегистрируйтесь, чтобы присоединиться к беседе.
- Дмитрий
- Автор темы
- Не в сети
- Новый участник
Less
Больше
- Сообщений: 4
- Спасибо получено: 0
8 года 8 мес. назад - 8 года 8 мес. назад #7555
от Дмитрий
Дмитрий ответил в теме Скидка группы на товар, имеющий специальную цену для этой группы
Вариант с базовой ценой ничего не изменил.
Дело в том, что $discount_info - это скидка на сам товар (с перечеркнутой ценой) безотносительно группы покупателей, она не имеет отношения в групповой скидке.
условие
вставлено с другой целью - не применять групповую скидку, если на товар уже есть скидка.
Как я понимаю, для решения моей задачи нужно найти в какой момент происходит проверка на наличие цены для группы, но не хватает знаний. Возможно в предыдущей секции :
"Получение цены для группы"
Она идёт непосредственно перед секцией расчёта цены:
Как можно выполнить отладку, чтобы проследить на каком этапе какое значение принимает цена?
Дело в том, что $discount_info - это скидка на сам товар (с перечеркнутой ценой) безотносительно группы покупателей, она не имеет отношения в групповой скидке.
условие
Code:
if ($discount_info [amount] > 0
Как я понимаю, для решения моей задачи нужно найти в какой момент происходит проверка на наличие цены для группы, но не хватает знаний. Возможно в предыдущей секции :
"Получение цены для группы"
ВНИМАНИЕ: Спойлер!
Code:
/**
* Get the price of product $product_id for the shopper group associated
* with $auth['user_id'] - including shopper group discounts
*
* @param int $product_id
* @param boolean $check_multiple_prices Check if the product has more than one price for that shopper group?
* @return array The product price information
*/
function get_price($product_id, $check_multiple_prices=false, $overrideShopperGroup='' ) {
if( empty( $product_id)) return array();
$auth = $_SESSION['auth'];
$cart = $_SESSION['cart'];
if( empty( $GLOBALS['product_info'][$product_id]['price'] )
|| !empty($GLOBALS['product_info'][$product_id]['price']["product_has_multiple_prices"])
|| $check_multiple_prices) {
$db = new ps_DB;
$vendor_id = $this->get_vendor_id($product_id);
if( $overrideShopperGroup === '') {
$shopper_group_id = $auth["shopper_group_id"];
$shopper_group_discount = $auth["shopper_group_discount"];
}
else {
$shopper_group_id = $overrideShopperGroup;
$shopper_group_discount = 0;
}
ps_shopper_group::makeDefaultShopperGroupInfo();
// Get the product_parent_id for this product/item
$product_parent_id = $this->get_field($product_id, "product_parent_id");
if( !$check_multiple_prices ) {
/* Added for Volume based prices */
// This is an important decision: we add up all product quantities with the same product_id,
// regardless to attributes. This gives "real" volume based discount, because our simple attributes
// depend on one and the same product_id
$quantity = 0;
$parent_id = "";
if ($product_parent_id) {
$parent = true;
}
else {
$parent = false;
}
for ($i=0;$i<$cart["idx"];$i++) {
if ($cart[$i]["product_id"] == $product_id) {
if ($parent) {
$parent_id = $cart[$i]["parent_id"];
}
else {
$quantity += $cart[$i]["quantity"];
}
}
}
if ($parent) {
for ($i=0;$i<$cart["idx"];$i++) {
if (@$cart[$i]['parent_id'] == $parent_id) {
$quantity += $cart[$i]["quantity"];
}
}
}
$volume_quantity_sql = " ORDER BY price_quantity_start";
if( $quantity > 0 ) {
$volume_quantity_sql = " AND (('$quantity' >= price_quantity_start AND '$quantity' <= price_quantity_end)
OR (price_quantity_end='0') OR ('$quantity' > price_quantity_end)) ORDER BY price_quantity_end DESC";
}
}
else {
$volume_quantity_sql = " ORDER BY price_quantity_start";
}
// Get the price array
$price = $this->getPriceByShopperGroup( $product_id, $shopper_group_id, $check_multiple_prices, $volume_quantity_sql );
if( !$price && $product_parent_id ) {
// If this is a child product and it has not a price for the requested shopper group, get the price for the default shopper group
$price = $this->getPriceByShopperGroup( $product_parent_id, $GLOBALS['vendor_info'][$vendor_id]['default_shopper_group_id'], $check_multiple_prices, $volume_quantity_sql );
if( !$price ) {
// if the child product has no priceat all, get the price of the parent product for that shopper group
$price = $this->getPriceByShopperGroup( $product_parent_id, $shopper_group_id, $check_multiple_prices, $volume_quantity_sql );
}
if( !$price ) {
// if the parent product has no price for the requested shopper group, get the price of the default shopper group
$price = $this->getPriceByShopperGroup( $product_parent_id, $shopper_group_id, $check_multiple_prices, $volume_quantity_sql );
}
}
elseif( !$price ) {
// if the product has no price for the requested shopper group, get the price of the default shopper group
$price = $this->getPriceByShopperGroup( $product_id, $GLOBALS['vendor_info'][$vendor_id]['default_shopper_group_id'], $check_multiple_prices, $volume_quantity_sql );
}
return $price;
}
else {
return $GLOBALS['product_info'][$product_id]['price'];
}
}
Она идёт непосредственно перед секцией расчёта цены:
ВНИМАНИЕ: Спойлер!
Code:
/**
* Returns the price for a specific shopper group,
* Returns nothing, when the shopper group has no price
*
* @param int $product_id
* @param int $shopper_group_id
* @param boolean $check_multiple_prices
* @param string $additionalSQL
* @return mixed
*/
function getPriceByShopperGroup( $product_id, $shopper_group_id, $check_multiple_prices=false, $additionalSQL='' )
{
global $auth;
static $resultcache = array();
$db = new ps_DB;
$vendor_id = $_SESSION['ps_vendor_id'];
if( empty( $shopper_group_id )) {
ps_shopper_group::makeDefaultShopperGroupInfo();
$shopper_group_id = $GLOBALS['vendor_info'][$vendor_id]['default_shopper_group_id'];
}
$whereClause='WHERE product_id=%s AND shopper_group_id=%s ';
$whereClause = sprintf( $whereClause, intval($product_id), intval($shopper_group_id) );
$q = "SELECT `product_price`, `product_price_id`, `product_currency` FROM `#__{vm}_product_price` $whereClause $additionalSQL";
$sig = sprintf("%u\n", crc32($q));
if( !isset($resultcache[$sig]))
{
$db->query($q);
if( !$db->next_record() ) return false;
$discount_info = $this->get_discount( $product_id );
if ($discount_info [amount] > 0 )
{
$price_info["product_price"]= $db->f("product_price");
}
else
{
$price_info["product_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100);
}
$price_info["product_currency"] = $db->f("product_currency");
$price_info["product_base_price"]= $db->f("product_price") * ((100 - $auth["shopper_group_discount"])/100);
$price_info["product_has_multiple_prices"] = $db->num_rows() > 1;
$price_info["product_price_id"] = $db->f("product_price_id");
$price_info["item"]=true;
$GLOBALS['product_info'][$product_id]['price'] = $price_info;
// Store the result for later
$resultcache[$sig] = $price_info;
return $GLOBALS['product_info'][$product_id]['price'];
}
else
{
return $resultcache[$sig];
}
}
Как можно выполнить отладку, чтобы проследить на каком этапе какое значение принимает цена?
Последнее редактирование: 8 года 8 мес. назад пользователем Дмитрий.
Пожалуйста Войти или Зарегистрируйтесь, чтобы присоединиться к беседе.
- Wedal
- Не в сети
- Администратор
Less
Больше
- Сообщений: 2868
- Спасибо получено: 659
8 года 8 мес. назад #7557
от Wedal
Wedal ответил в теме Скидка группы на товар, имеющий специальную цену для этой группы
Дмитрий,
это уже цена со скидкой, которая получена из базы данных. Важно понять, применена ли к ней уже скидка для группы.
Для отладки вы можете вставить в нужном месте кода конструкцию:
Где-то на странице товара рядом с ценой при этом должно появиться значение переменной.
Но меня не покидает мысль: а стоило ли вообще трогать код? Может быть можно задать скидки в админке так, чтобы они покрывали ваши требования?
Code:
$db->f("product_price");
Для отладки вы можете вставить в нужном месте кода конструкцию:
Code:
print_r($ПЕРЕМЕННАЯ_PHP);
Но меня не покидает мысль: а стоило ли вообще трогать код? Может быть можно задать скидки в админке так, чтобы они покрывали ваши требования?
Пожалуйста Войти или Зарегистрируйтесь, чтобы присоединиться к беседе.
- Дмитрий
- Автор темы
- Не в сети
- Новый участник
Less
Больше
- Сообщений: 4
- Спасибо получено: 0
8 года 8 мес. назад #7559
от Дмитрий
Поскольку товаров таких более 200, это выливается в муторную работу, потому и хотел заставить магазин работать как положено.
Виталий, или вы знаете более простой способ задать скидки на определенные категории?
Дмитрий ответил в теме Скидка группы на товар, имеющий специальную цену для этой группы
Поскольку магазин не может задавать групповую скидку для отдельных категорий товара, придётся каждому товару назначать цены для группы с таким расчетом, чтобы после вычитания групповой скидки получался нужный результат. То есть, если нужно дать скидку 5% группе "10%", то цена_для_группы=0,95*цена_товара/0,9=1,05*цена_товара.Но меня не покидает мысль: а стоило ли вообще трогать код? Может быть можно задать скидки в админке так, чтобы они покрывали ваши требования?
Поскольку товаров таких более 200, это выливается в муторную работу, потому и хотел заставить магазин работать как положено.
Виталий, или вы знаете более простой способ задать скидки на определенные категории?
Пожалуйста Войти или Зарегистрируйтесь, чтобы присоединиться к беседе.
- Wedal
- Не в сети
- Администратор
Less
Больше
- Сообщений: 2868
- Спасибо получено: 659
8 года 8 мес. назад #7561
от Wedal
Wedal ответил в теме Скидка группы на товар, имеющий специальную цену для этой группы
Дмитрий, я уже давно не работал с Vm 1.1.x и плохо помню настройки в админке. В VM 2-3 ваша задача решается в пару кликов. Я тут вспомнил, что писал статью, которая может вам пригодиться:
wedal.ru/rasshireniya-joomla/virtuemart-internet-magazin-na-joomla-chast-28-fast-data-processing.html
Посмотрите в ней блок: "Скидка определенной категории товаров". Может быть вам это подойдет. Вариант, конечно, не идеальный, но в принципе приемлемый.
wedal.ru/rasshireniya-joomla/virtuemart-internet-magazin-na-joomla-chast-28-fast-data-processing.html
Посмотрите в ней блок: "Скидка определенной категории товаров". Может быть вам это подойдет. Вариант, конечно, не идеальный, но в принципе приемлемый.
Спасибо сказали: Дмитрий
Пожалуйста Войти или Зарегистрируйтесь, чтобы присоединиться к беседе.
- Дмитрий
- Автор темы
- Не в сети
- Новый участник
Less
Больше
- Сообщений: 4
- Спасибо получено: 0
8 года 8 мес. назад #7563
от Дмитрий
Дмитрий ответил в теме Скидка группы на товар, имеющий специальную цену для этой группы
Спасибо! Изучу статью!
Пожалуйста Войти или Зарегистрируйтесь, чтобы присоединиться к беседе.