/ Плагины / Цены в зависимости от группы пользователей

Цены в зависимости от группы пользователей

HIT

14.12.2017

7703

3

Попробуем разобраться в вопросе цен для определенных групп пользователей. Либо это должно быть реализовано специальной колонкой цен, либо скидкой на все товары.

WC Role Based Price

Плагин WC Role Based Price (6000) реализует это с помощью дополнительных полей в карточке товара. В настройках плагина мы выбираем роли, для которых цены могут отличаться. В бесплатной версии плагина это все.

Удобно, то что в настройках плагина можно выбрать определенные роли (например только созданные самостоятельно), которые будут выводится в товаре при активации функции Enable Role Based Pricing. Еще удобно, что группа дополнительных цен сохраняется ajax’ом без перезагрузки и сохранения всей страницы.

Из минусов — неудобная структура хранения цен в одном поле в виде массива. Пример, добавлено дополнительно 3 типа цен (без акционных):

a:3:{s:3:"vip";a:2:{s:13:"regular_price";s:5:"15000";s:13:"selling_price";s:0:"";}s:15:"large_wholesale";a:2:{s:13:"regular_price";s:5:"16500";s:13:"selling_price";s:0:"";}s:9:"wholesale";a:2:{s:13:"regular_price";s:5:"18000";s:13:"selling_price";s:0:"";}}

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

Pro версия за $59 предлагает такие дополнения:

  • Расписание скидки (в стандартном магазине это итак реализовано, но тут предлагается и для скидки для конкретной группы)
  • Динамическая цена (?)
  • Блокировка определенного способа оплаты в зависимости от роли
  • Блокировка оплаты товара в зависимости от роли (?)
  • Таблица со списком ролей и цен
  • Сопряжен с переключением валют (Aelia Currency Switcher Integration)
  • Сопряжен с массовым изменением цен (Bulk Price Updater)
  • Сопряжен с плагином WP All Import (можно импортировать цены)

WooCommerce Wholesale Prices (9000)

Предоставляет цену для оптовых покупателей, создавая особую роль Оптовый клиент. В админке: в товаре появляется новое поле — Wholesale Customer, а при выборе товаров колонку с оптовой ценой. В бесплатной версии все настройки заблокированы. Premium версия стоит 59 долларов, расширяет функционал:

  • Оптовые цены в WooCommerce
    Простота управления оптовой ценой по ролям пользователей. Глобальная скидка (%), скидка на категории (%) или индивидуальная оптовая цена.
  • Доставка, Налоговые и платежные шлюзы обрабатываются отдельно
    Назначить способы доставки и оплаты для оптовых клиентов.
  • Настройки каталог для оптовых клиентов
    Создание товаров «Только опт». Скрыть товары «Только розница» от оптовиков. Создание вариаций «Только опт».
  • Правила минимальной покупки
    Обеспечьте предварительную обработку заказа до оптового ценообразования. Минимальное количество товаров, которые нужно заказать. Минимальное количество отдельных товаров.

Woocommerce Role Pricing (1000)

Плагин не создает дополнительного поля цены у товаров. А воздействует глобально на все цены магазина в зависимости от роли.
Настройки метода: Выбираем метод скидки — ставка или количество. Применить для — основная цена или акционная цена. Выбираем — скидки или суммы.

Во вкладке роли выставляем коэффициент скидки для каждой из ролей.

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

Как это исправить:

В файле woocommerce-role-pricing/core/class-woorolepricinglight.php находим строки:

