xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Программно добавить скидку к заказу

Опубликовано в

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

Пример добавления скидки в 500 руб. для заказов с числом товаров больше 5:

/**
 * Implements hook_commerce_order_presave().
 */
function MODULENAME_commerce_order_presave($order) {
  $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
  $line_items_quantity = commerce_line_items_quantity($order_wrapper->commerce_line_items, commerce_product_line_item_types());
 
  if ($line_items_quantity > 5) {
    $discount_decimal = 500;
    $discount_currency_code = 'RUB';
 
    $order_total = $order_wrapper->commerce_order_total->value();
    $discount_amount = commerce_currency_decimal_to_amount($discount_decimal, $discount_currency_code);
    $discount_amount = commerce_currency_convert($discount_amount, $discount_currency_code, $order_total['currency_code']);
 
    $order_wrapper->commerce_order_total->amount = $order_total['amount'] - $discount_amount;
    $order_wrapper->commerce_order_total->data = commerce_price_component_add($order_total, 'discount', array(
      'amount' => $discount_amount,
      'currency_code' => $order_total['currency_code'],
      'data' => array(),
    ), TRUE);
  }
}
Написанное актуально для Commerce 1
Похожие записи

Комментарии RSS

как сделать что бы скидка срабатывала только определенных товаров?

xandeadx, может вы подскажите, как реализовать подобное вне хука commerce_order_presave()? Дело в том, что этот хук срабатывает ДО того как пользователь заполнит форму на странице checkout, а мне надо чтобы срабатывало ПОСЛЕ, по нажатию кнопки submit. Навешиваю на кнопку свой обработчик, пишу аналогичный код, но не работает.

function commerce_my_checkout_mysubmit(&$form, &$form_state) {
  $order = commerce_order_load($form_state['order']->order_id);
  $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
  $line_items_quantity = commerce_line_items_quantity($order_wrapper->commerce_line_items, commerce_product_line_item_types());
 
  if ($line_items_quantity > 5) {
    $discount_decimal = 500;
    $discount_currency_code = 'RUB';
 
    $order_total = $order_wrapper->commerce_order_total->value();
    $discount_amount = commerce_currency_decimal_to_amount($discount_decimal, $discount_currency_code);
    $discount_amount = commerce_currency_convert($discount_amount, $discount_currency_code, $order_total['currency_code']);
 
    $order_wrapper->commerce_order_total->amount = $order_total['amount'] - $discount_amount;
    $order_wrapper->commerce_order_total->data = commerce_price_component_add($order_total, 'discount', array(
      'amount' => $discount_amount,
      'currency_code' => $order_total['currency_code'],
      'data' => array(),
    ), TRUE);
  }
}

просто выполните в нужный момент commerce_cart_order_refresh($order), функция запустит hook_commerce_order_presave.

xandeadx, добрый день, делаю функционал динамического увеличения стоимости заказа на определённую сумму, которую получаю от стороннего API. сумму передаю в _presave() доп.переменной.

кажется, я не совсем понял ваш последний комментарий о commerce_cart_order_refresh($order)

делаю как-то так:

function ajaxcartrefresh_menu(){
	$items = array();
		$items['ajax/change-cart/%/%'] = array(
			'page callback' => 'ajaxcartrefresh_updater',
			'page arguments' => array(2,3),
			'type' => MENU_CALLBACK,
			'access arguments' => array('access content'),  
		);
	return $items;
}
 
function ajaxcartrefresh_updater($order,$summ){
	commerce_cart_order_refresh($order); //dafuq!
}
 
function ajaxcartrefresh_commerce_order_presave($order,$summ) {
	$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
	$line_items_quantity = commerce_line_items_quantity($order_wrapper->commerce_line_items, commerce_product_line_item_types());
 
	$discount_decimal = $summ;
	$discount_currency_code = 'RUB';
 
	$order_total = $order_wrapper->commerce_order_total->value();
	$discount_amount = commerce_currency_decimal_to_amount($discount_decimal, $discount_currency_code);
	$discount_amount = commerce_currency_convert($discount_amount, $discount_currency_code, $order_total['currency_code']);
 
	$order_wrapper->commerce_order_total->amount = $order_total['amount'] + $discount_amount;
	$order_wrapper->commerce_order_total->data = commerce_price_component_add($order_total, 'fee', array(
	  'amount' => $discount_amount,
	  'currency_code' => $order_total['currency_code'],
	  'data' => array(),
	),

Боль : когда перехожу по адресу, например mysite.com/ajax/change-cart/11/250, итоговая стоимость заказа не меняется
Вопрос : когда запускать card_order_refresh и как через него передать переменную $summ в _presave?

Сапсибо

сделайте $summ глобальной переменной

Да, спасибо!

Остался только вопрос по commerce_cart_order_refresh — вызывает ли она _commerce_order_presave сама по себе или нужны дополнительные манипуляции?
В документации прямого вызова не нашёл.

как писал выше - вызывает сама

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании