Как получить итоговые цены до сохранения способа оплаты? - PullRequest
9 голосов
/ 08 февраля 2012

Я пытаюсь создать одноступенчатый заказ, но на странице оформления заказа возникла проблема с проверкой заказа. Например, когда я выбираю способ оплаты, «наложенный платеж» имеет дополнительные 5 $, или «чекодер» имеет скидку 4%, или «оплата кредитной картой» добавляет дополнительно к общей сумме заказа. Мне нужен способ расчета скидок перед сохранением способа оплаты. Любое предложение?

Ответы [ 2 ]

17 голосов
/ 09 февраля 2012

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

Как создать пользовательские модели Magento

Чтобы создать собственную итоговую модель, сначала необходимо создать модуль и добавить итоговые модели в конфигурацию.

<global>
  <sales>
    <quote>
      <totals>
        <your_total>
          <class>your_module/quote_address_total_yourTotal</class>
          <after>shipping</after><!-- calculate after these total models -->
          <before>grand_total,tax</before><!-- calculate before these total models -->
        </your_total>
      </totals>
    </quote>
    <order_invoice>
      <totals>
        <your_total>
          <class>your_module/order_invoice_total_yourTotal</class>
          <after>shipping</after>
          <before>grand_total,tax</before>
        </your_total>
      </totals>
    </order_invoice>
    <order_creditmemo>
      <totals>
        <your_total>
          <class>your_module/order_creditmemo_total_yourTotal</class>
          <after>shipping</after>
          <before>grand_total,tax</before>
        </your_total>
      </totals>
    </order_creditmemo>
  </sales>
  <pdf>
    <totals>
      <your_total translate="title">
        <title>Your Total</title>
        <source_field>your_total</source_field>
        <font_size>7</font_size>
        <display_zero>0</display_zero>
        <sort_order>450</sort_order>
      </your_total>
    </totals>
  </pdf>
</global>

Затем реализуйте три класса, указанные в XML.
Всего в адресе кавычки необходимо расширить sales/quote_address_total_abstract и реализовать два метода collect() и fetch().

class Your_Module_Model_Quote_Address_Total_YourTotal
    extends Mage_Sales_Model_Quote_Address_Total_Abstract
{
    // Calculate your total value
    public function collect(Mage_Sales_Model_Quote_Address $address)
    {
        parent::collect($address);

        // Calculate the totals based on the information in the $address
        // and the $address->getQuote()
        // To get the items in the cart use $address->getAllItems()
        // To get the payment method use getPayment()->getMethodInstance()
        // etc

        // When your totals are known..
        $this->_addAmount($total); // store view currency amount
        $this->_addBaseAmount($baseTotal); // base currency amount

        // Also store in address for later reference in fetch()
        $address->setMyTotal($total);
        $address->setBaseMyTotal($baseTotal);

        return $this;
    }

    // If the total should be displayed in the cart and the checkout
    // add them to the address model here, otherwise just return
    // (it will still be calculated and added to the grand total)
    public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
        if ($address->getMyTotal() > 0)
        {
            $address->addTotal(array(
                'code'  => $this->getCode(),
                'title' => Mage::helper('your_module')->__('Your Total'),
                'value' => $address->getMyTotal()
            ));
        }
        return $this;
    }
}

Следующим классом, указанным в XML-файле конфигурации, является общая модель счета-фактуры your_module/order_invoice_total_yourTotal.

class Your_Module_Model_Order_Invoice_Total_YourTotal
    extends Mage_Sales_Model_Order_Invoice_Total_Abstract
{
    // Collect the totals for the invoice
    public function collect(Mage_Sales_Model_Order_Invoice $invoice)
    {
        $order = $invoice->getOrder();
        $myTotal = $order->getMyTotal();
        $baseMyTotal = $order->getBaseMyTotal();

        $invoice->setGrandTotal($invoice->getGrandTotal() + $myTotal);
        $invoice->setBaseGrandTotal($invoice->getBaseGrandTotal() + $basemyTotal);

        return $this;
    }
}

Последний класс, который необходимо реализовать в модели итога creditmemo, который аналогичен модели итога счета-фактуры, только он расширяет абстрактный класс Mage_Sales_Model_Order_Creditmemo_Total_Abstract.

Вам также необходимо добавить атрибуты, используя скрипт установки:

/**
 * @var Mage_Sales_Model_Resource_Setup $installer
 */
$installer = Mage::getResourceModel('sales/setup', 'default_setup');

$installer->startSetup();

$installer->addAttribute('order', 'base_your_total', array(
    'label' => 'Base Your Total',
    'type'  => 'decimal',
));

$installer->addAttribute('order', 'your_total', array(
    'label' => 'Your Total',
    'type'  => 'decimal',
));

