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.