Magento:结账时收取额外费用的税收错误

时间:2012-08-03 15:49:12

标签: php magento magento-1.6 gomage

我已经为结帐添加了额外的费用,但是税款计算不正确。

如果我执行$ this-> _calculateTax($ address),则税额不会正确累加;在收集功能中,它累计到包括税的总额,但我的税额仍然是。

如果是var_dump,则在$ address-> setAppliedTaxes($ previousAppliedTaxes)行之后设置应用税;我确实看到了正确的金额。它倾倒了两次,第一次看到正确的税额只是我的额外费用,第二次是正确的税额。但是在前端,它显示了税收而没有我的额外费用税。

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

    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 onepage checkout给出正确的总计,购物车没有。常规的Magento onepage checkout也提供了错误的格式。

3 个答案:

答案 0 :(得分:5)

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

在我的地址中,我将税收设置为额外的变量,称为税,并在观察者中使用该税来操纵税。

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>

答案 1 :(得分:2)

您是要尝试修改现有税行项目还是添加新项目?你能展示整个模型的config.xml条目吗?

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

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>

答案 2 :(得分:2)

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

请参阅

下面的网址

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

Magento添加费用或折扣订单

在本教程中,我们将了解如何向magento订单总计添加新订单项。 这意味着,如何添加额外的费用或折扣,或任何类型的费用来订购整个洋红色结账流程。 在典型的订单中,订单总计通常包括子总计,运输成本,税收,折扣,基于这些值计算总订单总计。现在,如果我们想要添加额外的信用卡费用或说明免费或会员折扣或任何其他订单总额,这将影响订单总额,我们需要创建一个magento模块。我们添加到总额中的额外费用将反映在

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

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

或尝试一下: -

结帐页总订单总数

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

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

这意味着每当计算报价的总数时,它也会调用此类。所有收集器都是从Quote Model中的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()。在收集功能中,您可以将任何数量添加到订单总计中,并且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;

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

这只是将订单项添加到订单总计的基础知识。休息时附带的模块中写了很多代码,请详细了解它以了解更多。