English (United Kingdom)Russian (CIS)
Доработка VirtueMart 1.1.X. "Скидка постоянным клиентам"


С обственно задача:
я покупателям делаю скидку со 2 заказ 5 % с 6 заказа - 7% с 10 и все последующие 10%. Вот надо чтобы это все автоматически считалось в личном кабинете покупателя. при этом скидка должна считаться от суммы покупки без учета стоимости доставки. И при этом скидка должна считаться только тогда когда в предыдущем заказе статус меняется например на заказ оплачен. покупатели у себя в кабинете смогут видеть сколько у них уже было заказов и какая им скидка полагается, а да еще забыла, на категорию распродажа скидки не должны распространяться.


В целом, задача не сложная и при быстром подходе решается за 2-3 часа. Но мы не будем искать легких путей, и полноценно интегрируем функционал таких скидок в VirtueMart. В результате в магазине появится новый раздел, где можно будет создавать и менять сами скидки.



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

Аналогичным образом решаются задачи по скидке от суммы заказа, от реферальной ссылки, от разных городов и т.д.

С обственно решение:

1. Для начала зайдем в phpMyAdmin и создадим таблицу jos_vm_castom1 в базе данных. Тут мы будем хранить информацию про наши скидки. Заодно добавим поле castom1_discount в таблицу jos_vm_orders. В этой таблице хранится информация о проведенных сделках, а мы запишем в нее нашу скидку, текущую на момент покупки. Не забываем про префиксы.

 
 CREATE TABLE IF NOT EXISTS `jos_vm_castom1` (
  `castom1_id` int(11) NOT NULL auto_increment,
  `castom1_val` int(11) default NULL ,
  `publish` int(1)  default NULL ,
  `castom1_from` int(11) default NULL ,
  `castom1_category` varchar(128) NOT NULL default '',
  PRIMARY KEY  (`castom1_id`)
)
 


 
 ALTER TABLE `jos_vm_orders` ADD `castom1_discount` varchar(50) NOT NULL default ''
 


2. Добавим языковые значения в файл /administrator/components/com_virtuemart/languages/common/russian.php. То-же самое нужно проделать для всех установленных в магазине языков:

 
  'PHPSHOP_CASTOM1_FORM_MNU' => 'Скидки для постоянных клиентов',
  'PHPSHOP_CASTOM1_TIP' => 'Введите через запятую id категорий, в которых скидка не будет начисляться. Скидка не будет начисляться и в дочерних категориях.',
  'PHPSHOP_CASTOM1_QUANTITY' => 'Количество необходимых сделок',
  'PHPSHOP_CASTOM1_CATEGORIES' => 'Исключенные категории',
  'PHPSHOP_CASTOM1_YOO' => 'Ваша скидка',
  'PHPSHOP_CASTOM1_YOO2' => 'Скидка постоянного пользователя',
  'PHPSHOP_CASTOM1_TITLE' => 'Наш магазин делает скидки постоянным покупателям. Вы сделали',
  'PHPSHOP_CASTOM1_N' => 'покупок',
 


3. Теперь добавим в админку магазина ссылку на управление нашими скидками. Она помечена желтым маркером на скриншотах. Для этого откроем файл /administrator/components/com_virtuemart/header.php и вставим в меню блок кода:

 
          <li class="item-smenu vmicon vmicon-16-content">
           <a href="<?php $sess->purl($_SERVER['PHP_SELF']."?pshop_mode=admin&page=admin.castom1_list") ?>"><?php echo $VM_LANG->_('PHPSHOP_CASTOM1_FORM_MNU') ?></a>
          <hr />  
          </li>
 
 

Это нужно сделать, примерно, ниже 303 строки, впрочем большого значения никакого нет. Теперь у нас появилась ссылка в меню, но нажимать на нее пока не стоит. Вначале нужно создать файлы, которые будут формировать страницы, как на скриншотах. Таких файлов будет три:

