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 сама по себе или нужны дополнительные манипуляции?
В документации прямого вызова не нашёл.

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

Привет!
надо изменить стоимость каждой позиции. делаю так

  $line_wrapper->commerce_unit_price->amount = $price_in_kop;
  $line_wrapper->commerce_unit_price->data = commerce_price_component_add(
    $price_in_kop,
    'base_price',
    array(
      'amount' => $price_in_kop,
      'currency_code' => 'RUB',
      'data' => array(),
    ),
    TRUE
  );

В $line все норм, но не считается сумма заказа http://i.imgur.com/qTLNxcN.png

Её нельзя автоматом подсчитывать?

Это не совсем скида или наценка. Цена зависит от разных мест (даже от значения элементов самой страницы), Т.е. нет какого-то одного правила.
Вообще я делаю форму заказа в один клик и в form_submit делаю вручную заказ. В нем делаю товар. В общем надо будет $order_wrapper->commerce_order_total установить самому?

Только почему так не помогает?

  $order_wrapper->commerce_order_total->amount = $price_in_kop;
  $order_wrapper->commerce_order_total->data = commerce_price_component_add(
    $price_in_kop,
    'base_price',
    array(
      'amount' => $price_in_kop,
      'currency_code' => 'RUB',
      'data' => array(),
    ),
    TRUE
  );

В общем изначально не правильно понимал суть компонентов ))

в итоге получилось так:

  $line_item = commerce_product_line_item_new($product, $quantity, $order->order_id);
 
  $line_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
  // Устонавливаем цену товара
  $origin_price = $line_wrapper->commerce_unit_price->value()[amount];
  // Высчитываем разницу, чтобы сделать наценку к текущей цене.
  // (чтобы считались верно сумма заказа и т.п.)
  $fee = $price_in_kop - $origin_price;
 
  $base_price = array(
    'amount' => $fee,
    'currency_code' => 'RUB',
    'data' => array(),
  );
 
  $line_wrapper->commerce_unit_price->amount = $price_in_kop;
  $line_wrapper->commerce_unit_price->data = commerce_price_component_add(
    $line_wrapper->commerce_unit_price->value(),
    'base_price',
    $base_price,
    TRUE
  );
 
  $line_wrapper->field_paint_size->set($paint_size);
  $line_wrapper->field_paint_frame->set($paint_frame);
  $line_wrapper->save();
 
  commerce_line_item_save($line_item);

Стояла задача сделать динамический расчет стоимости доставки на странице
checkout в зависимости от того какая страна била вибрана пользователем в поле
сгенерированим модулем addressfield
Сделал так:
http://pastebin.com/CYxDNxfQ

Бил би рад если етот комертарий отнести в отдельний пост, может кому то пригодиться
Извиняюсь за такой русский, лень переключать

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

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

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