$type = get_option( "wrp-method", "rate" );
$result = 0;
if ($type == "rate") {

И все что идет в фигурных скобках оборачиваем в условие:

if ( $product->is_on_sale() ) {
	
	$result = $product->get_sale_price();						
	
} else {
	
	// if rate and price includes taxes
	if ( $product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes' ) {
		$_tax       = new WC_Tax();
		$tax_rates  = $_tax->get_shop_base_rate( $product->get_tax_class() );
		$taxes      = $_tax->calc_tax( $baseprice, $tax_rates, true );
		$product_price      = $_tax->round( $baseprice - array_sum( $taxes ) );
	}

	$result = self::bcmul($product_price, $commission, WOO_ROLE_PRICING_LIGHT_DECIMALS);

	if ( $product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes' ) {
		$_tax       = new WC_Tax();
		$tax_rates  = $_tax->get_shop_base_rate( $product->get_tax_class() );
		$taxes      = $_tax->calc_tax( $result, $tax_rates, false ); // important false
		$result      = $_tax->round( $result + array_sum( $taxes ) );
	}
	
}

Либо еще один способ исправить то что скидка распространяется и на акционные цены (при том что не должна). В том же файле (woocommerce-role-pricing/core/class-woorolepricinglight.php) в условии (строка 80):

if ( $product->get_sale_price() != $product->get_regular_price() && $product->get_sale_price() == $product_get_price ) {
	
	if ( get_option( "wrp-baseprice", "regular" )=="sale" ) {
		$baseprice = $product->get_sale_price();
	}
	
}

добавляем $commission = 1;

Должно получится так:

if ( $product->get_sale_price() != $product->get_regular_price() && $product->get_sale_price() == $product_get_price ) {
	
	if ( get_option( "wrp-baseprice", "regular" )=="sale" ) {
		$baseprice = $product->get_sale_price();
	}
	
	$commission = 1;
	
}

Исключить из скидки определенную категорию

Т.к. в категорию исключения входят только вариативные товары, то условие еще немного усложняется.

$cart_item_cat_ids = wc_get_product_term_ids( $product->get_parent_id(), 'product_cat' );
if ( $product->is_type( 'variation' ) && $cart_item_cat_ids[0] == 251 ) { // исключение категории Подарочные сертификаты
	$result = $product->get_regular_price();
} else {
	$result = self::bcmul($product_price, $commission, WOO_ROLE_PRICING_LIGHT_DECIMALS);
}

Для простых товаров было бы условие:

$cart_item_cat_ids = wc_get_product_term_ids( $product->get_id(), 'product_cat' );
if ( $cart_item_cat_ids[0] == 251 ) { // исключение категории Подарочные сертификаты
	$result = $product->get_regular_price();
} else {
	$result = self::bcmul($product_price, $commission, WOO_ROLE_PRICING_LIGHT_DECIMALS);
}
Данные условия создают исключения для стоимости товаров в корзине и оформлении, но также нужно изменять функцию вывода цена. она в этом же файле ниже.

Получить коэффициент скидки текущего пользователя

global $current_user;
$user_roles = $current_user->roles;
$user_role = array_shift($user_roles);
if ( !empty($user_role) ){
	$user_discount_value = get_option( "wrp-" . $user_role );
}

Вывод базовой цены в этом плагине предполагается только в Pro версии (19$). Функция по выводу базовой цены:

// Вывести базовую цену
function woocommerce_low_cost() { 
	global $current_user;
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);
	if ( !empty($user_role) ){
	if ( $user_role != 'administrator' ){
		global $product;
		if ( !$product->is_on_sale() ){
			echo '';
			echo $product->get_regular_price();
			echo '';
		}
	}
	}
};
add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_low_cost', 15 );

Функция по выводу разницы «Ваша скидка» + вывод в карточке товара:

// Вывести базовую цену
function woocommerce_low_cost() { 
	global $current_user;
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);
	if ( !empty($user_role) ){
		global $product;
		if ( !$product->is_on_sale() ){
			echo '<small class="role-sale">Скидка: ';
			$skidka = $product->get_regular_price() - $product->get_price();
			echo $skidka;
			echo ' руб.</small>';
		}
	}
};
add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_low_cost', 15 );
add_action( 'woocommerce_single_product_summary', 'woocommerce_low_cost', 15 );

Вычисляем общую сумму без скидки (этот код я вставляю напрямую в шаблон woocommerce/cart/cart-totals.php):

