YAMB: Creditmemo with shippingInclTax > 0 and shippingAmount = 0

YAMB: Creditmemo with shippingInclTax > 0 and shippingAmount = 0

I think I just found yet another Magento Bug (YAMB).

I'm working on credit memos and want to add tax to adjustments (I hope I'll write a blog post about this soon - please remind me if you are interested).

I had the problem, that in \Mage_Sales_Model_Order_Creditmemo_Total_Shipping::collect the shippingAmount was 0 (as expected) but the shippingIncludingTax is the complete shipping amount (and is printed on our credit memos).

The problem ends here right before the end of the method.

$creditmemo->setShippingAmount($shipping);
$creditmemo->setBaseShippingAmount($baseShipping);
$creditmemo->setShippingInclTax($shippingInclTax);
$creditmemo->setBaseShippingInclTax($baseShippingInclTax);

I think the bug is the following problem. In the beginning all shipping values are initialized with the values from the order:

$shipping               = $order->getShippingAmount();
$baseShipping           = $order->getBaseShippingAmount();
$shippingInclTax        = $order->getShippingInclTax();
$baseShippingInclTax    = $order->getBaseShippingInclTax();

Due to the fact, that we do it through the backend, the following comment helps us. In the beginning I ignored the comment, and assumed that the baseShippingAmount is 0 and therefore the if shouldn't be entered.

$isShippingInclTax = Mage::getSingleton('tax/config')->displaySalesShippingInclTax($order->getStoreId());

/**
 * Check if shipping amount was specified (from invoice or another source).
 * Using has magic method to allow setting 0 as shipping amount.
 */
if ($creditmemo->hasBaseShippingAmount()) {
    $baseShippingAmount = Mage::app()->getStore()->roundPrice($creditmemo->getBaseShippingAmount());
    if ($isShippingInclTax && $baseShippingInclTax != 0) {
        $part = $baseShippingAmount/$baseShippingInclTax;
        $shippingInclTax    = Mage::app()->getStore()->roundPrice($shippingInclTax*$part);
        $baseShippingInclTax= $baseShippingAmount;
        $baseShippingAmount = Mage::app()->getStore()->roundPrice($baseShipping*$part);
    }

What happens here? We get the current setting for displaySalesShippingInclTax, which should be including tax (but was excluding tax in my case).

So, if the tax setting is "wrong" (excluding tax), we don't enter the if block.

If we enter it, the part of the shipping would be calculated which is refunded (0) and everything is updated. But when the if block is not entered, the shippingInclTax is not updated and therefore the value of shippingInclTax is not consistent with shippingAmount

Images is from Pixabay and CC0
Thanks to 777546-777546