$installer->addAttribute('invoice', 'base_your_total', array(
    'label' => 'Base Your Total',
    'type'  => 'decimal',
));

$installer->addAttribute('invoice', 'your_total', array(
    'label' => 'Your Total',
    'type'  => 'decimal',
));

$installer->addAttribute('creditmemo', 'base_your_total', array(
    'label' => 'Base Your Total',
    'type'  => 'decimal',
));

$installer->addAttribute('creditmemo', 'your_total', array(
    'label' => 'Your Total',
    'type'  => 'decimal',
));

$installer->endSetup();

Чтобы отобразить новый итог в административной области, вам нужно добавить для него блок итогов с использованием макета XML. Зарегистрируйте файл обновления макета для области adminhtml в вашем модуле. Вот пример содержания:

<layout version="0.1.0">

  <adminhtml_sales_order_view>
    <reference name="order_totals">
      <block type="your_module/sales_total_yourTotal" name="total_your_total" as="your_total"/>
    </reference>
  </adminhtml_sales_order_view>

  <adminhtml_sales_order_invoice_new>
    <reference name="invoice_totals">
      <block type="your_module/sales_total_yourTotal" name="total_your_total" as="your_total"/>
    </reference>
  </adminhtml_sales_order_invoice_new>

  <adminhtml_sales_order_invoice_updateqty>
    <reference name="invoice_totals">
      <block type="your_module/sales_total_yourTotal" name="total_your_total" as="your_total"/>
    </reference>
  </adminhtml_sales_order_invoice_updateqty>

  <adminhtml_sales_order_invoice_view>
    <reference name="invoice_totals">
      <block type="your_module/sales_total_yourTotal" name="total_your_total" as="your_total"/>
    </reference>
  </adminhtml_sales_order_invoice_view>

  <adminhtml_sales_order_creditmemo_new>
    <reference name="creditmemo_totals">
      <block type="your_module/sales_total_yourTotal" name="total_your_total" as="your_total"/>
    </reference>
  </adminhtml_sales_order_creditmemo_new>

  <adminhtml_sales_order_creditmemo_view>
    <reference name="creditmemo_totals">
      <block type="your_module/sales_total_yourTotal" name="total_your_total" as="your_total"/>
    </reference>
  </adminhtml_sales_order_creditmemo_view>

</layout>

Если вы не хотите где-то отображать общее количество, просто опустите его. Это все еще будет рассчитано. Хорошо, почти там. И наконец, реализация класса общего блока административной области:

// Many ways to implement this, here is one option
class Your_Module_Block_Sales_Total_YourTotal
    extends Mage_Core_Block_Abstract
{
    public function initTotals()
    {
        $parent = $this->getParentBlock();

        $value = $parent->getSource()->getMyTotal();

        if ($value > 0)
        {
            $total = new Varien_Object(array(
            'code'  => 'my_total',
            'value' => $parent->getSource()->getMyTotal(),
            'base_value' => $parent->getSource()->getBaseMyTotal(),
            'label' => $this->__('My Total'),
            'field' => 'my_total'
            ));
            $parent->addTotal($total, 'my_total');
        }
        return $this;
    }
}

Теперь единственное, чего не хватает, - это набора полей для копирования общей суммы с адреса котировки в заказ и из заказа в счет-фактуру и кредитную отметку. Добавьте следующий XML-файл в файл config.xml:

<fieldsets>
    <sales_convert_quote_address>
        <shipping_surcharge><to_order>*</to_order></shipping_surcharge>
        <base_shipping_surcharge><to_order>*</to_order></base_shipping_surcharge>
    </sales_convert_quote_address>
    <sales_convert_order>
        <shipping_surcharge><to_invoice>*</to_invoice><to_cm>*</to_cm></shipping_surcharge>
    </sales_convert_order>
</fieldsets>

И это все. Общая сумма будет отображаться везде (включая сгенерированные PDF-файлы).
Как я уже сказал, есть много других способов просто обновить значения всех моделей, уже присутствующих в ядре, но это полноценный способ его реализации.

0 голосов
/ 08 февраля 2012

В заказе есть методы setShippingAmount и getShippingAmount. Изменить, чтобы добавить «наложенным платежом».

Создать метод и добавить его в качестве наблюдателя к событию checkout_type_onepage_save_order в /etc/config.xml

# file: /Model/Observer.php
<?php
    class Handling_Fee_Model_Observer 
    {
       public function updateHandling ($observer)
       {
          $order = $observer->getEvent()->getOrder();
          $shipping_amount = $order->getShippingAmount();
          $order->setShippingAmount($shipping_amount * (1 + 0,5));
          return $this;
       }
    }

Это часть вашего вопроса. По моему мнению, вы можете настроить левые части таким образом.

...