cart->get_cart() as $cart_item_key => $cart_item ) {
		$_product   = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
		$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
			
		if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
			$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
	
			$is_on_sale = $cart_item[data]->sale_price;
			if ( !empty($is_on_sale) ){
				$proprice = $cart_item[data]->sale_price;
				$proqt = $cart_item['quantity'];
			} else {
				$proprice = $cart_item[data]->regular_price;
				$proqt = $cart_item['quantity'];
			}
			$prototal[] = $proprice * $proqt;
		}
	}
	global $woocommerce;
	$basetotal = $woocommerce->cart->get_cart_total();
	$basetotalnum = preg_replace("/[^0-9]/", '', $basetotal);
	$total_role_sale = array_sum($prototal) - $basetotalnum;
	echo '<p class="role-sale">Ваша скидка: ' .$total_role_sale. ' р.</p>';
?>
preg_replace(«/[^0-9]/», », $basetotal); — php функция отбора из переменной только числовых значений

Либо можно сделать более универсально — функцией добавляющей данный расчет в нужные места Woocommerce

function woocommerce_low_cost_total() { 
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
		$_product   = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
		$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
			
		if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
			$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
	
			$is_on_sale = $cart_item[data]->sale_price;
			if ( !empty($is_on_sale) ){
				$proprice = $cart_item[data]->sale_price;
				$proqt = $cart_item['quantity'];
			} else {
				$proprice = $cart_item[data]->regular_price;
				$proqt = $cart_item['quantity'];
			}
			$prototal[] = $proprice * $proqt;
		}
	}
	global $woocommerce;
	$basetotal = $woocommerce->cart->get_cart_total();
	$basetotalnum = preg_replace("/[^0-9]/", '', $basetotal);
	$total_role_sale = array_sum($prototal) - $basetotalnum;
	echo '<p class="role-sale">Ваша скидка: ' .$total_role_sale. ' р.</p>';
}

add_action( 'woocommerce_widget_shopping_cart_before_buttons', 'woocommerce_low_cost_total', 15 ); // в миникорзину
add_action( 'woocommerce_cart_totals_after_order_total', 'woocommerce_low_cost_total', 15 ); // в корзину

И отдельная функция для шаблона оформления:

function woocommerce_low_cost_total_tr() { 
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
		$_product   = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
		$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
			
		if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
			$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
	
			$is_on_sale = $cart_item[data]->sale_price;
			if ( !empty($is_on_sale) ){
				$proprice = $cart_item[data]->sale_price;
				$proqt = $cart_item['quantity'];
			} else {
				$proprice = $cart_item[data]->regular_price;
				$proqt = $cart_item['quantity'];
			}
			$prototal[] = $proprice * $proqt;
		}
	}
	global $woocommerce;
	$basetotal = $woocommerce->cart->get_cart_total();
	$basetotalnum = preg_replace("/[^0-9]/", '', $basetotal);
	$total_role_sale = array_sum($prototal) - $basetotalnum;
	echo '<p class="role-sale">Ваша скидка: ' .$total_role_sale. ' р.</p>';
}
add_action( 'woocommerce_review_order_after_order_total', 'woocommerce_low_cost_total_tr', 15 ); // в шаблон оформления

Вывод общих скидок с купонами

Еще одна функция вывода данных в корзине вместе с суммой за купоны

function woocommerce_low_cost_total() {
	
	global $woocommerce;
	global $current_user;
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);
	if ( !empty($user_role) ){
		
		$value_discount_option = get_option( "wrp-" . $user_role );
		
		$coupons = WC()->cart->get_applied_coupons();
		
		foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
			$_product   = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );

			if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {

				if ( $_product->is_on_sale() ){	
					$proprice = $cart_item[data]->get_sale_price();
					$proqt = $cart_item['quantity'];
					$club_sale = 0;
				} else {
					$proprice = $cart_item[data]->get_regular_price();
					$proqt = $cart_item['quantity'];
					$club_sale = $proprice * $value_discount_option;
				}

				$prototal[] = $proprice * $proqt;
				$club_sale_total[] = $club_sale * $proqt;

			}
		}	

		echo '<p class="total-product-price total-product-price-first">Итого без клубной скидки: <strong>' .number_format(array_sum($prototal), 0, '', ' '). ' р.</strong></p>';	
		echo '<p class="role-sale">Ваша клубная скидка: <strong>' .number_format(array_sum($club_sale_total), 0, '', ' '). ' р.</strong></p>';
		if (!empty($coupons)) { echo '<p class="role-sale">Скидка по промокодам: <strong>' .$woocommerce->cart->get_cart_discount_total(). ' р.</strong></p>'; }
		echo '<p class="total-product-price total-product-price-last">Итого со скидкой: <strong>' .$woocommerce->cart->get_cart_total(). '</strong></p>';	
		
	} else {
		echo '<p class="total-product-price total-product-price-last">Итого: <strong>' .$woocommerce->cart->get_cart_total(). '</strong></p>';
	}

}