4.Создадим файлы
/administrator/components/com_virtuemart/classes/ps_castom1.php
/administrator/components/com_virtuemart/html/admin.castom1_form.php
/administrator/components/com_virtuemart/html/admin.castom1_list.php

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

Скачать архив с файлами ps_castom1.php, admin.castom1_form.php, admin.castom1_list.php    


5. Теперь мы имеем почти работающую амин-часть функционала. Осталось только добавить кнопку для удаления скидок. Для этого в файле /administrator/components/com_virtuemart/toolbar.virtuemart.php вставим, примерно после 53 строки

 
  "admin.castom1_list" => "castom1Delete",
 


6. Последнее, что нужно для того, чтобы админка заработала - это прописать новые функции castom1Delete, Castom1Update, Castom1Add.
Для этого открываем в меню virtuemart пункт Список модулей. Напротив пункта admin открываем Список функций. Нажимаем кнопку "Новый"

имя функции: castom1Delete
Имя класса: ps_castom1
Метод класса: delete
Права на функцию: admin, storeadmin

Аналогично прописываем две другие функции - Castom1Update и Castom1Add.

7. Теперь можно заняться реализацией наших скидок в корзине, письмах и отчетах.
В начале добавим две функции в класс ps_product. Позже мы легко сможем их вызвать там где нам нужно. Это функция, определяющая, находится ли данный продукт в запрешенной категории или нет. И ее вспомогательная функция, определяющая все дочерние категории, которые идут от запрещенных. Откроем файл /administrator/components/com_virtuemart/classes/ps_product.php и в самом низу класса добавим перед закрывающей класс скобкой две функции:

 
//    Скидка постоянным пользователям. Проверка запрещенных категорий.
    function get_castom1_rate($product_id,$castom1_categories) {
 
      if(!$castom1_categories)return TRUE;
      $castom1_categories=$this->get_castom1_categories_child($castom1_categories);
 
      $db = new ps_DB;
      $count = "SELECT COUNT(*) as num_rows FROM #__k2_items WHERE id=(SELECT itemID FROM #__k2mart WHERE productID=" . (int)$product_id.") AND catid IN($castom1_categories)";
      $db->query($count);
      $db->next_record();
      if( $db->f('num_rows')) return FALSE;
 
      return TRUE;
    }
 
//    Получим все дочерние категории от запрещенных
    function get_castom1_categories_child($castom1_categories) {
 
      $db = new ps_DB;
      $ret = $castom1_categories;
 
      while($castom1_categories){
        $catid = array();
        $q = "SELECT id FROM #__k2_categories WHERE parent IN($castom1_categories)";
        $db->query($q);
        while($db->next_record()){
          $catid[]=$db->f('id');
        }
        $castom1_categories=implode(',',$catid);
        if($castom1_categories)$ret .=','.$castom1_categories;
      }
      return $ret;
    }
 
 


Поскольку в моем случае магазин был собран на связке К2 + VirtueMart, то мне пришлось получать категории из К2. В случае VirtueMart все еще проще.

Если использовать категории VirtueMart, то эти функции будут такими

 
//    Скидка постоянным пользователям. Проверка запрещенных категорий.
    function get_castom1_rate($product_id,$castom1_categories) {
      if(!$castom1_categories) return TRUE;
 
      require_once (CLASSPATH."ps_product_category.php");
      $ps_product_category = new ps_product_category;
 
      $castom1_categories=explode(',',$this->get_castom1_categories_child($castom1_categories));
      if(in_array($ps_product_category->get_cid( $product_id ), $castom1_categories)) return FALSE;
 
      return TRUE;
    }
 
