1

I want to give a fixed discount (for example 50 EUR) to every x-th visitor. In the session I keep track if the discount has to be awarded or not. The discount should only be be awarded for items bought - inclusive their taxes (not for shipping...)

My tax calculation settings are: "apply customer tax": after discount and "apply discount on prices": including taxes.

I catch the sales-quote-collect-totals-after event and calculate the total order value:

$grandTotal = 0;
/* @var $item Mage_Sales_Model_Resource_Quote_Item */
$items = $quote->getAllItems();
foreach ($items as $item) {
    $grandTotal += $item->getRowTotal();
}
$discount = 50; // simplified for clarity, assume $grandTotal > 50
Mage::getSingleton('checkout/session')->setDiscount($discount); // for displaying info
$baseDiscount = $discount * $xRate; // simplified: $xRate has been calculated previously...
foreach ($items as $item) {
    // We apply discount amount based on the ratio between the overall total and the RowTotal
    $rowTotal = $item->getRowTotal();
    $fraction = $rowTotal / $discountable;

    $itemDiscount = $discount * $fraction;
    $itemBaseDiscount = $baseDiscount * $fraction;

    $item->setDiscountAmount($item->getDiscountAmount() + $itemDiscount);
    $item->setBaseDiscountAmount($item->getBaseDiscountAmount() + $itemBaseDiscount);
    $item->save();
}
// Do the items now contain all info for proper calculations in collectTotals?

$addresses = $quote->getAllAddresses();
/* @var $address Mage_Sales_Model_Quote_Address */
foreach ($addresses as $address) {
    // set the totals to 0
    // is this needed? must other stuff be set to 0?
    $address->setSubtotal(0);
    $address->setBaseSubtotal(0);
    $address->setGrandTotal(0);
    $address->setBaseGrandTotal(0);

    // let magento do it's work...
    $address->collectTotals();

    if ($address->getAddressType() == 'shipping') {
        $address->setSubtotalWithDiscount($address->getSubtotalWithDiscount() - $discount);
        $address->setGrandTotal($address->getGrandTotal() - $discount);

        $address->setBaseSubtotalWithDiscount($address->getBaseSubtotalWithDiscount() - $baseDiscount);
        $address->setBaseGrandTotal($address->getBaseGrandTotal() - $baseDiscount);

        if ($address->getDiscountDescription()) {
            $address->setDiscountDescription($address->getDiscountDescription() . ', 'Happy Randomizer');
            $address->setDiscountAmount($address->getDiscountAmount() - $discount);
            $address->setBaseDiscountAmount(($address->getBaseDiscountAmount - $baseDiscount));
        } else {
            $address->setDiscountAmount(-($discount));
            $address->setDiscountDescription('Happy Randomizer');
            $address->setBaseDiscountAmount(-$baseDiscount);
        }
        $address->setAddressId($address->getAddressId());
        $address->save();
    }

    // update quote totals
    $quote->setSubtotal($quote->getSubtotal() + $address->getSubtotal());
    $quote->setSubtotalWithDiscount($quote->getSubtotal() - $discount);
    $quote->setGrandTotal($quote->getGrandTotal() + $address->getGrandTotal());

    $quote->setBaseSubtotal($quote->getBaseSubtotal() + $address->getBaseSubtotal());
    $quote->setBaseSubtotalWithDiscount($quote->getBaseSubtotal() - $baseDiscount);
    $quote->setBaseGrandTotal($quote->getBaseGrandTotal() + $address->getBaseGrandTotal());

    $quote->save();
}

After this, in cart , totals are displayed correctly, the discount is displayed, but the tax (VAT) is wrong: the tax is not calculated on the items' discounted price, but on the original value.

Questions:

  • is the approach valid?
  • if not, what would be the alternative?
  • if so, what am I missing in order to have tax calculated / displayed correctly?

Thx.

wdelaet
  • 21
  • 6
  • I changed approach and now create a sales rule on the fly, attach it to the cart/quote and let the core magento functionality do the work... Tax calculation is now fine. – wdelaet Aug 18 '15 at 09:05
  • The remaining issue is that now it cannot be combined with another coupon, but that is work for later :) – wdelaet Aug 18 '15 at 09:06
  • Inspiration for creating sales rule on the fly (programatically )found [here](http://www.demacmedia.com/magento-commerce/mini-tutorial-creating-shopping-cart-rules-programatically/) and [here](http://inchoo.net/magento/programming-magento/programmatically-create-apply-and-delete-shopping-cart-price-rule-in-magento/) – wdelaet Aug 18 '15 at 09:11

0 Answers0