Skip to content

Instantly share code, notes, and snippets.

@Schrank
Last active February 12, 2021 13:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Schrank/896561c841f564efb003c87441e90a4e to your computer and use it in GitHub Desktop.
Save Schrank/896561c841f564efb003c87441e90a4e to your computer and use it in GitHub Desktop.
Refund magento creditmemos with highest tax
<?xml version="1.0"?>
<config>
<modules>
<Customer_RefundPartialCreditmemoWithTax>
<version>1.0.0</version>
</Customer_RefundPartialCreditmemoWithTax>
</modules>
<global>
<models>
<customer_refundpartialcreditmemowithtax>
<class>Customer_RefundPartialCreditmemoWithTax_Model</class>
</customer_refundpartialcreditmemowithtax>
</models>
<sales>
<order_creditmemo>
<totals>
<tax>
<class>customer_refundpartialcreditmemowithtax/order_creditmemo_total_tax</class>
</tax>
</totals>
</order_creditmemo>
</sales>
</global>
</config>
<?php
class Customer_RefundPartialCreditmemoWithTax_Model_Order_Creditmemo_Total_Tax
extends Mage_Sales_Model_Order_Creditmemo_Total_Tax
{
public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo)
{
$shippingTaxAmount = 0;
$baseShippingTaxAmount = 0;
$totalHiddenTax = 0;
$baseTotalHiddenTax = 0;
$order = $creditmemo->getOrder();
list($totalTax, $baseTotalTax) = $this->calculateTaxForRefundAdjustment($creditmemo);
/** @var $item Mage_Sales_Model_Order_Creditmemo_Item */
foreach ($creditmemo->getAllItems() as $item) {
$orderItem = $item->getOrderItem();
if ($orderItem->isDummy()) {
continue;
}
$orderItemTax = $orderItem->getTaxInvoiced();
$baseOrderItemTax = $orderItem->getBaseTaxInvoiced();
$orderItemHiddenTax = $orderItem->getHiddenTaxInvoiced();
$baseOrderItemHiddenTax = $orderItem->getBaseHiddenTaxInvoiced();
$orderItemQty = $orderItem->getQtyInvoiced();
if (($orderItemTax || $orderItemHiddenTax) && $orderItemQty) {
/**
* Check item tax amount
*/
$tax = $orderItemTax - $orderItem->getTaxRefunded();
$baseTax = $baseOrderItemTax - $orderItem->getBaseTaxRefunded();
$hiddenTax = $orderItemHiddenTax - $orderItem->getHiddenTaxRefunded();
$baseHiddenTax = $baseOrderItemHiddenTax - $orderItem->getBaseHiddenTaxRefunded();
if (!$item->isLast()) {
$availableQty = $orderItemQty - $orderItem->getQtyRefunded();
$tax = $creditmemo->roundPrice($tax / $availableQty * $item->getQty());
$baseTax = $creditmemo->roundPrice($baseTax / $availableQty * $item->getQty(), 'base');
$hiddenTax = $creditmemo->roundPrice($hiddenTax / $availableQty * $item->getQty());
$baseHiddenTax = $creditmemo->roundPrice($baseHiddenTax / $availableQty * $item->getQty(), 'base');
}
$item->setTaxAmount($tax);
$item->setBaseTaxAmount($baseTax);
$item->setHiddenTaxAmount($hiddenTax);
$item->setBaseHiddenTaxAmount($baseHiddenTax);
$totalTax += $tax;
$baseTotalTax += $baseTax;
$totalHiddenTax += $hiddenTax;
$baseTotalHiddenTax += $baseHiddenTax;
}
}
$invoice = $creditmemo->getInvoice();
if ($invoice) {
//recalculate tax amounts in case if refund shipping value was changed
if ($order->getBaseShippingAmount() && $creditmemo->getBaseShippingAmount()) {
$taxFactor = $creditmemo->getBaseShippingAmount() / $order->getBaseShippingAmount();
$shippingTaxAmount = $invoice->getShippingTaxAmount() * $taxFactor;
$baseShippingTaxAmount = $invoice->getBaseShippingTaxAmount() * $taxFactor;
$totalHiddenTax += $invoice->getShippingHiddenTaxAmount() * $taxFactor;
$baseTotalHiddenTax += $invoice->getBaseShippingHiddenTaxAmount() * $taxFactor;
$shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount);
$baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base');
$totalHiddenTax = $creditmemo->roundPrice($totalHiddenTax);
$baseTotalHiddenTax = $creditmemo->roundPrice($baseTotalHiddenTax, 'base');
$totalTax += $shippingTaxAmount;
$baseTotalTax += $baseShippingTaxAmount;
}
} else {
$orderShippingAmount = $order->getShippingAmount();
$baseOrderShippingAmount = $order->getBaseShippingAmount();
$baseOrderShippingRefundedAmount = $order->getBaseShippingRefunded();
$shippingTaxAmount = 0;
$baseShippingTaxAmount = 0;
$shippingHiddenTaxAmount = 0;
$baseShippingHiddenTaxAmount = 0;
$shippingDelta = $baseOrderShippingAmount - $baseOrderShippingRefundedAmount;
if ($shippingDelta > $creditmemo->getBaseShippingAmount()) {
$part = $creditmemo->getShippingAmount() / $orderShippingAmount;
$basePart = $creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount;
$shippingTaxAmount = $order->getShippingTaxAmount() * $part;
$baseShippingTaxAmount = $order->getBaseShippingTaxAmount() * $basePart;
$shippingHiddenTaxAmount = $order->getShippingHiddenTaxAmount() * $part;
$baseShippingHiddenTaxAmount = $order->getBaseShippingHiddenTaxAmount() * $basePart;
$shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount);
$baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base');
$shippingHiddenTaxAmount = $creditmemo->roundPrice($shippingHiddenTaxAmount);
$baseShippingHiddenTaxAmount = $creditmemo->roundPrice($baseShippingHiddenTaxAmount, 'base');
} elseif ($shippingDelta == $creditmemo->getBaseShippingAmount()) {
$shippingTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded();
$baseShippingTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded();
$shippingHiddenTaxAmount = $order->getShippingHiddenTaxAmount()
- $order->getShippingHiddenTaxRefunded();
$baseShippingHiddenTaxAmount = $order->getBaseShippingHiddenTaxAmount()
- $order->getBaseShippingHiddenTaxRefunded();
}
$totalTax += $shippingTaxAmount;
$baseTotalTax += $baseShippingTaxAmount;
$totalHiddenTax += $shippingHiddenTaxAmount;
$baseTotalHiddenTax += $baseShippingHiddenTaxAmount;
}
$allowedTax = $order->getTaxInvoiced() - $order->getTaxRefunded() - $creditmemo->getTaxAmount();
$allowedBaseTax = $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded()
- $creditmemo->getBaseTaxAmount();
$allowedHiddenTax = $order->getHiddenTaxInvoiced() + $order->getShippingHiddenTaxAmount()
- $order->getHiddenTaxRefunded() - $order->getShippingHiddenTaxRefunded();
$allowedBaseHiddenTax = $order->getBaseHiddenTaxInvoiced() + $order->getBaseShippingHiddenTaxAmount()
- $order->getBaseHiddenTaxRefunded() - $order->getBaseShippingHiddenTaxRefunded();
$totalTax = min($allowedTax, $totalTax);
$baseTotalTax = min($allowedBaseTax, $baseTotalTax);
$totalHiddenTax = min($allowedHiddenTax, $totalHiddenTax);
$baseTotalHiddenTax = min($allowedBaseHiddenTax, $baseTotalHiddenTax);
$creditmemo->setTaxAmount($creditmemo->getTaxAmount() + $totalTax);
$creditmemo->setBaseTaxAmount($creditmemo->getBaseTaxAmount() + $baseTotalTax);
$creditmemo->setHiddenTaxAmount($totalHiddenTax);
$creditmemo->setBaseHiddenTaxAmount($baseTotalHiddenTax);
$creditmemo->setShippingTaxAmount($shippingTaxAmount);
$creditmemo->setBaseShippingTaxAmount($baseShippingTaxAmount);
$creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $totalTax + $totalHiddenTax);
$creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() + $baseTotalTax + $baseTotalHiddenTax);
return $this;
}
/**
* @param Mage_Sales_Model_Order_Creditmemo $creditmemo
* @return array
*/
private function calculateTaxForRefundAdjustment(Mage_Sales_Model_Order_Creditmemo $creditmemo)
{
/** @var Mage_Sales_Model_Order_Item $orderItems */
$orderItems = $creditmemo->getOrder()->getItemsCollection();
$taxPercentage = 0;
foreach ($orderItems as $item) {
$taxPercentage = max($taxPercentage, $item->getTaxPercent() / 100);
}
$totalAdjustment = $creditmemo->getAdjustmentPositive() - $creditmemo->getAdjustmentNegative();
$baseTotalAdjustment = $creditmemo->getBaseAdjustmentPositive() - $creditmemo->getBaseAdjustmentNegative();
// Adjustment values already include tax in my case. Modify calculation if you're entering values without tax
$totalAdjustmentTax = $totalAdjustment / ($taxPercentage + 1) * $taxPercentage;
$baseTotalAdjustmentTax = $baseTotalAdjustment / ($taxPercentage + 1) * $taxPercentage;
$creditmemo->setGrandTotal($creditmemo->getGrandTotal() - $totalAdjustmentTax);
$creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() - $baseTotalAdjustmentTax);
return [$totalAdjustmentTax, $baseTotalAdjustmentTax];
}
}
@sanderjongsma
Copy link

Awesome

@sreichel
Copy link

sreichel commented Jan 25, 2021

Should L35 ...

$baseTax = $baseOrderItemTax - $orderItem->getTaxRefunded();

not be

$baseTax = $baseOrderItemTax - $orderItem->getBaseTaxRefunded();

And L160-161 can be removed?

@Schrank
Copy link
Author

Schrank commented Feb 11, 2021

Thanks @sreichel for the tax, fixed.
But I'm not sure about L160/161 🤷

@sreichel
Copy link

sreichel commented Feb 12, 2021

@Schrank L160-161 is set in 135-136. Isnt it?

@Schrank
Copy link
Author

Schrank commented Feb 12, 2021

From the first look, I think we need all four lines. In 160/61 I remove the adjustment tax and later I'll add other taxes. I think this is all right. But we'll leave this discussion here - if someone (e.g. you :D ) tests it and tells me we don't need it I'll leave a comment and remove it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment