/** * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this * @throws \Magento\Framework\Exception\LocalizedException */ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) { $order = $creditmemo->getOrder(); $allowedAmount = $order->getShippingAmount() - $order->getShippingRefunded(); $baseAllowedAmount = $order->getBaseShippingAmount() - $order->getBaseShippingRefunded(); $orderShippingAmount = $order->getShippingAmount(); $orderBaseShippingAmount = $order->getBaseShippingAmount(); $orderShippingInclTax = $order->getShippingInclTax(); $orderBaseShippingInclTax = $order->getBaseShippingInclTax(); $shippingAmount = $baseShippingAmount = $shippingInclTax = $baseShippingInclTax = 0; /** * 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 = $this->priceCurrency->round($creditmemo->getBaseShippingAmount()); /* * Rounded allowed shipping refund amount is the highest acceptable shipping refund amount. * Shipping refund amount shouldn't cause errors, if it doesn't exceed that limit. * Note: ($x < $y + 0.0001) means ($x <= $y) for floats */ if ($baseShippingAmount < $this->priceCurrency->round($baseAllowedAmount) + 0.0001) { $ratio = 0; if ($orderBaseShippingAmount > 0) { $ratio = $baseShippingAmount / $orderBaseShippingAmount; } /* * Shipping refund amount should be equated to allowed refund amount, * if it exceeds that limit. * Note: ($x > $y - 0.0001) means ($x >= $y) for floats */ if ($baseShippingAmount > $baseAllowedAmount - 0.0001) { $shippingAmount = $allowedAmount; $baseShippingAmount = $baseAllowedAmount; } else { $shippingAmount = $this->priceCurrency->round($orderShippingAmount * $ratio); } $shippingInclTax = $this->priceCurrency->round($orderShippingInclTax * $ratio); $baseShippingInclTax = $this->priceCurrency->round($orderBaseShippingInclTax * $ratio); } else { $baseAllowedAmount = $order->getBaseCurrency()->format($baseAllowedAmount, null, false); throw new \Magento\Framework\Exception\LocalizedException(__('Maximum shipping amount allowed to refund is: %1', $baseAllowedAmount)); } } else { $shippingAmount = $allowedAmount; $baseShippingAmount = $baseAllowedAmount; $allowedTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded(); $baseAllowedTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded(); $shippingInclTax = $this->priceCurrency->round($allowedAmount + $allowedTaxAmount); $baseShippingInclTax = $this->priceCurrency->round($baseAllowedAmount + $baseAllowedTaxAmount); } $creditmemo->setShippingAmount($shippingAmount); $creditmemo->setBaseShippingAmount($baseShippingAmount); $creditmemo->setShippingInclTax($shippingInclTax); $creditmemo->setBaseShippingInclTax($baseShippingInclTax); $creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $shippingAmount); $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() + $baseShippingAmount); return $this; }
/** * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this * @throws \Magento\Framework\Exception\LocalizedException */ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) { $order = $creditmemo->getOrder(); // amounts without tax $orderShippingAmount = $order->getShippingAmount(); $orderBaseShippingAmount = $order->getBaseShippingAmount(); $allowedAmount = $orderShippingAmount - $order->getShippingRefunded(); $baseAllowedAmount = $orderBaseShippingAmount - $order->getBaseShippingRefunded(); // amounts including tax $orderShippingInclTax = $order->getShippingInclTax(); $orderBaseShippingInclTax = $order->getBaseShippingInclTax(); $allowedTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded(); $baseAllowedTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded(); $allowedAmountInclTax = $allowedAmount + $allowedTaxAmount; $baseAllowedAmountInclTax = $baseAllowedAmount + $baseAllowedTaxAmount; // for the credit memo $shippingAmount = $baseShippingAmount = $shippingInclTax = $baseShippingInclTax = 0; // Check if the desired shipping amount to refund was specified (from invoice or another source). if ($creditmemo->hasBaseShippingAmount()) { // For the conditional logic, we will either use amounts that always include tax -OR- never include tax. // The logic uses the 'base' currency to be consistent with what the user (admin) provided as input. $useAmountsWithTax = $this->isSuppliedShippingAmountInclTax($order); // Since the user (admin) supplied 'desiredAmount' it already has tax -OR- does not include tax $desiredAmount = $this->priceCurrency->round($creditmemo->getBaseShippingAmount()); $maxAllowedAmount = $useAmountsWithTax ? $baseAllowedAmountInclTax : $baseAllowedAmount; $originalTotalAmount = $useAmountsWithTax ? $orderBaseShippingInclTax : $orderBaseShippingAmount; // Note: ($x < $y + 0.0001) means ($x <= $y) for floats if ($desiredAmount < $this->priceCurrency->round($maxAllowedAmount) + 0.0001) { // since the admin is returning less than the allowed amount, compute the ratio being returned $ratio = 0; if ($originalTotalAmount > 0) { $ratio = $desiredAmount / $originalTotalAmount; } // capture amounts without tax // Note: ($x > $y - 0.0001) means ($x >= $y) for floats if ($desiredAmount > $maxAllowedAmount - 0.0001) { $shippingAmount = $allowedAmount; $baseShippingAmount = $baseAllowedAmount; } else { $shippingAmount = $this->priceCurrency->round($orderShippingAmount * $ratio); $baseShippingAmount = $this->priceCurrency->round($orderBaseShippingAmount * $ratio); } $shippingInclTax = $this->priceCurrency->round($orderShippingInclTax * $ratio); $baseShippingInclTax = $this->priceCurrency->round($orderBaseShippingInclTax * $ratio); } else { $maxAllowedAmount = $order->getBaseCurrency()->format($maxAllowedAmount, null, false); throw new \Magento\Framework\Exception\LocalizedException(__('Maximum shipping amount allowed to refund is: %1', $maxAllowedAmount)); } } else { $shippingAmount = $allowedAmount; $baseShippingAmount = $baseAllowedAmount; $shippingInclTax = $this->priceCurrency->round($allowedAmountInclTax); $baseShippingInclTax = $this->priceCurrency->round($baseAllowedAmountInclTax); } $creditmemo->setShippingAmount($shippingAmount); $creditmemo->setBaseShippingAmount($baseShippingAmount); $creditmemo->setShippingInclTax($shippingInclTax); $creditmemo->setBaseShippingInclTax($baseShippingInclTax); $creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $shippingAmount); $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() + $baseShippingAmount); return $this; }