//    Получим все дочерние категории от запрещенных
    function get_castom1_categories_child($castom1_categories) {
 
      $db = new ps_DB;
      $ret = $castom1_categories;
 
      while($castom1_categories){
        $catid = array();
        $query = "SELECT a.category_id "
               . "FROM #__{vm}_category AS a "
               . "LEFT JOIN #__{vm}_category_xref AS b "
               . "ON a.category_id = b.category_child_id "
               . "WHERE b.category_parent_id IN($castom1_categories) "
               . "AND a.category_publish = 'Y' ";
        $db->query($query);
        while($db->next_record()){
          $catid[]=$db->f('category_id');
        }
        $castom1_categories=implode(',',$catid);
        if($castom1_categories)$ret .=','.$castom1_categories;
      }
      return $ret;
    }    
 
 


8. Перейдем к корзине. Здесь мы должны проделать серию изменений для двух файлов.
/administrator/components/com_virtuemart/html/basket.php
/administrator/components/com_virtuemart/html/ro_basket.php
В обоих файлах изменения аналогичные. Ищем примерно 52 строку $product_rows = Array(); и ниже добавляем

 
//    Скидка постоянным пользователям.
  $castom1_discount = 0;
  $castom1_discount_val = 0;
  $castom1_categories = '';
  $ps_vendor_id = $_SESSION["ps_vendor_id"];
  $auth = $_SESSION['auth'];
  $db = new ps_DB;
  $countfields = 'count(*) as num_rows';
  $count = "SELECT $countfields FROM #__{vm}_orders o ";
  $q = "WHERE o.vendor_id='$ps_vendor_id' ";
  $q .= "AND (order_status='S' OR order_status='R') ";
  $q .= "AND user_id='" . $auth["user_id"] . "' ";
  $count .= $q;
  $db->query($count);
  $db->next_record();
  $num_rows = $db->f('num_rows');
  if($num_rows){
    $q = "SELECT * FROM #__{vm}_castom1 WHERE publish=1 ORDER BY castom1_val LIMIT 100";
    $db->setQuery($q); $db->query();
    while ($db->next_record()) {
      if($num_rows>=($db->f("castom1_from"))){
        $castom1_discount_val =$db->f("castom1_val");
        $castom1_categories =$db->f("castom1_category");
      }
    }
  }
 
 


Затем ищем участок кода в районе 132 строки
		if( $auth["show_price_including_tax"] == 1 ) {
			$product_price = $price["product_price"] * ($my_taxrate+1);
		} else {
			$product_price = $price["product_price"];
		}

и ниже добавляем

 
//    Скидка постоянным пользователям
    if($castom1_discount_val&&$ps_product->get_castom1_rate($cart[$i]["product_id"],$castom1_categories)){
        $castom1_discount += $product_price*$castom1_discount_val/100;
    }
 
 


Далее ищем участок кода в районе 314 строки
	$order_total += $shipping_total + $total;
	$total_undiscounted += $shipping_total;


и ниже добавляем в файле basket.php

 
//    Скидка постоянным пользователям.
   if($castom1_discount){
     $castom1_discount=round( $castom1_discount, 2 ); 
     $order_total -= $castom1_discount;
     $_SESSION['castom1_discount']=$castom1_discount;
     $castom1_discount=$GLOBALS['CURRENCY_DISPLAY']->getFullValue($castom1_discount); 
   }
 

в файле ro_basket.php

 
//    Скидка постоянным пользователям.
   $castom1_discount=round( $castom1_discount, 2 ); 
   $order_total -= $castom1_discount;
   if($castom1_discount)$castom1_discount=$GLOBALS['CURRENCY_DISPLAY']->getFullValue($castom1_discount); 
 
 


Теперь передадим нашу переменную в шаблон корзины. Ищем ниже участок кода в обоих файлах
	$tpl->set_vars( Array(
				'product_rows' => $product_rows,
				'subtotal_display' => $subtotal_display,
				'discount_before' => $discount_before,
				'discount_after' => $discount_after,

и добавляем туда

 
        'castom1_discount' => $castom1_discount,
 
 


9. Теперь займемся шаблонами корзины - их четыре и менять нужно все. К счастью, изменений не много. В файлах
/components/com_virtuemart/themes/шаблон/templates/basket/basket_b2b.html.php
/components/com_virtuemart/themes/шаблон/templates/basket/basket_b2c.html.php
Ищем участок кода
 
if($discount_after) { ?>
  <tr class="sectiontableentry1">
    <td colspan="4" align="right"><?php echo $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT') ?>:
    </td> 
    <td colspan="3" align="right"><?php echo $coupon_display ?></td>
  </tr>
<?php }
 

и ниже дописываем

 
if($castom1_discount) { ?>
  <tr class="sectiontableentry1">
    <td colspan="4" align="right"><?php echo $VM_LANG->_('PHPSHOP_CASTOM1_YOO') ?>:
    </td> 
    <td colspan="3" align="right"><?php echo $castom1_discount ?></td>
  </tr>
<?php } ?>
 


Аналогично в файлах
/components/com_virtuemart/themes/шаблон/templates/basket/ro_basket_b2b.html.php
/components/com_virtuemart/themes/шаблон/templates/basket/ro_basket_b2c.html.php
Ищем участок кода
 
if( $coupon_discount_after ) { ?>
  <tr class="sectiontableentry1">
    <td colspan="4" align="right"><?php echo $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT') ?>:
    </td> 
    <td align="right"><?php echo $coupon_display ?></td>
  </tr>
<?php }
 

и ниже дописываем

 
if($castom1_discount) { ?>
  <tr class="sectiontableentry1">
    <td colspan="4" align="right"><?php echo $VM_LANG->_('PHPSHOP_CASTOM1_YOO') ?>:
    </td> 
    <td colspan="3" align="right"><?php echo $castom1_discount ?></td>
  </tr>
<?php } ?>
 


Теперь при оформлении заказа покупатель видит свою скидку. Но это еще не все, перейдем к отправляемым письмам и отчетам.

10. Открываем файл /administrator/components/com_virtuemart/classes/ps_checkout.php и начинаем править.
Ищем участок кода, примерно 970 строка:
 
    // Collect all fields and values to store them!
    $fields = array(
      'user_id' => $auth["user_id"], 
      'vendor_id' => $ps_vendor_id, 
      'order_number' => $order_number, 
      'user_info_id' =>  $d["ship_to_info_id"], 
      'ship_method_id' => @urldecode($d["shipping_rate_id"]),
 
 

И вписываем туда
 
      'castom1_discount' => $castom1_discount,
 


Ищем участок кода, примерно 1231 строка:
 
    // Clear the sensitive Session data
    $_SESSION['ccdata']['order_payment_name']  = "";
    $_SESSION['ccdata']['order_payment_number']  = "";
    $_SESSION['ccdata']['order_payment_expire_month'] = "";
    $_SESSION['ccdata']['order_payment_expire_year'] = "";
    $_SESSION['ccdata']['credit_card_code'] = "";
    $_SESSION['coupon_discount'] = "";
 

И вписываем туда
 
    $_SESSION['castom1_discount'] = "";
 


Ищем участок кода, примерно 1308 строка:
 
    /* DISCOUNT HANDLING */
    if( !empty($_SESSION['coupon_discount']) ) {
      $totals['coupon_discount'] = floatval($_SESSION['coupon_discount']);
    }
    else {
      $totals['coupon_discount'] = 0.00;
    }
 
 

И ниже дописываем
 
    /* Скидка постоянным пользователям */
    if( !empty($_SESSION['castom1_discount']) ) {
      $totals['castom1_discount'] = floatval($_SESSION['castom1_discount']);
    }
    else {
      $totals['castom1_discount'] = 0;
    }
 
 


Ищем участок кода, примерно 1344 строка:
 
    $d['order_total'] = $totals['order_total'] =   $tmp_subtotal 
                      + $totals['order_tax']
                      + $totals['order_shipping']
                      + $totals['order_shipping_tax']
                      - $totals['coupon_discount']
 

И вписываем туда
 
                      - $totals['castom1_discount']
 


Ищем участок кода, примерно 1538 строка:
 
        if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
          && PAYMENT_DISCOUNT_BEFORE == '1' ) {
 

И меняем на
 
                    if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ) || !empty( $_SESSION['castom1_discount'] ))
                        && PAYMENT_DISCOUNT_BEFORE == '1' ) {
 


Чуть ниже ищем
 
                                $use_coupon_discount= @$_SESSION['coupon_discount'];
 

И ниже дописываем
 
              $use_castom1_discount= @$_SESSION['castom1_discount'];
              if( !empty( $_SESSION['castom1_discount'] )) {
                if( $auth["show_price_including_tax"] == 1 ) {
                  $use_castom1_discount = $_SESSION['castom1_discount'] / ($tax_rate+1);
                }
              }
 
 


Чуть ниже ищем
 
              $factor = (100 * ($use_coupon_discount + @$d['payment_discount'])) / $this->_subtotal;
 

И меняем на
 
                                $factor = (100 * ($use_castom1_discount + $use_coupon_discount + @$d['payment_discount'])) / $this->_subtotal;
 


Ищем участок кода, примерно 1585 строка:
 
        if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
          && PAYMENT_DISCOUNT_BEFORE != '1' ) {
 

И меняем на
 
        if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ) || !empty( $_SESSION['castom1_discount'] ))
          && PAYMENT_DISCOUNT_BEFORE == '1' ) {
 


Чуть ниже ищем
 
            if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
              && PAYMENT_DISCOUNT_BEFORE == '1' ) {
              $use_coupon_discount= @$_SESSION['coupon_discount'];
 
 

И меняем на
 
            if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ) || !empty( $_SESSION['castom1_discount'] ))
              && PAYMENT_DISCOUNT_BEFORE == '1' ) {
              $use_coupon_discount= @$_SESSION['coupon_discount'];
              $use_castom1_discount= @$_SESSION['castom1_discount'];
              if( !empty( $_SESSION['castom1_discount'] )) {
                if( $auth["show_price_including_tax"] == 1 ) {
                  $use_castom1_discount = $_SESSION['castom1_discount'] / ($tax_rate+1);
                }
              }
 


Чуть ниже ищем
 
              $factor = (100 * ($use_coupon_discount + @$d['payment_discount'])) / $this->_subtotal;
 

И меняем на
 
              $factor = (100 * ($use_castom1_discount + $use_coupon_discount + @$d['payment_discount'])) / $this->_subtotal;
 
 


Ниже ищем
 
  if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
    && PAYMENT_DISCOUNT_BEFORE != '1' ) {
 
    // Here we need to re-calculate the Discount
    // because we assume the Discount is "including Tax"
    $discounted_total = @$d['order_subtotal_withtax'] - @$_SESSION['coupon_discount'] - @$d['payment_discount'];
 
 

И меняем на
 
        if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ) || !empty( $_SESSION['castom1_discount'] ))
          && PAYMENT_DISCOUNT_BEFORE != '1' ) {
 
          // Here we need to re-calculate the Discount
          // because we assume the Discount is "including Tax"
          $discounted_total = @$d['order_subtotal_withtax'] - @$_SESSION['coupon_discount'] - @$d['payment_discount'] - @$_SESSION['castom1_discount'] ;
 


Ниже в функции function email_receipt($order_id) ищем, примерно строка 1884
 
    $order_total = $db->f("order_total");
    $order_discount = $db->f("order_discount");
    $coupon_discount = $db->f("coupon_discount");
 

И ниже дописываем
 
    $castom1_discount = $db->f("castom1_discount");
 


В этой-же функции ищем два раза, примерно строка 2055 и 2087
 
  if( !empty($coupon_discount)) {
    /* following 2 lines added by Erich for coupon hack */
    $shopper_message .= $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT',false) . ": ";
    $shopper_message .= $CURRENCY_DISPLAY->getFullValue($coupon_discount, '', $db->f('order_currency')) . "\n";
  }
 

И ниже дописываем
 
      if( !empty($castom1_discount)) {
        $shopper_message .= $VM_LANG->_('PHPSHOP_CASTOM1_YOO',false) . ": ";
        $shopper_message .= $CURRENCY_DISPLAY->getFullValue($castom1_discount, '', $db->f('order_currency')) . "\n";
      }
 


Ниже ищем участок кода
 
      // These are a lot of vars to import for the email confirmation
      $template->set_vars(array(
                            'is_email_to_shopper' => true,
                            'db' => $db,
                            'dboi' => $dboi,
                            'dbbt' => $dbbt,
                            'dbst' => $dbst,
                            'ps_product' => $ps_product,
                            'shippingfields' => $shippingfields,
 

И вставляем туда
 
                            'castom1_discount' => $castom1_discount,
 


11. Открываем файл /components/com_virtuemart/themes/default/templates/order_emails/confirmation_email.tpl.php. В двух местах находим
 
      if ($coupon_discount > 0 || $coupon_discount < 0) {
        ?>
        <tr class="Stil1">
          <td align="right" colspan="4"><?php echo $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT') ?>: </td>
          <td><?php echo $coupon_discount_plusminus. ' '.$CURRENCY_DISPLAY->getFullValue(abs($coupon_discount),
 '', $db->f('order_currency')) ?></td>
        </tr>
        <?php
      }
 

И в каждом случае дописываем снизу
 
      if ($castom1_discount > 0 || $castom1_discount < 0) {
        ?>
        <tr class="Stil1">
          <td align="right" colspan="4"><?php echo $VM_LANG->_('PHPSHOP_CASTOM1_YOO') ?>: </td>
          <td><?php echo ' -'.$CURRENCY_DISPLAY->getFullValue(abs($castom1_discount), '', $db->f('order_currency')) ?></td>
        </tr>
        <?php
      }
 
 


12. Открываем файл /administrator/components/com_virtuemart/html/order.order_printdetails.php и ищем код
 
      $coupon_discount = $db->f("coupon_discount");
 
      if( $coupon_discount > 0 ) {
        $subtotal -= $coupon_discount;
      ?>
        <tr>
          <td colspan="4" align="right"><?php echo $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT') ?>:
          </td>
          <td align="right"><?php
            echo "- ".$CURRENCY_DISPLAY->getFullValue( $coupon_discount, '', $db->f('order_currency') ); ?>   
          </td>
        </tr>
      <?php
      }
 

под ним пишем снизу
 
      $castom1_discount = $db->f("castom1_discount");
 
      if( $castom1_discount > 0 ) {
        $subtotal -= $castom1_discount;
      ?>
        <tr>
          <td colspan="4" align="right"><?php echo $VM_LANG->_('PHPSHOP_CASTOM1_YOO2') ?>:
          </td>
          <td align="right"><?php
       echo "- ".$CURRENCY_DISPLAY->getFullValue( $castom1_discount, '', $db->f('order_currency') ); ?>   
          </td>
        </tr>
      <?php
      }
 


Ниже, примерно строка 354
 
           $total = $db->f("order_subtotal") + $tax_total + $db->f("order_shipping") - $db->f("coupon_discount");
 

меняем на
 
              $total = $db->f("order_subtotal") + $tax_total + $db->f("order_shipping") - $db->f("coupon_discount") - $db->f("castom1_discount");
 


13. Открываем файл /components/com_virtuemart/themes/default/templates/pages/account.order_details.tpl.php. Примерно строка 404.
 
  $coupon_discount = $db->f("coupon_discount");
  $order_discount = $db->f("order_discount");
 
 

снизу дописываем
 
  $castom1_discount = $db->f("castom1_discount");
 


Ниже ищем два раза
 
    if( $coupon_discount > 0 ) {
  ?>
          <tr>
            <td colspan="4" align="right"><?php echo $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT') ?>:
            </td> 
            <td align="right"><?php
              echo "- ".$CURRENCY_DISPLAY->getFullValue( $coupon_discount, '', $db->f('order_currency') ); ?>   
            </td>
          </tr>
  <?php
    }
 

снизу дописываем каждый раз
 
    if( $castom1_discount > 0 ) {
  ?>
          <tr>
            <td colspan="4" align="right"><?php echo $VM_LANG->_('PHPSHOP_CASTOM1_YOO') ?>:
            </td> 
            <td align="right"><?php
              echo "- ".$CURRENCY_DISPLAY->getFullValue( $castom1_discount, '', $db->f('order_currency') ); ?>   
            </td>
          </tr>
  <?php
    }
 


14. Открываем файл /administrator/components/com_virtuemart/html/order.order_print.php Примерно строка 419
 
        /* COUPON DISCOUNT */
      $coupon_discount = $db->f("coupon_discount");
 

снизу дописываем
 
      $castom1_discount = $db->f("castom1_discount");
 


Ниже ищем два раза
 
    if( $coupon_discount > 0 || $coupon_discount < 0) {
 ?>
    <tr>
    <td align="right" colspan="7"><strong><?php echo $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT') ?>:</strong></td> 
    <td  width="5%" align="right" style="padding-right: 5px;"><?php
     echo "- ".$GLOBALS['CURRENCY_DISPLAY']->getFullValue( $coupon_discount, '', $db->f('order_currency') ); ?>
    </td>
    </tr>
    <?php
    }
 

снизу дописываем каждый раз
 
        if( $castom1_discount > 0 || $castom1_discount < 0) {
    ?>
        <tr>
        <td align="right" colspan="7"><strong><?php echo $VM_LANG->_('PHPSHOP_CASTOM1_YOO2') ?>:</strong></td> 
        <td  width="5%" align="right" style="padding-right: 5px;"><?php
          echo "- ".$GLOBALS['CURRENCY_DISPLAY']->getFullValue( $castom1_discount, '', $db->f('order_currency') ); ?>
        </td>
        </tr>
        <?php
        }
 



С обственно все.

Осталось только вывести размер скидки в личный кабинет покупателя. Для этого открываем файл
/components/com_virtuemart/themes/default/templates/pages/account.index.tpl.php
и добавляем новую строку в таблицу разметки

 
    <tr>
      <td>
        <?php 
 
//    Скидка постоянным пользователям.
          echo $VM_LANG->_('PHPSHOP_CASTOM1_TITLE');
          $castom1_discount_val = 0;
          $ps_vendor_id = $_SESSION["ps_vendor_id"];
          $auth = $_SESSION['auth'];
          $db = new ps_DB;
          $countfields = 'count(*) as num_rows';
          $count = "SELECT $countfields FROM #__{vm}_orders o ";
          $q = "WHERE o.vendor_id='$ps_vendor_id' ";
          $q .= "AND (order_status='S' OR order_status='R') ";
          $q .= "AND user_id='" . $auth["user_id"] . "' ";
          $count .= $q;
          $db->query($count);
          $db->next_record();
          $num_rows = $db->f('num_rows');
          if($num_rows){
            $q = "SELECT * FROM #__{vm}_castom1 WHERE publish=1 ORDER BY castom1_val LIMIT 100";
            $db->setQuery($q); $db->query();
            while ($db->next_record()) {
              if($num_rows>=($db->f("castom1_from"))){
                $castom1_discount_val =$db->f("castom1_val");
              }
            }
          }
          echo ' <strong style="font-size:130%;color:blue">'.$num_rows.'</strong> ';
          echo $VM_LANG->_('PHPSHOP_CASTOM1_N');
          echo '. '.$VM_LANG->_('PHPSHOP_CASTOM1_YOO');
          echo ' <strong style="font-size:130%;color:blue">'.$castom1_discount_val.' %</strong>';
 
        ?>
        <hr />
      </td>
    </tr>