/** * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this * * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) { $shippingTaxAmount = 0; $baseShippingTaxAmount = 0; $totalTax = 0; $baseTotalTax = 0; $totalDiscountTaxCompensation = 0; $baseTotalDiscountTaxCompensation = 0; $order = $creditmemo->getOrder(); /** @var $item \Magento\Sales\Model\Order\Creditmemo\Item */ foreach ($creditmemo->getAllItems() as $item) { $orderItem = $item->getOrderItem(); if ($orderItem->isDummy() || $item->getQty() <= 0) { continue; } $orderItemTax = (double) $orderItem->getTaxInvoiced(); $baseOrderItemTax = (double) $orderItem->getBaseTaxInvoiced(); $orderItemQty = (double) $orderItem->getQtyInvoiced(); if ($orderItemTax && $orderItemQty) { /** * Check item tax amount */ $tax = $orderItemTax - $orderItem->getTaxRefunded(); $baseTax = $baseOrderItemTax - $orderItem->getBaseTaxRefunded(); $discountTaxCompensation = $orderItem->getDiscountTaxCompensationInvoiced() - $orderItem->getDiscountTaxCompensationRefunded(); $baseDiscountTaxCompensation = $orderItem->getBaseDiscountTaxCompensationInvoiced() - $orderItem->getBaseDiscountTaxCompensationRefunded(); if (!$item->isLast()) { $availableQty = $orderItemQty - $orderItem->getQtyRefunded(); $tax = $creditmemo->roundPrice($tax / $availableQty * $item->getQty()); $baseTax = $creditmemo->roundPrice($baseTax / $availableQty * $item->getQty(), 'base'); $discountTaxCompensation = $creditmemo->roundPrice($discountTaxCompensation / $availableQty * $item->getQty()); $baseDiscountTaxCompensation = $creditmemo->roundPrice($baseDiscountTaxCompensation / $availableQty * $item->getQty(), 'base'); } $item->setTaxAmount($tax); $item->setBaseTaxAmount($baseTax); $item->setDiscountTaxCompensationAmount($discountTaxCompensation); $item->setBaseDiscountTaxCompensationAmount($baseDiscountTaxCompensation); $totalTax += $tax; $baseTotalTax += $baseTax; $totalDiscountTaxCompensation += $discountTaxCompensation; $baseTotalDiscountTaxCompensation += $baseDiscountTaxCompensation; } } $isPartialShippingRefunded = false; if ($invoice = $creditmemo->getInvoice()) { //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; $totalDiscountTaxCompensation += $invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor; $baseTotalDiscountTaxCompensation += $invoice->getBaseShippingDiscountTaxCompensationAmnt() * $taxFactor; $shippingDiscountTaxCompensationAmount = $invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor; $baseShippingDiscountTaxCompensationAmount = $invoice->getBaseShippingDiscountTaxCompensationAmnt() * $taxFactor; $shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount); $baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base'); $totalDiscountTaxCompensation = $creditmemo->roundPrice($totalDiscountTaxCompensation); $baseTotalDiscountTaxCompensation = $creditmemo->roundPrice($baseTotalDiscountTaxCompensation, 'base'); $shippingDiscountTaxCompensationAmount = $creditmemo->roundPrice($shippingDiscountTaxCompensationAmount); $baseShippingDiscountTaxCompensationAmount = $creditmemo->roundPrice($baseShippingDiscountTaxCompensationAmount, 'base'); if ($taxFactor < 1 && $invoice->getShippingTaxAmount() > 0) { $isPartialShippingRefunded = true; } $totalTax += $shippingTaxAmount; $baseTotalTax += $baseShippingTaxAmount; } } else { $orderShippingAmount = $order->getShippingAmount(); $baseOrderShippingAmount = $order->getBaseShippingAmount(); $baseOrderShippingRefundedAmount = $order->getBaseShippingRefunded(); $shippingTaxAmount = 0; $baseShippingTaxAmount = 0; $shippingDiscountTaxCompensationAmount = 0; $baseShippingDiscountTaxCompensationAmount = 0; $shippingDelta = $baseOrderShippingAmount - $baseOrderShippingRefundedAmount; if ($shippingDelta > $creditmemo->getBaseShippingAmount()) { $part = $creditmemo->getShippingAmount() / $orderShippingAmount; $basePart = $creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount; $shippingTaxAmount = $order->getShippingTaxAmount() * $part; $baseShippingTaxAmount = $order->getBaseShippingTaxAmount() * $basePart; $shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount() * $part; $baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt() * $basePart; $shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount); $baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base'); $shippingDiscountTaxCompensationAmount = $creditmemo->roundPrice($shippingDiscountTaxCompensationAmount); $baseShippingDiscountTaxCompensationAmount = $creditmemo->roundPrice($baseShippingDiscountTaxCompensationAmount, 'base'); if ($part < 1 && $order->getShippingTaxAmount() > 0) { $isPartialShippingRefunded = true; } } elseif ($shippingDelta == $creditmemo->getBaseShippingAmount()) { $shippingTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded(); $baseShippingTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded(); $shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount() - $order->getShippingDiscountTaxCompensationRefunded(); $baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt() - $order->getBaseShippingDiscountTaxCompensationRefunded(); } $totalTax += $shippingTaxAmount; $baseTotalTax += $baseShippingTaxAmount; $totalDiscountTaxCompensation += $shippingDiscountTaxCompensationAmount; $baseTotalDiscountTaxCompensation += $baseShippingDiscountTaxCompensationAmount; } $allowedTax = $order->getTaxInvoiced() - $order->getTaxRefunded() - $creditmemo->getTaxAmount(); $allowedBaseTax = $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded() - $creditmemo->getBaseTaxAmount(); $allowedDiscountTaxCompensation = $order->getDiscountTaxCompensationInvoiced() + $order->getShippingDiscountTaxCompensationAmount() - $order->getDiscountTaxCompensationRefunded() - $order->getShippingDiscountTaxCompensationRefunded() - $creditmemo->getDiscountTaxCompensationAmount() - $creditmemo->getShippingDiscountTaxCompensationAmount(); $allowedBaseDiscountTaxCompensation = $order->getBaseDiscountTaxCompensationInvoiced() + $order->getBaseShippingDiscountTaxCompensationAmnt() - $order->getBaseDiscountTaxCompensationRefunded() - $order->getBaseShippingDiscountTaxCompensationRefunded() - $creditmemo->getBaseShippingDiscountTaxCompensationAmnt() - $creditmemo->getBaseDiscountTaxCompensationAmount(); if ($creditmemo->isLast() && !$isPartialShippingRefunded) { $totalTax = $allowedTax; $baseTotalTax = $allowedBaseTax; $totalDiscountTaxCompensation = $allowedDiscountTaxCompensation; $baseTotalDiscountTaxCompensation = $allowedBaseDiscountTaxCompensation; } else { $totalTax = min($allowedTax, $totalTax); $baseTotalTax = min($allowedBaseTax, $baseTotalTax); $totalDiscountTaxCompensation = min($allowedDiscountTaxCompensation, $totalDiscountTaxCompensation); $baseTotalDiscountTaxCompensation = min($allowedBaseDiscountTaxCompensation, $baseTotalDiscountTaxCompensation); } $creditmemo->setTaxAmount($creditmemo->getTaxAmount() + $totalTax); $creditmemo->setBaseTaxAmount($creditmemo->getBaseTaxAmount() + $baseTotalTax); $creditmemo->setDiscountTaxCompensationAmount($totalDiscountTaxCompensation); $creditmemo->setBaseDiscountTaxCompensationAmount($baseTotalDiscountTaxCompensation); $creditmemo->setShippingTaxAmount($shippingTaxAmount); $creditmemo->setBaseShippingTaxAmount($baseShippingTaxAmount); $creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $totalTax + $totalDiscountTaxCompensation); $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() + $baseTotalTax + $baseTotalDiscountTaxCompensation); return $this; }
/** * Collect Weee amounts for the credit memo * * @param Creditmemo $creditmemo * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function collect(Creditmemo $creditmemo) { $store = $creditmemo->getStore(); $totalWeeeAmount = 0; $baseTotalWeeeAmount = 0; $totalWeeeAmountInclTax = 0; $baseTotalWeeeAmountInclTax = 0; $totalTaxAmount = 0; $baseTotalTaxAmount = 0; foreach ($creditmemo->getAllItems() as $item) { $orderItem = $item->getOrderItem(); $orderItemQty = $orderItem->getQtyOrdered(); if (!$orderItemQty || $orderItem->isDummy() || $item->getQty() < 0) { continue; } $ratio = $item->getQty() / $orderItemQty; $orderItemWeeeAmountExclTax = $orderItem->getWeeeTaxAppliedRowAmount(); $orderItemBaseWeeeAmountExclTax = $orderItem->getBaseWeeeTaxAppliedRowAmnt(); $weeeAmountExclTax = $creditmemo->roundPrice($orderItemWeeeAmountExclTax * $ratio); $baseWeeeAmountExclTax = $creditmemo->roundPrice($orderItemBaseWeeeAmountExclTax * $ratio, 'base'); $orderItemWeeeAmountInclTax = $this->_weeeData->getRowWeeeTaxInclTax($orderItem); $orderItemBaseWeeeAmountInclTax = $this->_weeeData->getBaseRowWeeeTaxInclTax($orderItem); $weeeAmountInclTax = $creditmemo->roundPrice($orderItemWeeeAmountInclTax * $ratio); $baseWeeeAmountInclTax = $creditmemo->roundPrice($orderItemBaseWeeeAmountInclTax * $ratio, 'base'); $itemTaxAmount = $weeeAmountInclTax - $weeeAmountExclTax; $itemBaseTaxAmount = $baseWeeeAmountInclTax - $baseWeeeAmountExclTax; $weeeAmountAvailable = $this->_weeeData->getWeeeAmountInvoiced($orderItem) - $this->_weeeData->getWeeeAmountRefunded($orderItem); $baseWeeeAmountAvailable = $this->_weeeData->getBaseWeeeAmountInvoiced($orderItem) - $this->_weeeData->getBaseWeeeAmountRefunded($orderItem); $weeeTaxAmountAvailable = $this->_weeeData->getWeeeTaxAmountInvoiced($orderItem) - $this->_weeeData->getWeeeTaxAmountRefunded($orderItem); $baseWeeeTaxAmountAvailable = $this->_weeeData->getBaseWeeeTaxAmountInvoiced($orderItem) - $this->_weeeData->getBaseWeeeTaxAmountRefunded($orderItem); if ($item->isLast()) { $weeeAmountExclTax = $weeeAmountAvailable; $baseWeeeAmountExclTax = $baseWeeeAmountAvailable; $itemTaxAmount = $weeeTaxAmountAvailable; $itemBaseTaxAmount = $baseWeeeTaxAmountAvailable; } else { $weeeAmountExclTax = min($weeeAmountExclTax, $weeeAmountAvailable); $baseWeeeAmountExclTax = min($baseWeeeAmountExclTax, $baseWeeeAmountAvailable); $itemTaxAmount = min($itemTaxAmount, $weeeTaxAmountAvailable); $itemBaseTaxAmount = min($itemBaseTaxAmount, $baseWeeeTaxAmountAvailable); } $totalWeeeAmount += $weeeAmountExclTax; $baseTotalWeeeAmount += $baseWeeeAmountExclTax; $item->setWeeeTaxAppliedRowAmount($weeeAmountExclTax); $item->setBaseWeeeTaxAppliedRowAmount($baseWeeeAmountExclTax); $totalTaxAmount += $itemTaxAmount; $baseTotalTaxAmount += $itemBaseTaxAmount; //Set the ratio of the tax amount in invoice item compared to tax amount in order item //This information is needed to calculate tax per tax rate later $orderItemTaxAmount = $orderItemWeeeAmountInclTax - $orderItemWeeeAmountExclTax; if ($orderItemTaxAmount != 0) { $taxRatio = []; if ($item->getTaxRatio()) { $taxRatio = unserialize($item->getTaxRatio()); } $taxRatio[\Magento\Weee\Model\Total\Quote\Weee::ITEM_TYPE] = $itemTaxAmount / $orderItemTaxAmount; $item->setTaxRatio(serialize($taxRatio)); } $totalWeeeAmountInclTax += $weeeAmountInclTax; $baseTotalWeeeAmountInclTax += $baseWeeeAmountInclTax; $newApplied = []; $applied = $this->_weeeData->getApplied($orderItem); foreach ($applied as $one) { $title = (string) $one['title']; $one['base_row_amount'] = $creditmemo->roundPrice($one['base_row_amount'] * $ratio, $title . '_base'); $one['row_amount'] = $creditmemo->roundPrice($one['row_amount'] * $ratio, $title); $one['base_row_amount_incl_tax'] = $creditmemo->roundPrice($one['base_row_amount_incl_tax'] * $ratio, $title . '_base'); $one['row_amount_incl_tax'] = $creditmemo->roundPrice($one['row_amount_incl_tax'] * $ratio, $title); $newApplied[] = $one; } $this->_weeeData->setApplied($item, $newApplied); // Update order item $newApplied = []; $applied = $this->_weeeData->getApplied($orderItem); foreach ($applied as $one) { if (isset($one[WeeeHelper::KEY_BASE_WEEE_AMOUNT_REFUNDED])) { $one[WeeeHelper::KEY_BASE_WEEE_AMOUNT_REFUNDED] = $one[WeeeHelper::KEY_BASE_WEEE_AMOUNT_REFUNDED] + $baseWeeeAmountExclTax; } else { $one[WeeeHelper::KEY_BASE_WEEE_AMOUNT_REFUNDED] = $baseWeeeAmountExclTax; } if (isset($one[WeeeHelper::KEY_WEEE_AMOUNT_REFUNDED])) { $one[WeeeHelper::KEY_WEEE_AMOUNT_REFUNDED] = $one[WeeeHelper::KEY_WEEE_AMOUNT_REFUNDED] + $weeeAmountExclTax; } else { $one[WeeeHelper::KEY_WEEE_AMOUNT_REFUNDED] = $weeeAmountExclTax; } if (isset($one[WeeeHelper::KEY_BASE_WEEE_TAX_AMOUNT_REFUNDED])) { $one[WeeeHelper::KEY_BASE_WEEE_TAX_AMOUNT_REFUNDED] = $one[WeeeHelper::KEY_BASE_WEEE_TAX_AMOUNT_REFUNDED] + $itemBaseTaxAmount; } else { $one[WeeeHelper::KEY_BASE_WEEE_TAX_AMOUNT_REFUNDED] = $itemBaseTaxAmount; } if (isset($one[WeeeHelper::KEY_WEEE_TAX_AMOUNT_REFUNDED])) { $one[WeeeHelper::KEY_WEEE_TAX_AMOUNT_REFUNDED] = $one[WeeeHelper::KEY_WEEE_TAX_AMOUNT_REFUNDED] + $itemTaxAmount; } else { $one[WeeeHelper::KEY_WEEE_TAX_AMOUNT_REFUNDED] = $itemTaxAmount; } $newApplied[] = $one; } $this->_weeeData->setApplied($orderItem, $newApplied); $item->setWeeeTaxRowDisposition($item->getWeeeTaxDisposition() * $item->getQty()); $item->setBaseWeeeTaxRowDisposition($item->getBaseWeeeTaxDisposition() * $item->getQty()); } if ($this->_weeeData->includeInSubtotal($store)) { $creditmemo->setSubtotal($creditmemo->getSubtotal() + $totalWeeeAmount); $creditmemo->setBaseSubtotal($creditmemo->getBaseSubtotal() + $baseTotalWeeeAmount); } $creditmemo->setTaxAmount($creditmemo->getTaxAmount() + $totalTaxAmount); $creditmemo->setBaseTaxAmount($creditmemo->getBaseTaxAmount() + $baseTotalTaxAmount); $creditmemo->setSubtotalInclTax($creditmemo->getSubtotalInclTax() + $totalWeeeAmountInclTax); $creditmemo->setBaseSubtotalInclTax($creditmemo->getBaseSubtotalInclTax() + $baseTotalWeeeAmountInclTax); $creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $totalWeeeAmount + $totalTaxAmount); $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() + $baseTotalWeeeAmount + $baseTotalTaxAmount); return $this; }