add_action( 'woocommerce_widget_shopping_cart_before_buttons', 'woocommerce_low_cost_total', 15 ); // в миникорзину
add_action( 'woocommerce_cart_totals_after_order_total', 'woocommerce_low_cost_total', 15 ); // в корзину

И в шаблоне оформления

function woocommerce_low_cost_total_tr() { 
	
	global $woocommerce;
	global $current_user;
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);
	if ( !empty($user_role) ){
		
		$value_discount_option = get_option( "wrp-" . $user_role );	
		
		$coupons = WC()->cart->get_applied_coupons();
	
		foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
			$_product   = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );

			if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {

				if ( $_product->is_on_sale() ){
					$proprice = $cart_item[data]->get_sale_price();
					$proqt = $cart_item['quantity'];
					$club_sale = 0;

				} else {
					$proprice = $cart_item[data]->get_regular_price();
					$proqt = $cart_item['quantity'];
					$club_sale = $proprice * $value_discount_option;
				}

				$prototal[] = $proprice * $proqt;
				$club_sale_total[] = $club_sale * $proqt;

			}
		}

		echo '<tr><td class="total-product-price total-product-price-first" colspan="2">Итого без скидок: <strong>' .array_sum($prototal). ' р.</strong></td></tr>';
		echo '<tr><td class="total-product-price role-sale" colspan="2">Ваша клубная скидка: <strong>' .array_sum($club_sale_total). ' р.</strong></td></tr>';
		if (!empty($coupons)) { echo '<tr><td class="total-product-price role-sale" colspan="2">Скидка по промокодам: <strong>' .$woocommerce->cart->get_cart_discount_total(). ' р.</strong></td></tr>'; }
		echo '<tr><td class="total-product-price total-product-price-last" colspan="2">Итого со всеми скидками: <strong>' .$woocommerce->cart->get_cart_total(). '</strong></td></tr>';	
		
	} else {
		echo '<tr><td class="total-product-price total-product-price-last" colspan="2">Итого: <strong>' .$woocommerce->cart->get_cart_total(). '</strong></td></tr>';
	}
}

add_action( 'woocommerce_review_order_before_shipping', 'woocommerce_low_cost_total_tr', 15 ); // в оформление

Если нужно сделать исключение вывода скидки по категории, то дополняем эту часть в обоих скриптах (для корзины и для оформления):

$cart_item_cat_ids = wc_get_product_term_ids( $cart_item['product_id'], 'product_cat' );

if ( $_product->is_on_sale() ){
	$proprice = $cart_item[data]->get_sale_price();
	$proqt = $cart_item['quantity'];
	$club_sale = 0;

} else {
	$proprice = $cart_item[data]->get_regular_price();
	$proqt = $cart_item['quantity'];
	if ( $cart_item_cat_ids[0] != 251 ) { $club_sale = $proprice * $value_discount_option; } //исключая категорию Подарочные сертификаты
}

$prototal[] = $proprice * $proqt;
$club_sale_total[] = $club_sale * $proqt;

Другие плагины

Есть еще два полностью платных плагина по данной тематике — YITH Woocommerce Role Based Prices (60$) и Prices By User Role for WooCommerce (44$), но я их не тестировал.

Удалось попробовать плагин YITH Woocommerce Role Based Prices принцип его работы больше напоминает функционал Woocommerce Role Pricing, но с более гибкими настройками (скидки/наценки в виде процентов или количества к каждому товару или глобально).

Протестировал и плагин Prices By User Role for WooCommerce. Данный плагин дает возможность различных манипуляций с ценой и товаром в зависимости от роли: скрытие цены, скрытие товаров, скидка (% или руб) для групп. Но индивидульную цену на каждый товар этот плагин не поддерживает.

