/** * This method generates a set of line items, which represents the delta of the amount change. * * * @param Customweb_Payment_Authorization_IInvoiceItem[] $originalLineItems List of line items on which the delta based on. * @param float $amount The reduction amount. * @return Customweb_Payment_Authorization_IInvoiceItem[] The set of line items, which represents the delta. */ public static function getItemsByReductionAmount(array $originalLineItems, $amount, $currencyCode) { if (count($originalLineItems) <= 0) { throw new Exception("No line items provided."); } $total = self::getTotalAmountIncludingTax($originalLineItems); $factor = $amount / $total; $appliedTotal = 0; $newItems = array(); foreach ($originalLineItems as $item) { /* @var $item Customweb_Payment_Authorization_IInvoiceItem */ $newAmount = Customweb_Util_Currency::roundAmount($item->getAmountIncludingTax() * $factor, $currencyCode); $newItem = new Customweb_Payment_Authorization_DefaultInvoiceItem($item->getSku(), $item->getName(), $item->getTaxRate(), $newAmount, $item->getQuantity(), $item->getType(), $item->getOriginalSku()); $newItems[] = $newItem; if ($item->getType() == Customweb_Payment_Authorization_DefaultInvoiceItem::TYPE_DISCOUNT) { $appliedTotal -= $newAmount; } else { $appliedTotal += $newAmount; } } // Fix rounding error $roundingDifference = $amount - $appliedTotal; $item = $newItems[0]; $newAmount = $item->getAmountIncludingTax() + $roundingDifference; $newItems[0] = new Customweb_Payment_Authorization_DefaultInvoiceItem($item->getSku(), $item->getName(), $item->getTaxRate(), $newAmount, $item->getQuantity(), $item->getType(), $item->getOriginalSku()); return $newItems; }
public function refundByLineItemsDry(array $items, $close = false, $additionalMessage = '') { $amount = Customweb_Util_Invoice::getTotalAmountIncludingTax($items); if (!$this->isAuthorized()) { throw new Exception(Customweb_I18n_Translation::__("Only authorized transaction can be refunded.")); } if ($this->refundClosed) { throw new Exception(Customweb_I18n_Translation::__("This transaction is already closed for further refunds.")); } if ($this->isCancelled()) { throw new Exception(Customweb_I18n_Translation::__("A cancelled transaction cannot be refunded.")); } if (!$this->isCaptured()) { throw new Exception(Customweb_I18n_Translation::__("Only captured transaction can be refunded.")); } $newTotalRefundedAmount = $amount + $this->getRefundedTotalAmount(); if (Customweb_Util_Currency::roundAmount($newTotalRefundedAmount, $this->getCurrencyCode()) > Customweb_Util_Currency::roundAmount($this->getCapturedAmount(), $this->getCurrencyCode())) { throw new Exception(Customweb_I18n_Translation::__("The total refund amount (!totalRefundedAmount) cannot be greater than the captured amount (!capturedAmount).", array('!totalRefundedAmount' => $newTotalRefundedAmount, '!capturedAmount' => $this->getCapturedAmount()))); } // Check that the amounts of the single items are not higher as the original ones. $originalItems = $this->getCapturedLineItems(); $originalItemMap = array(); foreach ($originalItems as $item) { $originalItemMap[$item->getSku()] = $item; } foreach ($items as $item) { if ($item instanceof Customweb_Payment_Authorization_IInvoiceItem) { if (!isset($originalItemMap[$item->getSku()])) { throw new Exception(Customweb_I18n_Translation::__("The refund item with SKU '@sku' is not present in the original order.", array('@sku' => $item->getSku()))); } if (Customweb_Util_Currency::compareAmount($item->getAmountIncludingTax(), $originalItemMap[$item->getSku()]->getAmountIncludingTax(), $this->getCurrencyCode()) > 0) { throw new Exception(Customweb_I18n_Translation::__("The refund item with SKU '@sku' has a higher amount (@amountItem) as the original item (@amountOriginal).", array('@sku' => $item->getSku(), '@amountItem' => Customweb_Util_Currency::formatAmount($item->getAmountIncludingTax(), $this->getCurrencyCode()), '@amountOriginal' => Customweb_Util_Currency::formatAmount($originalItemMap[$item->getSku()]->getAmountIncludingTax(), $this->getCurrencyCode())))); } } } return $this; }