I have already used the event sales_order_place_after




                    $canAddItems = $quote->isVirtual() ? ('billing') : ('shipping');
                    foreach ($quote->getAllAddresses() as $address) {




                        $quote->setSubtotal((float) $quote->getSubtotal() + $address->getSubtotal());
                        $quote->setBaseSubtotal((float) $quote->getBaseSubtotal() + $address->getBaseSubtotal());

                                (float) $quote->getSubtotalWithDiscount() + $address->getSubtotalWithDiscount()
                                (float) $quote->getBaseSubtotalWithDiscount() + $address->getBaseSubtotalWithDiscount()

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


                        $quote->setGrandTotal($quote->getBaseSubtotal() - $discountAmount)
                                ->setBaseGrandTotal($quote->getBaseSubtotal() - $discountAmount)
                                ->setSubtotalWithDiscount($quote->getBaseSubtotal() - $discountAmount)
                                ->setBaseSubtotalWithDiscount($quote->getBaseSubtotal() - $discountAmount)

                        if ($address->getAddressType() == $canAddItems) {
                            //echo $address->setDiscountAmount; exit;
                            $address->setSubtotalWithDiscount((float) $address->getSubtotalWithDiscount() - $discountAmount);
                            $address->setGrandTotal((float) $address->getGrandTotal() - $discountAmount);
                            $address->setBaseSubtotalWithDiscount((float) $address->getBaseSubtotalWithDiscount() - $discountAmount);
                            $address->setBaseGrandTotal((float) $address->getBaseGrandTotal() - $discountAmount);
                            if ($address->getDiscountDescription()) {
                                $address->setDiscountAmount(-($address->getDiscountAmount() - $discountAmount));
                                $address->setDiscountDescription($address->getDiscountDescription() . ', Company Discount');
                                $address->setBaseDiscountAmount(-($address->getBaseDiscountAmount() - $discountAmount));
                            } else {
                                $address->setDiscountDescription('Company Discount');
                        }//end: if
                    } //end: foreach
                    //echo $quote->getGrandTotal();

                    foreach ($quote->getAllItems() as $item) {
                        //We apply discount amount based on the ratio between the GrandTotal and the RowTotal
                        $rat = $item->getPrice() / $total;
                        $ratdisc = $discountAmount * $rat;
                        $item->setDiscountAmount($item->getDiscountAmount() + $ratdisc * $item->getQty());
                        $item->setBaseDiscountAmount($item->getBaseDiscountAmount() + $ratdisc * $item->getQty())->save();

Now, the problem I'm facing is, Tax setting is, Apply Tax After Discount, but Tax is calculated before this custom discount.

1 Answer 1


I'm not sure to understand well your problem but you are starting from a quote to do a discount based on the address informations.

It can be better to wait that you have a real order and at this moment all the address informations will be filled, that might not be the case at the quote state.

If you do the same behaviour starting on the order you ll probably have your discount well calculated and then the taxes that will apply on this amount.

Keep me in touch if it is better.

  • Did you solve your problem?
    – Nicolas D
    Commented Oct 19, 2015 at 10:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.