8

我在结帐时添加了额外费用,但税款计算不正确。

如果我这样做 $this->_calculateTax($address); 在收集功能中,它被加到包括税的总额中,但我的税额仍然是当时的。

if is var_dump $address->setAppliedTaxes($previouslyAppliedTaxes); 我确实看到了正确的数量。它转储了两次,第一次是我的额外费用的正确税额,第二次是正确的总税额。但是在前端它显示了没有我的额外费用税的税。

关于这可能是什么的任何线索?

    class Company_Customer_Model_Quote_Address_Total_PrintPrepCosts extends Mage_Sales_Model_Quote_Address_Total_Abstract
{
    public function __construct() {
        $this->setCode('printPrepCosts');
        $this->_store = Mage::app()->getStore();
        return $this;
    }

public function collect(Mage_Sales_Model_Quote_Address $address)
    {
        parent::collect($address);
        $address->setPrintPrepcosts(0);
        $address->setTaxAmount(0);
        $address->setBaseTaxAmount(0);

        if(count($address->getAllItems()) == 0)
        {
            return $this;
        }

        $pricePrint = $this->calcTotalPrintPrepCosts();

        $address->setPrintPrepcosts($pricePrint);
        $address->setBasePrintPrepcosts($pricePrint);

        $address->setBaseGrandTotal($address->getBaseGrandTotal() + $address->getPrintPrepcosts());
        $address->setGrandTotal($address->getGrandTotal() + $address->getPrintPrepcosts());

        $this->_calculateTax($address);
        return $this;
    }

    protected function _calculateTax(Mage_Sales_Model_Quote_Address $address)
    {
        $calculator     = Mage::getSingleton('tax/calculation');
        $inclTax        = Mage::getStoreConfig('tax/calculation/printing_prep_includes_tax', $this->_store);

        $taxRateRequest = $calculator->getRateRequest(
            $address,
            $address->getQuote()->getBillingAddress(),
            $address->getQuote()->getCustomerTaxClassId(),
            $this->_store
        );

        // TODO undef prop _store
        $taxRateRequest->setProductClassId(Mage::getStoreConfig('tax/classes/printing_prep_tax_class', $this->_store));

        $rate = $calculator->getRate($taxRateRequest);
        $baseTax = $tax = $calculator->calcTaxAmount($address->getPrepPrintcosts(), $rate, $inclTax, true);

        $address->addTotalAmount('tax', max(0, $tax));
        $address->addBaseTotalAmount('tax', max(0, $baseTax));

        $this->_saveAppliedTaxes($address, 
            $calculator->getAppliedRates($taxRateRequest), 
            $tax, 
            $baseTax, 
            $rate
        );

        // later on added - which fixes the total, lose tax amount still off
        $address->setTaxAmount($tax);
        $address->setBaseTaxAmount($baseTax);

        if($inclTax)
        {
            $address->setBaseGrandTotal($address->getBaseGrandTotal() - $baseTax);
            $address->setGrandTotal($address->getGrandTotal() - $tax);
        }
    }

    protected function _saveAppliedTaxes(Mage_Sales_Model_Quote_Address $address, $applied, $amount, $baseAmount, $rate)
    {
        $previouslyAppliedTaxes = $address->getAppliedTaxes();
        $process = count($previouslyAppliedTaxes);


        foreach ($applied as $row) {
            if (!isset($previouslyAppliedTaxes[$row['id']])) {
                $row['process'] = $process;
                $row['amount'] = 0;
                $row['base_amount'] = 0;
                $previouslyAppliedTaxes[$row['id']] = $row;
            }

            if (!is_null($row['percent'])) {
                $row['percent'] = $row['percent'] ? $row['percent'] : 1;
                $rate = $rate ? $rate : 1;

                $appliedAmount = $amount/$rate*$row['percent'];
                $baseAppliedAmount = $baseAmount/$rate*$row['percent'];
            } else {
                $appliedAmount = 0;
                $baseAppliedAmount = 0;
                foreach ($row['rates'] as $rate) {
                    $appliedAmount += $rate['amount'];
                    $baseAppliedAmount += $rate['base_amount'];
                }
            }


            if ($appliedAmount || $previouslyAppliedTaxes[$row['id']]['amount']) {
                $previouslyAppliedTaxes[$row['id']]['amount'] += $appliedAmount;
                $previouslyAppliedTaxes[$row['id']]['base_amount'] += $baseAppliedAmount;
            } else {
                unset($previouslyAppliedTaxes[$row['id']]);
            }
        }
        $address->setAppliedTaxes($previouslyAppliedTaxes);        
    }

    public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
        $address->addTotal(array(
            'code'  => $this->getCode(),
            'title' => "Prep Print costs",
            'value' => $address->getPrintPrepcosts(),
        ));
        return $this;
    }

编辑 1 XML 包含以下内容:

        <sales>
        <quote>
            <totals>
                <printPrepCosts>
                    <class>Company_Customer_Model_Quote_Address_Total_PrintPrepCosts</class>
                    <after>subtotal</after>
                    <before>tax</before>
                </printPrepCosts>
            </totals>
        </quote>
    </sales>

编辑 2 我在我的 calcTax 函数中添加了以下几行,这确实修复了总计,但 TAX 的金额仍然关闭。

  $address->setTaxAmount($tax);
  $address->setBaseTaxAmount($baseTax);

输出 - 示例

Subtotal    € 67,50
printPrepCosts  € 40,00
Shipping    € 50,00
TAX     € 22,33
Total   € 187,43

编辑 3 我的错,只有 GoMage 单页结帐提供了正确的总计,而购物车没有。常规的 Magento 单页结帐也会给出错误的总计。

4

3 回答 3

5

我找到了一种解决方法,它不是最好的解决方案,但它确实有效:)

在我的地址中,我将税收设置为一个名为 tax 的额外变量,并在观察者中使用它来操纵税收。

class Company_Client_Model_Observer
{   
    public function setCorrectTax ($observer)
    {
        $quote = $observer->getQuote();
        foreach ($quote->getAllAddresses() as $address) {
            $printPrepCosts = $address->getPrintPrepcosts();
            if(!empty($printPrepCosts)) {
                $address->setTaxAmount($address->tax);
            }
        }
    }
}

和 XML

    <events>
    <sales_quote_collect_totals_after>
        <observers>
            <client>
                <type>singleton</type>
                <class>client/observer</class>
                <method>setCorrectTax</method>
            </client>
        </observers>
    </sales_quote_collect_totals_after>
    </events>
于 2012-08-13T13:47:16.230 回答
2

您是要修改现有的税单项目还是添加一个新项目?您可以显示整个模型的 config.xml 条目吗?

如果您要添加新的税项,这应该就足够了,只需针对 CE 1.7 vanilla 安装进行测试:

class KJ_Mymodule_Model_Sales_Quote_Address_Total_Kjtest extends Mage_Sales_Model_Quote_Address_Total_Abstract
{
    public function __construct()
    {
        $this->setCode('kjtest');
    }

    public function collect(Mage_Sales_Model_Quote_Address $address)
    {
        parent::collect($address);

        $this->_setAmount(1.01);
        $this->_setBaseAmount(1.01);

        return $this;
    }

    public function processConfigArray($config, $store) {
        return $config;
    }

    public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
        $address->addTotal(array(
            'code'  => $this->getCode(),
            'title' => "Prep Print costs",
            'value' => 1.01,
        ));
        return $this;
    }
}

足够了,我的意思是这应该是显示该税项所需的最低限度。

在你的 config.xml 中有这个:

<sales>
    <quote>
        <totals>
            <kjtest>
                <class>mymodule/sales_quote_address_total_kjtest</class>
                <after>tax</after>
            </kjtest>
        </totals>
    </quote>     
</sales>
于 2012-08-08T01:05:55.123 回答
2

请阅读以下内容,我认为这对您很有帮助:-

见下面的网址

http://www.excellencemagentoblog.com/magento-add-fee-discount-order-total

Magento 添加费用或折扣订单总额

在本教程中,我们将看到如何将新的订单项添加到 magento 订单总额中。这意味着,如何添加额外的费用或折扣,或任何类型的费用来订购 magento 结帐流程的总额。在典型的订单中,订单总额通常包括小计、运费、税金、折扣,根据这些值计算订单总额。现在,如果我们想添加额外的信用卡费用或说服免费或附属折扣或任何其他会影响订单总额的订单总额,我们需要创建一个 magento 模块。我们添加到总额中的这笔额外费用将反映在

  • 结帐页面订单总计
  • 购物车页面订单总计
  • 我的帐户订单查看页面
  • 订购电子邮件
  • 管理员订单查看/电子邮件/PDF
  • 管理员发票查看/电子邮件/PDF
  • 管理员信用备忘录查看/电子邮件/PDF

