Добавление к товару дополнительной услуги влияющей на цену.

01.11.2012
Клиенту потребовалось возможность, что бы несколько товаров, в одной из категорий можно было продавать с упаковкой и без нее.
Вариант сделать по два товара (обычный и с упаковкой) не подходил.

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

Начал с того, что добавил нужным товарам выпадающий список (с вариантами покупки).
Для этого в файле:
/administrator/components/com_virtuemart/classes/ps_product_attribute.php
В функции show_quantity_box
до

return $html;

подключил файл с классом, создал объект $oOddHelper и добавил:

$html .= $oOddHelper->getExtPrice($prod_id);

Код для метода getExtPrice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    /**
     * Выводит селект "Цена упаковки"
     * Только для категории цветы
     * @param int $id - ИД товара
     * @return string
    */
    function getExtPrice($id)
    {
      $category_id = JRequest::getString('category_id');
      $sRet = '';
        $iTax = 0;
        if ($category_id == 11) // Если это цветы
        {
          switch ($id)
          {
            case 173:  // Цветы №1
              $iTax = 240;
            break;

            case 172:  // Цветы №2
              $iTax = 260;
            break;

            default:  // Все остальные
               $iTax = 200;
            break;
          }
        }

        if ($iTax)
        {
          $sRet .= <<<EOD
<br/><b>Цена упаковки</b>:
<select id="ext_price_$id" class="ext_price" name="ext_price" shop_id="$id">
    <option value='$iTax' selected="selected"> Упаковать (+ $iTax.00руб.)</option>
    <option value='0'>без упаковки</option>
</select><br/>
EOD;
        }
      return $sRet;
    }

Следующая мысль была добавить дополнительное поле к товарам, лежащим в корзине (таблица _vm_order_item).
Но тут выяснилось, что до оформления заказа информация о оваре в базу не помещается, и все манипуляции с ней происходят через PHP сессии.

Но все по порядку. Сначала нужно обработать и запомнить выбор пользователя.
В файле
/administrator/components/com_virtuemart/classes/ps_cart.php
Нужны два метода add и update

Для add находим

$_SESSION['cart'][$k]["quantity"] = $quantity;
$_SESSION['cart'][$k]["product_id"] = $product_id;
$_SESSION['cart'][$k]["parent_id"] = $e["product_id"];

и добавляем

$_SESSION['cart'][$k]["ext_price"] = $e["ext_price"];

Для update после кода

$_SESSION['cart'][$i]["quantity"] = $quantity;

Добавляем:

$_SESSION['cart'][$i]["ext_price"] = $d["ext_price"];

Дальше пришлось протащить дополнительную цену за собой через скрытые поля.
В файле
/administrator/components/com_virtuemart/html/basket.php
Ищем

$product_price = round( $product_price, 2 );

И перед ним вставляем

$product_price = $product_price + $cart[$i]['ext_price'];

Ниже ищем

$product_rows[$i]['update_form'] = '<form action="'

Нужно среди всех полей добавить и свое

<input type="hidden" name="ext_price" value="'. $_SESSION['cart'][$i]["ext_price"] .'" />

Тоже самое нужно сделать и после

$product_rows[$i]['delete_form'] = '<form action=" 

Переходим к файлу
/administrator/components/com_virtuemart/html/ro_basket.php
Нам обязательно нужно добавить 'ext_price' на форму «подтвердить заказ»
Находим начало цикла

for ($i=0;$i<$cart["idx"];$i++) {

До него добавляем:

global $extra_info;
$extra_info = '';

- не люблю глобальные переменные, надеюсь, выберу время все это переписать!
Ниже находим

$product_price = round( $product_price, 5 );

и до него пишем:

$product_price = $product_price + $cart[$i]['ext_price'];

Еще ниже находим, уже знакомые

$product_rows[$i]['update_form'] =

и

$product_rows[$i]['delete_form'] =

В список полей каждой нужно добавить

<input type=\"hidden\" name=\"ext_price\" value=\"". $_SESSION['cart'][$i]["ext_price"] ."\" />

- в этом месте кавычки нужно экранировать или использовать одинарные.

Теперь выводим дополнительное поле на форме.
Открываем
/components/com_virtuemart/themes/default/templates/checkout/get_final_confirmation.tpl.php
После

echo $basket_html;

Пишем:

global $extra_info;
echo $extra_info; 

Осталось сделать, что бы дополнительная цена добавлялась в заказ (уже в БД, почтовое уведомление и т.д.).
/administrator/components/com_virtuemart/classes/ps_checkout.php
Нас интересует метод add
Находим

$product_final_price = 

заменяем эту строчку на

$ext_price = isset($_REQUEST['ext_price_'.$cart[$i]["product_id"]])?$_REQUEST['ext_price_'.$cart[$i]["product_id"]]:0;
$product_final_price = $ext_price + round( ($product_price *($my_taxrate+1)), 2 );

Ниже находим

$fields = array('order_id' => $order_id,

И среди параметров добавляем

'ext_price' => $ext_price,

- теперь к конечной цене товара будет добавлена наша наценка.

В этом же файле нужно еще поправить несколько мест:

  1. Метод calc_order_subtotal

    В нем есть условие

    if( $auth["show_price_including_tax"] == 1 ) {

    до него добавляем

    $ext_price = $cart[$i]['ext_price'];

    А в нутрии условия и в ветке else меняем

    $product_price = round( ($product_price *($my_taxrate+1)), 2 );

    на

    $product_price = round( ($ext_price + $product_price *($my_taxrate+1)), 2 ); 

  2. Метод calc_order_taxable

    Изменяем строчку

    $subtotal += ($product_price) * $cart[$i]["quantity"];

    на

    $subtotal += ($cart[$i]["ext_price"] + $product_price) * $cart[$i]["quantity"]; 


Категории: VirtueMart 1.X
Яндекс.Метрика