Price based on User Role for WooCommerce

Нашел еще один плагин, менее популярный чем предыдущие (700+), но дающий неплохой функционал по установке цен на каждый товар в зависимости от роли — Price based on User Role for WooCommerce. И при соответствующей доработке, этим плагином можно решать некоторые задачи. Выгодным отличием от WC Role Based Price (по крайней мере его бесплатной версии, платную не использовал) является структура хранения цен в метаполях. В этом смысле даже у плагина считаю перебор, т.к. он для каждой роли создает аж по три метаполя.

Перечислю тезисно что входит в функционал плагина:

  • Массовые правила для групп. Реализовано в виде коэффициента.
  • Цена в зависимости от роли для каждого товара.
  • Выбор набора ролей, которые будут выводится в товаре для назначения цен.
  • Скрыть цены либо глобально для роли, либо индивидуально для любого товара в зависимости от роли.
  • Поля доступны для массового редактирования в Advanced Bulk Edit.
  • Поля доступны для экспорта / импорта.
  • Поддержка вариаций.

И теперь о плохом, в бесплатной версии плагина допускается создание всего одного товара с ценами для ролей, видимо только для тестирования. Pro версия стоит 20$ (10.01.2019).

Поделиться в соц. сетях:

  • Похожие записи
  • Комментарии
  • Вложения
Быстрый просмотр товара без плагина

Быстрый просмотр товара без плагина

В одной из предыдущих статей мы научились вызывать ajax’ом содержимое записи. Теперь настроим и доработаем данный функционал для товаров woocommerce. Создание функционала Техническая часть (скрипты, стили) остается той же что Читать далее »

Запись на прием

Запись на прием

Внедряем в сайт функционал записи на прием. Данная возможность может пригодится в медицинской сфере, а также в сфере образования (репетиторство). Плагин Booked Appointments Плагин платный (59 $), но если хорошо Читать далее »

/
Плагин: Миниатюра таксономии

Плагин: Миниатюра таксономии

Обычно для добавления изображения (миниатюры) таксономии импользую плагин Advanced Custom Fields. Плагин хороший, но довольно тяжеловат, т.к. является мощным многозадачным плагином. Есть более легковесная альтернатива — плагин taxonomy term image Читать далее »

/

Добавить комментарий

3 комментария

  1. Сергей

    Хорошая работа, при использовании вашего кода:
    // Вывести базовую цену
    function woocommerce_low_cost() {
    global $current_user;
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);
    if ( !empty($user_role) ){
    global $product;
    if ( !$product->is_on_sale() ){
    echo '<small class="role-sale">Скидка: ';
    $skidka = $product->get_regular_price() - $product->get_price();
    echo $skidka;
    echo ' руб.</small>';
    }
    }
    };
    add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_low_cost', 15 );
    add_action( 'woocommerce_single_product_summary', 'woocommerce_low_cost', 15 );

    При singl продукте все работает, при вариативном товаре , при условии что у каждой вариации своя цена этот код не работает. получается вот так
    Warning: A non-numeric value encountered in ….вот на эту строку ругается: $skidka = $product->get_regular_price() — $product->get_price();Дело в том что так как разная цена, то пишется  цена от 100-300, и поэтому наверное не получается правильно посчитать. Как изменить формулу чтоб вчитывалось из цены конкретно выбранной вариации. 

  2. Ольга

    Возможно, вопрос не совсем по этой теме, но связан с ролями и заказами..
    При помощи какого плагина  ограничивать число покупок товаров определенных категорий в Woocommerce + ограничивать период этих покупок? Например, покупка членства…. При этом оплата членства была бы как кошелек, с которого бы списывались оплаты за эти покупки? например, оплачиваешь членство на 20$ и тебе доступно 10 товаров по 2$  (товары будут иметь одинаковую стоимость)

    1. Alexandr

      Подобный функционал самому делать не доводилось. Возможно стоит начать с плагина WooCommerce Memberships или ему подобных.

Цены в зависимости от группы пользователей Цены в зависимости от группы пользователей Цены в зависимости от группы пользователей
Добавим опции к сайту
Рекомендации для васДобавим опции к сайтуOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.