从上面的列表可以看出,这个模块并不简单。在本教程中,我附上了这样一个非常基本的模块的源代码,您可以使用您的起点来添加额外的更改。我还将解释如何实现这一点的基础知识。在本教程中,我将添加一个名为“费用”的新订单总额,固定成本为 10 美元。

或者试试看:-

结帐页面总订单总基础

我们将看到如何仅将总计添加到结帐页面。结帐页面上显示的所有总计行项目都来自位于文件夹 Mage\Sales\Model\Quote\Address\Total 的文件。在magento中,在下订单之前,所有订单数据都存储在报价对象中,下订单后,它会被传输到订单对象。报价总额遵循收集器模式,我们可以添加尽可能多的收集器类。要将收集器添加到 config.xml 中的报价对象,我们添加以下行

<global>
        <sales>
            <quote>
                <totals>
                    <fee>
                        <class>fee/sales_quote_address_total_fee</class>
                    </fee>
                </totals>
            </quote>
       </sales>
</global>

这意味着每当计算报价的总数时,它也会调用这个类。从报价模型中的 collectTotals() 函数调用所有收集器。在我们的收集器类中,我们输入了代码

<?php
   class Excellence_Fee_Model_Sales_Quote_Address_Total_Fee extends Mage_Sales_Model_Quote_Address_Total_Abstract{
    protected $_code = 'fee';

    public function collect(Mage_Sales_Model_Quote_Address $address)
    {
        parent::collect($address);

        $this->_setAmount(0);
        $this->_setBaseAmount(0);

        $items = $this->_getAddressItems($address);
        if (!count($items)) {
            return $this; //this makes only address type shipping to come through
        }


        $quote = $address->getQuote();

        if(Excellence_Fee_Model_Fee::canApply($address)){ //your business logic
            $exist_amount = $quote->getFeeAmount();
            $fee = Excellence_Fee_Model_Fee::getFee();
            $balance = $fee - $exist_amount;
            $address->setFeeAmount($balance);
            $address->setBaseFeeAmount($balance);

            $quote->setFeeAmount($balance);

            $address->setGrandTotal($address->getGrandTotal() + $address->getFeeAmount());
            $address->setBaseGrandTotal($address->getBaseGrandTotal() + $address->getBaseFeeAmount());
        }
    }

    public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
        $amt = $address->getFeeAmount();
        $address->addTotal(array(
                'code'=>$this->getCode(),
                'title'=>Mage::helper('fee')->__('Fee'),
                'value'=> $amt
        ));
        return $this;
    }
}

这里的两个主要函数是 collect() 和 fetch()。在 collect 函数中,您可以将所需的任何数量添加到订单总额中,并且 fetch() 用于显示目的。如果此操作正确,您应该会在结帐和购物车页面中看到您的订单总行。这里我们使用两个字段 fee_amount 和 base_fee_amount,其中包含我们的费用金额。我们将不得不看到将这两个字段保存到数据库中,因此在我们的模块安装程序文件中添加此代码

ALTER TABLE  `".$this->getTable('sales/quote_address')."` ADD  `fee_amount` DECIMAL( 10, 2 ) NOT NULL;
ALTER TABLE  `".$this->getTable('sales/quote_address')."` ADD  `base_fee_amount` DECIMAL( 10, 2 ) NOT NULL;

订单页面

到目前为止,所有编写的代码都只针对引用对象完成。但是下订单后,我们需要将所有信息传递给订单对象。正如您在上面看到的,我们使用了两个字段 fee_amount 和 base_fee_amount,我们现在还需要将这两个字段存储在订单表中。要做到以上所有,我们需要做两件事。首先在 config.xml 文件中的全局选项卡内添加此代码,

<fieldsets>
        <sales_convert_quote_address>
            <fee_amount><to_order>*</to_order></fee_amount>
            <base_fee_amount><to_order>*</to_order></base_fee_amount>
        </sales_convert_quote_address>
    </fieldsets>

在我们的模块安装文件中

ALTER TABLE  `".$this->getTable('sales/order')."` ADD  `fee_amount` DECIMAL( 10, 2 ) NOT NULL;
ALTER TABLE  `".$this->getTable('sales/order')."` ADD  `base_fee_amount` DECIMAL( 10, 2 ) NOT NULL;

完成此操作后,这两个字段应从报价表保存到订单表中。

这只是将订单项添加到订单总额的基础知识。其余的附加模块里面写了很多代码,请详细阅读以了解更多。

于 2012-08-08T06:53:00.447 回答