Умножаем цену ubercart на заданный курс в админке (модуль)

Главные вкладки

Аватар пользователя mozh mozh 14 ноября 2014 в 12:05

Всем привет, долго лазил по форуму в поисках решения, но подходящего так и не было найдено. В итоге было решено написать свой первый модуль на Drupal 7 (год сижу на нем и только сейчас возникла потребность в модуле).
И так задача: есть магазин на ubercart, цены для товаров задаются в у.е - нужно выводить цены умноженные на курс, который задаем в админке, причем цены должны пересчитываться везде: корзина, заказ, страница товара, каталог товара сделанный с помощью views.
Пишем модуль с одним единственным полем, которое будет принимать наше значение курса (функции помечены краткими комментариями):

<?php
/**
 * Implements hook_menu(). Добавляем ссылку модуля в меню "конфигурация"
 */
function course_menu() {
  
$items = array();

  

$items['admin/config/course'] = array(
    
'title' => 'Current course',
    
'description' => 'Configuration for Current course module',
    
'page callback' => 'drupal_get_form',
    
'page arguments' => array('course_form'),
    
'access arguments' => array('access course content'),
    
'type' => MENU_NORMAL_ITEM,
  );

  return 

$items;
}

/**
 * Page callback: Current posts settings. Создаем форму для ввода значения
 */
function course_form($form, &$form_state) {
  
$form['course'] = array(
    
'#type' => 'textfield',
    
'#title' => t('Course USD'),
    
'#default_value' => variable_get('course'),
    
'#size' => 20,
    
'#maxlength' => 100,
    
'#description' => t('Current course USD to BLR'),
    
'#required' => TRUE,
  );

  return 

system_settings_form($form);
}

/**
 * Implements validation from the Form API. Проверка валидности ввода значения
 */
function course_form_validate($form, &$form_state){
  
$course $form_state['values']['course'];
  if (!
is_numeric($course)){
    
form_set_error('course't('You must enter a number.'));
  }
  elseif (
$course <= 0){
    
form_set_error('course't('Course number must be positive.'));
  }
}

/**
 * Implements hook_permission(). Доступ к модулю.(можно не реализовывать)
 */
function course_permission() {
  return array(
    
'access course content' => array(
      
'title' => t('Access content for the Current course module'),
    )
  );
}

/**
 * Implements hook_uc_product_alter(). И вот самый главный хук от уберкарта, который будет домнажать нашу цену на значение курса, при выводе
 */
function course_uc_product_alter(&$node) {
  
$node->price *= variable_get('course');
}
?>

Готовый модуль прикреплен. Готов выслушать замечания.
Но теперь вроде как все хорошо, но если у вас переопределен node.tpl для product (т.е. есть файл в теме node--product.tpl.php) и вы там выводите каким-то боком значение цен, то необходимо их вручную домножить вот так:

<div class="content"<?php print $content_attributes; ?>>
        <div class="hide-price">
    <?php
     // We hide the comments and links now so that we can render them later.
     hide($content['comments']);
     hide($content['links']);
          hide($content['add_to_cart']);
          hide($content['sell_price']);
          hide($content['cost']);
               
     print render($content);
   ?>
        </div>
        <?php
        $cost = $node->cost;
        if($cost !=0){ ?>
        <div class="product-info cost uc-product-<?php print $node->nid; ?>">
                <span class="uc-price-label">Старая цена:</span>
                <span class="uc-price"><?php print uc_currency_format($node->cost*= variable_get('course')); ?></span></div>
        </div>
        <?php }
        if($node->sell_price!=0){
        ?>
        <div class="product-info sell-price <?php if($cost !=0) echo 'sell-prices'; ?>">
                <span class="uc-price-label">Цена:</span>
                <span class="uc-price"><?php print uc_currency_format($node->sell_price*= variable_get('course')); ?></span>
        </div>
        <?php } ?>
        <?php print render($content['add_to_cart']); ?>
  <?php print render($content['links']); ?>
  <?php print render($content['comments']); ?>

Как видно из кода, мы вначале скрываем из вывода наши цены hide($content['sell_price']);hide($content['cost']); а затем их выводим, определяя им стиль и условия вывода (если ноль, то не выводим его) Стиль предназначен для вывода перечеркнутой цены и новой красного цвета. Либо просто одной цены серого цвета (css думаю сами набросаете).
Далее проблема есть со views, там также не хочет пересчитываться цена, поэтому необходимо установить модуль для типа поля Глобальный php

Код для поля Глобальный php может быть сокращен до одной строки отмеченной справа стрелкой

<?php
echo uc_currency_format($row->sell_price *= variable_get('course'));?>

Результат views:

Результат корзина (бел. руб.):

Первоначальная цена будет отображаться только при редактировании товара:

Кстате я поставил руб, что бы на сайте было ок, хотя при редактировании это есть у.е., но это видит только админ так что неважно.

Замечена проблема с фильтром по цене "Между" он не работает, переданные значения в фильтр нужно также домнажать. Чуть позже постараюсь сделать в виде слайдера и отписать здесь.

Модуль прикреплен, перед заливкой переименовал его (course => uc_course), должен работать.

ВложениеРазмер
Иконка пакета uc_course.zip1.23 КБ

Комментарии

Аватар пользователя mozh mozh 15 ноября 2014 в 23:20

"ХулиGUN" wrote:
Не проще ли сделать свой форматтер и/или хендлер, раз это модуль?

хм, а можно поподробнее, не знаком с этими понятиями.
"ХулиGUN" wrote:
И текущий курс не вручную записывать, а тянуть с сервиса банка?

гибкость решения, заказчик хочет задавать свой курс