Пример #1
0
 /**
  * Prepare order data for refund
  *
  * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo
  * @return void
  */
 protected function prepareOrder(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
 {
     $order = $creditmemo->getOrder();
     $baseOrderRefund = $this->priceCurrency->round($order->getBaseTotalRefunded() + $creditmemo->getBaseGrandTotal());
     $orderRefund = $this->priceCurrency->round($order->getTotalRefunded() + $creditmemo->getGrandTotal());
     $order->setBaseTotalRefunded($baseOrderRefund);
     $order->setTotalRefunded($orderRefund);
     $order->setBaseSubtotalRefunded($order->getBaseSubtotalRefunded() + $creditmemo->getBaseSubtotal());
     $order->setSubtotalRefunded($order->getSubtotalRefunded() + $creditmemo->getSubtotal());
     $order->setBaseTaxRefunded($order->getBaseTaxRefunded() + $creditmemo->getBaseTaxAmount());
     $order->setTaxRefunded($order->getTaxRefunded() + $creditmemo->getTaxAmount());
     $order->setBaseDiscountTaxCompensationRefunded($order->getBaseDiscountTaxCompensationRefunded() + $creditmemo->getBaseDiscountTaxCompensationAmount());
     $order->setDiscountTaxCompensationRefunded($order->getDiscountTaxCompensationRefunded() + $creditmemo->getDiscountTaxCompensationAmount());
     $order->setBaseShippingRefunded($order->getBaseShippingRefunded() + $creditmemo->getBaseShippingAmount());
     $order->setShippingRefunded($order->getShippingRefunded() + $creditmemo->getShippingAmount());
     $order->setBaseShippingTaxRefunded($order->getBaseShippingTaxRefunded() + $creditmemo->getBaseShippingTaxAmount());
     $order->setShippingTaxRefunded($order->getShippingTaxRefunded() + $creditmemo->getShippingTaxAmount());
     $order->setAdjustmentPositive($order->getAdjustmentPositive() + $creditmemo->getAdjustmentPositive());
     $order->setBaseAdjustmentPositive($order->getBaseAdjustmentPositive() + $creditmemo->getBaseAdjustmentPositive());
     $order->setAdjustmentNegative($order->getAdjustmentNegative() + $creditmemo->getAdjustmentNegative());
     $order->setBaseAdjustmentNegative($order->getBaseAdjustmentNegative() + $creditmemo->getBaseAdjustmentNegative());
     $order->setDiscountRefunded($order->getDiscountRefunded() + $creditmemo->getDiscountAmount());
     $order->setBaseDiscountRefunded($order->getBaseDiscountRefunded() + $creditmemo->getBaseDiscountAmount());
     if ($creditmemo->getDoTransaction()) {
         $order->setTotalOnlineRefunded($order->getTotalOnlineRefunded() + $creditmemo->getGrandTotal());
         $order->setBaseTotalOnlineRefunded($order->getBaseTotalOnlineRefunded() + $creditmemo->getBaseGrandTotal());
     } else {
         $order->setTotalOfflineRefunded($order->getTotalOfflineRefunded() + $creditmemo->getGrandTotal());
         $order->setBaseTotalOfflineRefunded($order->getBaseTotalOfflineRefunded() + $creditmemo->getBaseGrandTotal());
     }
     $order->setBaseTotalInvoicedCost($order->getBaseTotalInvoicedCost() - $creditmemo->getBaseCost());
 }
Пример #2
0
 /**
  * Filter value
  *
  * @param float $value
  * @return string
  */
 public function filter($value)
 {
     $value = $this->_localeFormat->getNumber($value);
     $value = $this->priceCurrency->round($this->_rate * $value);
     $value = sprintf("%f", $value);
     return $this->_currency->toCurrency($value);
 }
 /**
  * MOBI-486: Add partial payment data to totals are requested with REST API.
  * MOBI-489: Add partial payment configuration to totals extension attributes.
  *
  * @param \Magento\Quote\Model\Cart\CartTotalRepository $subject
  * @param \Closure $proceed
  * @param $cartId
  * @return \Magento\Quote\Api\Data\TotalsInterface
  */
 public function aroundGet(\Magento\Quote\Model\Cart\CartTotalRepository $subject, \Closure $proceed, $cartId)
 {
     /** @var \Magento\Quote\Model\Cart\Totals $result */
     $result = $proceed($cartId);
     /* Get partial method configuration */
     $isPartialEnabled = $this->_hlpCfg->getWalletPartialEnabled();
     if ($isPartialEnabled) {
         //            $partialMaxPercent = $this->_hlpCfg->getWalletPartialPercent();
         //            /** @var \Magento\Quote\Api\Data\TotalExtensionInterface $exts */
         //            $exts = $this->_factTotalExt->create();
         //            /** @var \Praxigento\Wallet\Api\Data\Config\Payment\Method $extData */
         //            $extData = new \Praxigento\Wallet\Api\Data\Config\Payment\Method();
         //            $extData->setPartialMaxPercent($partialMaxPercent);
         //            $extData->setIsPartialEnabled($isPartialEnabled);
         //            $exts->setPraxigentoWalletPaymentConfig($extData);
         //            $result->setExtensionAttributes($exts);
         /* get partial data from repository */
         /** @var \Praxigento\Wallet\Data\Entity\Partial\Quote $found */
         $found = $this->_repoPartialQuote->getById($cartId);
         if ($found) {
             $basePartial = $found->getBasePartialAmount();
             $basePartial = $this->_hlpPriceCurrency->round($basePartial);
             /* add current partial total to segment */
             $segments = $result->getTotalSegments();
             /** @var \Magento\Quote\Api\Data\TotalSegmentInterface $seg */
             $seg = $this->_manObj->create(\Magento\Quote\Api\Data\TotalSegmentInterface::class);
             $seg->setCode(self::TOTAL_SEGMENT);
             $seg->setValue($basePartial);
             $segments[self::TOTAL_SEGMENT] = $seg;
             $result->setTotalSegments($segments);
         }
     }
     return $result;
 }
Пример #4
0
 /**
  * Get credit memo shipping amount depend on configuration settings
  *
  * @return float
  */
 public function getShippingAmount()
 {
     $source = $this->getSource();
     if ($this->_taxConfig->displaySalesShippingInclTax($source->getOrder()->getStoreId())) {
         $shipping = $source->getBaseShippingInclTax();
     } else {
         $shipping = $source->getBaseShippingAmount();
     }
     return $this->priceCurrency->round($shipping) * 1;
 }
Пример #5
0
 /**
  * @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;
 }
Пример #6
0
 /**
  * @param AbstractItem $item
  * @return float
  */
 public function getBasePriceInclTax($item)
 {
     $qty = $item->getQty() ? $item->getQty() : ($item->getQtyOrdered() ? $item->getQtyOrdered() : 1);
     $taxAmount = $item->getBaseTaxAmount() + $item->getBaseDiscountTaxCompensation();
     $price = floatval($qty) ? ($item->getBaseRowTotal() + $taxAmount) / $qty : 0;
     return $this->priceCurrency->round($price);
 }
Пример #7
0
 /**
  * Distribute discount at parent item to children items
  *
  * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
  * @return $this
  */
 protected function distributeDiscount(\Magento\Quote\Model\Quote\Item\AbstractItem $item)
 {
     $parentBaseRowTotal = $item->getBaseRowTotal();
     $keys = ['discount_amount', 'base_discount_amount', 'original_discount_amount', 'base_original_discount_amount'];
     $roundingDelta = [];
     foreach ($keys as $key) {
         //Initialize the rounding delta to a tiny number to avoid floating point precision problem
         $roundingDelta[$key] = 1.0E-7;
     }
     foreach ($item->getChildren() as $child) {
         $ratio = $child->getBaseRowTotal() / $parentBaseRowTotal;
         foreach ($keys as $key) {
             if (!$item->hasData($key)) {
                 continue;
             }
             $value = $item->getData($key) * $ratio;
             $roundedValue = $this->priceCurrency->round($value + $roundingDelta[$key]);
             $roundingDelta[$key] += $value - $roundedValue;
             $child->setData($key, $roundedValue);
         }
     }
     foreach ($keys as $key) {
         $item->setData($key, 0);
     }
     return $this;
 }
Пример #8
0
 /**
  * Prepare order based on quote address
  *
  * @param   \Magento\Quote\Model\Quote\Address $address
  * @return  \Magento\Sales\Model\Order
  * @throws  \Magento\Checkout\Exception
  */
 protected function _prepareOrder(\Magento\Quote\Model\Quote\Address $address)
 {
     $quote = $this->getQuote();
     $quote->unsReservedOrderId();
     $quote->reserveOrderId();
     $quote->collectTotals();
     $order = $this->quoteAddressToOrder->convert($address);
     $order->setQuote($quote);
     $order->setBillingAddress($this->quoteAddressToOrderAddress->convert($quote->getBillingAddress()));
     if ($address->getAddressType() == 'billing') {
         $order->setIsVirtual(1);
     } else {
         $order->setShippingAddress($this->quoteAddressToOrderAddress->convert($address));
     }
     $order->setPayment($this->quotePaymentToOrderPayment->convert($quote->getPayment()));
     if ($this->priceCurrency->round($address->getGrandTotal()) == 0) {
         $order->getPayment()->setMethod('free');
     }
     foreach ($address->getAllItems() as $item) {
         $_quoteItem = $item->getQuoteItem();
         if (!$_quoteItem) {
             throw new \Magento\Checkout\Exception(__('Item not found or already ordered'));
         }
         $item->setProductType($_quoteItem->getProductType())->setProductOptions($_quoteItem->getProduct()->getTypeInstance()->getOrderOptions($_quoteItem->getProduct()));
         $orderItem = $this->quoteItemToOrderItem->convert($item);
         if ($item->getParentItem()) {
             $orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
         }
         $order->addItem($orderItem);
     }
     return $order;
 }
Пример #9
0
 /**
  * Round price considering delta
  *
  * @param float $price
  * @param bool $negative Indicates if we perform addition (true) or subtraction (false) of rounded value
  * @return float
  */
 public function deltaRound($price, $negative = false)
 {
     $roundedPrice = $price;
     if ($roundedPrice) {
         if ($negative) {
             $this->_delta = -$this->_delta;
         }
         $price += $this->_delta;
         $roundedPrice = $this->priceCurrency->round($price);
         $this->_delta = $price - $roundedPrice;
         if ($negative) {
             $this->_delta = -$this->_delta;
         }
     }
     return $roundedPrice;
 }
Пример #10
0
 /**
  * @param array $ruleData
  * @param null $productData
  * @return float
  */
 protected function calcRuleProductPrice($ruleData, $productData = null)
 {
     if ($productData !== null && isset($productData['rule_price'])) {
         $productPrice = $productData['rule_price'];
     } else {
         $productPrice = $ruleData['default_price'];
     }
     switch ($ruleData['action_operator']) {
         case 'to_fixed':
             $productPrice = min($ruleData['action_amount'], $productPrice);
             break;
         case 'to_percent':
             $productPrice = $productPrice * $ruleData['action_amount'] / 100;
             break;
         case 'by_fixed':
             $productPrice = max(0, $productPrice - $ruleData['action_amount']);
             break;
         case 'by_percent':
             $productPrice = $productPrice * (1 - $ruleData['action_amount'] / 100);
             break;
         default:
             $productPrice = 0;
     }
     return $this->priceCurrency->round($productPrice);
 }
Пример #11
0
 /**
  * Calculate amount for dynamic bundle product
  *
  * @param float $basePriceValue
  * @param Product $bundleProduct
  * @param \Magento\Bundle\Pricing\Price\BundleSelectionPrice[] $selectionPriceList
  * @param null|string $exclude
  * @return \Magento\Framework\Pricing\Amount\AmountInterface
  */
 protected function calculateDynamicBundleAmount($basePriceValue, $bundleProduct, $selectionPriceList, $exclude)
 {
     $fullAmount = 0.0;
     $adjustments = [];
     $amountList = [$this->calculator->getAmount($basePriceValue, $bundleProduct, $exclude)];
     /** @var $option \Magento\Bundle\Model\Option */
     foreach ($selectionPriceList as $selectionPrice) {
         $amountList[] = $selectionPrice->getAmount();
     }
     /** @var  Store $store */
     $store = $bundleProduct->getStore();
     $roundingMethod = $this->taxHelper->getCalculationAgorithm($store);
     /** @var \Magento\Framework\Pricing\Amount\AmountInterface $itemAmount */
     foreach ($amountList as $itemAmount) {
         if ($roundingMethod != TaxCalculationServiceInterface::CALC_TOTAL_BASE) {
             //We need to round the individual selection first
             $fullAmount += $this->priceCurrency->round($itemAmount->getValue());
             foreach ($itemAmount->getAdjustmentAmounts() as $code => $adjustment) {
                 $adjustment = $this->priceCurrency->round($adjustment);
                 $adjustments[$code] = isset($adjustments[$code]) ? $adjustments[$code] + $adjustment : $adjustment;
             }
         } else {
             $fullAmount += $itemAmount->getValue();
             foreach ($itemAmount->getAdjustmentAmounts() as $code => $adjustment) {
                 $adjustments[$code] = isset($adjustments[$code]) ? $adjustments[$code] + $adjustment : $adjustment;
             }
         }
     }
     if ($exclude && isset($adjustments[$exclude])) {
         $fullAmount -= $adjustments[$exclude];
         unset($adjustments[$exclude]);
     }
     return $this->amountFactory->create($fullAmount, $adjustments);
 }
Пример #12
0
 /**
  * Calculate item row total price
  *
  * @return $this
  */
 public function calcRowTotal()
 {
     $qty = $this->getTotalQty();
     // Round unit price before multiplying to prevent losing 1 cent on subtotal
     $total = $this->priceCurrency->round($this->getCalculationPriceOriginal()) * $qty;
     $baseTotal = $this->priceCurrency->round($this->getBaseCalculationPriceOriginal()) * $qty;
     $this->setRowTotal($this->priceCurrency->round($total));
     $this->setBaseRowTotal($this->priceCurrency->round($baseTotal));
     return $this;
 }
Пример #13
0
 /**
  * Convert price from default currency to current currency
  *
  * @param float $price
  * @param bool $round
  * @return float
  */
 protected function _convertPrice($price, $round = false)
 {
     if (empty($price)) {
         return 0;
     }
     $price = $this->priceCurrency->convert($price);
     if ($round) {
         $price = $this->priceCurrency->round($price);
     }
     return $price;
 }
Пример #14
0
 /**
  * Process row amount based on FPT total amount configuration setting
  *
  * @param   \Magento\Quote\Model\Quote\Address\Total $total
  * @param   float $rowValueExclTax
  * @param   float $baseRowValueExclTax
  * @param   float $rowValueInclTax
  * @param   float $baseRowValueInclTax
  * @return  $this
  */
 protected function processTotalAmount($total, $rowValueExclTax, $baseRowValueExclTax, $rowValueInclTax, $baseRowValueInclTax)
 {
     if (!$this->weeeData->isTaxable($this->_store)) {
         //Accumulate the values.  Will be used later in the 'weee tax' collector
         $this->weeeTotalExclTax += $this->priceCurrency->round($rowValueExclTax);
         $this->weeeBaseTotalExclTax += $this->priceCurrency->round($baseRowValueExclTax);
     }
     //This value is used to calculate shipping cost; it will be overridden by tax collector
     $total->setSubtotalInclTax($total->getSubtotalInclTax() + $this->priceCurrency->round($rowValueInclTax));
     $total->setBaseSubtotalInclTax($total->getBaseSubtotalInclTax() + $this->priceCurrency->round($baseRowValueInclTax));
     return $this;
 }
 /**
  * @param \Magento\Sales\Api\Data\CreditmemoInterface $creditmemo
  * @return bool
  * @throws \Magento\Framework\Exception\LocalizedException
  */
 protected function validateForRefund(\Magento\Sales\Api\Data\CreditmemoInterface $creditmemo)
 {
     if ($creditmemo->getId()) {
         throw new \Magento\Framework\Exception\LocalizedException(__('We cannot register an existing credit memo.'));
     }
     $baseOrderRefund = $this->priceCurrency->round($creditmemo->getOrder()->getBaseTotalRefunded() + $creditmemo->getBaseGrandTotal());
     if ($baseOrderRefund > $this->priceCurrency->round($creditmemo->getOrder()->getBaseTotalPaid())) {
         $baseAvailableRefund = $creditmemo->getOrder()->getBaseTotalPaid() - $creditmemo->getOrder()->getBaseTotalRefunded();
         throw new \Magento\Framework\Exception\LocalizedException(__('The most money available to refund is %1.', $creditmemo->getOrder()->formatBasePrice($baseAvailableRefund)));
     }
     return true;
 }
Пример #16
0
 /**
  * Calculate amount for dynamic bundle product
  *
  * @param float $basePriceValue
  * @param Product $bundleProduct
  * @param \Magento\Bundle\Pricing\Price\BundleSelectionPrice[] $selectionPriceList
  * @param null|bool|string|array $exclude
  * @return \Magento\Framework\Pricing\Amount\AmountInterface
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 protected function calculateDynamicBundleAmount($basePriceValue, $bundleProduct, $selectionPriceList, $exclude)
 {
     $fullAmount = 0.0;
     $adjustments = [];
     $i = 0;
     $amountList[$i]['amount'] = $this->calculator->getAmount($basePriceValue, $bundleProduct, $exclude);
     $amountList[$i]['quantity'] = 1;
     foreach ($selectionPriceList as $selectionPrice) {
         ++$i;
         $amountList[$i]['amount'] = $selectionPrice->getAmount();
         // always honor the quantity given
         $amountList[$i]['quantity'] = $selectionPrice->getQuantity();
     }
     /** @var  Store $store */
     $store = $bundleProduct->getStore();
     $roundingMethod = $this->taxHelper->getCalculationAlgorithm($store);
     foreach ($amountList as $amountInfo) {
         /** @var \Magento\Framework\Pricing\Amount\AmountInterface $itemAmount */
         $itemAmount = $amountInfo['amount'];
         $qty = $amountInfo['quantity'];
         if ($roundingMethod != TaxCalculationInterface::CALC_TOTAL_BASE) {
             //We need to round the individual selection first
             $fullAmount += $this->priceCurrency->round($itemAmount->getValue()) * $qty;
             foreach ($itemAmount->getAdjustmentAmounts() as $code => $adjustment) {
                 $adjustment = $this->priceCurrency->round($adjustment) * $qty;
                 $adjustments[$code] = isset($adjustments[$code]) ? $adjustments[$code] + $adjustment : $adjustment;
             }
         } else {
             $fullAmount += $itemAmount->getValue() * $qty;
             foreach ($itemAmount->getAdjustmentAmounts() as $code => $adjustment) {
                 $adjustment = $adjustment * $qty;
                 $adjustments[$code] = isset($adjustments[$code]) ? $adjustments[$code] + $adjustment : $adjustment;
             }
         }
     }
     if (is_array($exclude) == false) {
         if ($exclude && isset($adjustments[$exclude])) {
             $fullAmount -= $adjustments[$exclude];
             unset($adjustments[$exclude]);
         }
     } else {
         foreach ($exclude as $oneExclusion) {
             if ($oneExclusion && isset($adjustments[$oneExclusion])) {
                 $fullAmount -= $adjustments[$oneExclusion];
                 unset($adjustments[$oneExclusion]);
             }
         }
     }
     return $this->amountFactory->create($fullAmount, $adjustments);
 }
Пример #17
0
 /**
  * Process "delta" rounding
  *
  * @param \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData
  * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
  * @return $this
  * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  */
 public function deltaRoundingFix(\Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData, \Magento\Quote\Model\Quote\Item\AbstractItem $item)
 {
     $store = $item->getQuote()->getStore();
     $discountAmount = $discountData->getAmount();
     $baseDiscountAmount = $discountData->getBaseAmount();
     //TODO Seems \Magento\Quote\Model\Quote\Item\AbstractItem::getDiscountPercent() returns float value
     //that can not be used as array index
     $percentKey = $item->getDiscountPercent();
     if ($percentKey) {
         $delta = isset($this->_roundingDeltas[$percentKey]) ? $this->_roundingDeltas[$percentKey] : 0;
         $baseDelta = isset($this->_baseRoundingDeltas[$percentKey]) ? $this->_baseRoundingDeltas[$percentKey] : 0;
         $discountAmount += $delta;
         $baseDiscountAmount += $baseDelta;
         $this->_roundingDeltas[$percentKey] = $discountAmount - $this->priceCurrency->round($discountAmount);
         $this->_baseRoundingDeltas[$percentKey] = $baseDiscountAmount - $this->priceCurrency->round($baseDiscountAmount);
     }
     $discountData->setAmount($this->priceCurrency->round($discountAmount));
     $discountData->setBaseAmount($this->priceCurrency->round($baseDiscountAmount));
     return $this;
 }
Пример #18
0
 /**
  * Get calculated taxes for each tax class
  *
  * This method returns array with format:
  * array(
  *  $index => array(
  *      'tax_amount'        => $taxAmount,
  *      'base_tax_amount'   => $baseTaxAmount,
  *      'title'             => $title,
  *      'percent'           => $percent
  *  )
  * )
  *
  * @param  \Magento\Sales\Model\Order|\Magento\Sales\Model\Order\Invoice|\Magento\Sales\Model\Order\Creditmemo $source
  * @return array
  */
 public function getCalculatedTaxes($source)
 {
     $taxClassAmount = [];
     if (empty($source)) {
         return $taxClassAmount;
     }
     $current = $source;
     if ($source instanceof Invoice || $source instanceof Creditmemo) {
         $source = $current->getOrder();
     }
     if ($current == $source) {
         $taxClassAmount = $this->calculateTaxForOrder($current);
     } else {
         $taxClassAmount = $this->calculateTaxForItems($source, $current);
     }
     foreach ($taxClassAmount as $key => $tax) {
         $taxClassAmount[$key]['tax_amount'] = $this->priceCurrency->round($tax['tax_amount']);
         $taxClassAmount[$key]['base_tax_amount'] = $this->priceCurrency->round($tax['base_tax_amount']);
     }
     return array_values($taxClassAmount);
 }
Пример #19
0
 /**
  * @param string $amount
  * @return $this
  */
 public function setAdjustmentNegative($amount)
 {
     $amount = trim($amount);
     if (substr($amount, -1) == '%') {
         $amount = (double) substr($amount, 0, -1);
         $amount = $this->getOrder()->getGrandTotal() * $amount / 100;
     }
     $amount = $this->priceCurrency->round($amount);
     $this->setData('base_adjustment_negative', $amount);
     $amount = $this->priceCurrency->round($amount * $this->getOrder()->getBaseToOrderRate());
     $this->setData('adjustment_negative', $amount);
     return $this;
 }
Пример #20
0
 /**
  * Get calculated taxes for each tax class
  *
  * This method returns array with format:
  * array(
  *  $index => array(
  *      'tax_amount'        => $taxAmount,
  *      'base_tax_amount'   => $baseTaxAmount,
  *      'title'             => $title,
  *      'percent'           => $percent
  *  )
  * )
  *
  * @param \Magento\Sales\Model\Order $source
  * @return array
  */
 public function getCalculatedTaxes($source)
 {
     if ($this->_coreRegistry->registry('current_invoice')) {
         $current = $this->_coreRegistry->registry('current_invoice');
     } elseif ($this->_coreRegistry->registry('current_creditmemo')) {
         $current = $this->_coreRegistry->registry('current_creditmemo');
     } else {
         $current = $source;
     }
     $taxClassAmount = array();
     if ($current && $source) {
         if ($current == $source) {
             $orderTaxDetails = $this->orderTaxService->getOrderTaxDetails($current->getId());
             $appliedTaxes = $orderTaxDetails->getAppliedTaxes();
             foreach ($appliedTaxes as $appliedTax) {
                 $taxCode = $appliedTax->getCode();
                 $taxClassAmount[$taxCode]['tax_amount'] = $appliedTax->getAmount();
                 $taxClassAmount[$taxCode]['base_tax_amount'] = $appliedTax->getBaseAmount();
                 $taxClassAmount[$taxCode]['title'] = $appliedTax->getTitle();
                 $taxClassAmount[$taxCode]['percent'] = $appliedTax->getPercent();
             }
         } else {
             $orderTaxDetails = $this->orderTaxService->getOrderTaxDetails($source->getId());
             // Apply any taxes for shipping
             $shippingTaxAmount = $current->getShippingTaxAmount();
             $originalShippingTaxAmount = $source->getShippingTaxAmount();
             if ($shippingTaxAmount && $originalShippingTaxAmount && $shippingTaxAmount != 0 && $originalShippingTaxAmount != 0) {
                 //An invoice or credit memo can have a different qty than its order
                 $shippingRatio = $shippingTaxAmount / $originalShippingTaxAmount;
                 $itemTaxDetails = $orderTaxDetails->getItems();
                 foreach ($itemTaxDetails as $itemTaxDetail) {
                     //Aggregate taxable items associated with shipping
                     if ($itemTaxDetail->getType() == \Magento\Sales\Model\Quote\Address::TYPE_SHIPPING) {
                         $taxClassAmount = $this->_aggregateTaxes($taxClassAmount, $itemTaxDetail, $shippingRatio);
                     }
                 }
             }
             // Apply any taxes for the items
             /** @var $item \Magento\Sales\Model\Order\Invoice\Item|\Magento\Sales\Model\Order\Creditmemo\Item */
             foreach ($current->getItemsCollection() as $item) {
                 $orderItem = $item->getOrderItem();
                 $orderItemId = $orderItem->getId();
                 $orderItemTax = $orderItem->getTaxAmount();
                 $itemTax = $item->getTaxAmount();
                 if (!$itemTax || !$orderItemTax) {
                     continue;
                 }
                 //An invoiced item or credit memo item can have a different qty than its order item qty
                 $itemRatio = $itemTax / $orderItemTax;
                 $itemTaxDetails = $orderTaxDetails->getItems();
                 foreach ($itemTaxDetails as $itemTaxDetail) {
                     //Aggregate taxable items associated with an item
                     if ($itemTaxDetail->getItemId() == $orderItemId || $itemTaxDetail->getAssociatedItemId() == $orderItemId) {
                         $taxClassAmount = $this->_aggregateTaxes($taxClassAmount, $itemTaxDetail, $itemRatio);
                     }
                 }
             }
         }
         // Finish
         foreach ($taxClassAmount as $key => $tax) {
             if ($tax['tax_amount'] == 0 && $tax['base_tax_amount'] == 0) {
                 unset($taxClassAmount[$key]);
             } else {
                 $taxClassAmount[$key]['tax_amount'] = $this->priceCurrency->round($tax['tax_amount']);
                 $taxClassAmount[$key]['base_tax_amount'] = $this->priceCurrency->round($tax['base_tax_amount']);
             }
         }
         $taxClassAmount = array_values($taxClassAmount);
     }
     return $taxClassAmount;
 }
Пример #21
0
 /**
  * Round up and cast specified amount to float or string
  *
  * @param string|float $amount
  * @param bool $asFloat
  * @return string|float
  */
 protected function _formatAmount($amount, $asFloat = false)
 {
     $amount = $this->priceCurrency->round($amount);
     return !$asFloat ? (string) $amount : $amount;
 }
Пример #22
0
 /**
  * Check whether method is available
  *
  * @param \Magento\Sales\Model\Quote|null $quote
  * @return bool
  */
 public function isAvailable($quote = null)
 {
     return parent::isAvailable($quote) && !empty($quote) && $this->priceCurrency->round($quote->getGrandTotal()) == 0;
 }
Пример #23
0
 /**
  * @param Product $product
  * @param null|false|\Magento\Quote\Model\Quote\Address $shipping
  * @param null|false|\Magento\Quote\Model\Quote\Address $billing
  * @param Website $website
  * @param bool $calculateTax
  * @return \Magento\Framework\Object[]
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 public function getProductWeeeAttributes($product, $shipping = null, $billing = null, $website = null, $calculateTax = null)
 {
     $result = [];
     $websiteId = $this->_storeManager->getWebsite($website)->getId();
     /** @var \Magento\Store\Model\Store $store */
     $store = $this->_storeManager->getWebsite($website)->getDefaultGroup()->getDefaultStore();
     $allWeee = $this->getWeeeTaxAttributeCodes($store);
     if (!$allWeee) {
         return $result;
     }
     /** @var \Magento\Tax\Model\Calculation $calculator */
     $calculator = $this->_calculationFactory->create();
     if ($shipping && $shipping->getCountryId()) {
         $customerTaxClass = $shipping->getQuote()->getCustomerTaxClassId();
     } else {
         // if customer logged use it default shipping and billing address
         if ($customerId = $this->_customerSession->getCustomerId()) {
             $shipping = $this->accountManagement->getDefaultShippingAddress($customerId);
             $billing = $this->accountManagement->getDefaultBillingAddress($customerId);
             $customerTaxClass = null;
         } else {
             $shippingAddressArray = $this->_customerSession->getDefaultTaxShippingAddress();
             $billingAddressArray = $this->_customerSession->getDefaultTaxBillingAddress();
             if (!empty($billingAddressArray)) {
                 $billing = new \Magento\Framework\Object($billingAddressArray);
             }
             if (!empty($shippingAddressArray)) {
                 $shipping = new \Magento\Framework\Object($shippingAddressArray);
             }
             $customerTaxClass = $this->_customerSession->getCustomerTaxClassId();
         }
     }
     $rateRequest = $calculator->getRateRequest($shipping, $billing, $customerTaxClass, $store);
     $defaultRateRequest = $calculator->getDefaultRateRequest($store);
     $productAttributes = $product->getTypeInstance()->getSetAttributes($product);
     foreach ($productAttributes as $code => $attribute) {
         if (in_array($code, $allWeee)) {
             $attributeSelect = $this->getResource()->getReadConnection()->select();
             $attributeSelect->from($this->getResource()->getTable('weee_tax'), 'value')->where('attribute_id = ?', (int) $attribute->getId())->where('website_id IN(?)', [$websiteId, 0])->where('country = ?', $rateRequest->getCountryId())->where('state IN(?)', [$rateRequest->getRegionId(), 0])->where('entity_id = ?', (int) $product->getId())->limit(1);
             $order = ['state ' . \Magento\Framework\DB\Select::SQL_DESC, 'website_id ' . \Magento\Framework\DB\Select::SQL_DESC];
             $attributeSelect->order($order);
             $value = $this->getResource()->getReadConnection()->fetchOne($attributeSelect);
             if ($value) {
                 $taxAmount = $amount = 0;
                 $amount = $value;
                 if ($calculateTax && $this->weeeConfig->isTaxable($store)) {
                     /** @var \Magento\Tax\Model\Calculation $calculator */
                     $defaultPercent = $calculator->getRate($defaultRateRequest->setProductClassId($product->getTaxClassId()));
                     $currentPercent = $calculator->getRate($rateRequest->setProductClassId($product->getTaxClassId()));
                     if ($this->_taxData->priceIncludesTax($store)) {
                         $amountInclTax = $value / (100 + $defaultPercent) * (100 + $currentPercent);
                         //round the "golden price"
                         $amountInclTax = $this->priceCurrency->round($amountInclTax);
                         $taxAmount = $amountInclTax - $amountInclTax / (100 + $currentPercent) * 100;
                         $taxAmount = $this->priceCurrency->round($taxAmount);
                     } else {
                         $appliedRates = $this->_calculationFactory->create()->getAppliedRates($rateRequest);
                         if (count($appliedRates) > 1) {
                             $taxAmount = 0;
                             foreach ($appliedRates as $appliedRate) {
                                 $taxRate = $appliedRate['percent'];
                                 $taxAmount += $this->priceCurrency->round($value * $taxRate / 100);
                             }
                         } else {
                             $taxAmount = $this->priceCurrency->round($value * $currentPercent / 100);
                         }
                         $taxAmount = $this->priceCurrency->round($value * $currentPercent / 100);
                     }
                 }
                 $one = new \Magento\Framework\Object();
                 $one->setName(__($attribute->getFrontend()->getLabel()))->setAmount($amount)->setTaxAmount($taxAmount)->setCode($attribute->getAttributeCode());
                 $result[] = $one;
             }
         }
     }
     return $result;
 }
Пример #24
0
 /**
  * Custom setter for 'price' attribute
  *
  * @param Entry $entry
  * @param Product $product
  * @param mixed $value Fload price value
  * @param string $name Google Content attribute name
  * @return Entry
  */
 protected function _setAttributePrice($entry, $product, $value, $name = 'price')
 {
     $store = $this->_storeManager->getStore($product->getStoreId());
     $price = $this->priceCurrency->convert($value, $store);
     return $this->_setAttribute($entry, $name, self::ATTRIBUTE_TYPE_FLOAT, sprintf('%.2f', $this->priceCurrency->round($price)), $store->getDefaultCurrencyCode());
 }
Пример #25
0
 /**
  * Retrieve order total due value
  *
  * @return float
  */
 public function getBaseTotalDue()
 {
     $total = $this->getBaseGrandTotal() - $this->getBaseTotalPaid();
     $total = $this->priceCurrency->round($total);
     return max($total, 0);
 }
Пример #26
0
 /**
  * Round tax amount
  *
  * @param   float $price
  * @return  float
  */
 public function round($price)
 {
     return $this->priceCurrency->round($price);
 }
Пример #27
0
 /**
  * @param Product $product
  * @param null|false|\Magento\Quote\Model\Quote\Address $shipping
  * @param null|false|\Magento\Quote\Model\Quote\Address $billing
  * @param Website $website
  * @param bool $calculateTax
  * @param bool $round
  * @return \Magento\Framework\DataObject[]
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 public function getProductWeeeAttributes($product, $shipping = null, $billing = null, $website = null, $calculateTax = null, $round = true)
 {
     $result = [];
     $websiteId = $this->_storeManager->getWebsite($website)->getId();
     /** @var \Magento\Store\Model\Store $store */
     $store = $this->_storeManager->getWebsite($website)->getDefaultGroup()->getDefaultStore();
     $allWeee = $this->getWeeeTaxAttributeCodes($store);
     if (!$allWeee) {
         return $result;
     }
     /** @var \Magento\Tax\Model\Calculation $calculator */
     $calculator = $this->_calculationFactory->create();
     $customerId = $this->_customerSession->getCustomerId();
     if ($shipping && $shipping->getCountryId()) {
         $customerTaxClass = $shipping->getQuote()->getCustomerTaxClassId();
     } else {
         // if customer logged use it default shipping and billing address
         if ($customerId) {
             $shipping = $this->accountManagement->getDefaultShippingAddress($customerId);
             $billing = $this->accountManagement->getDefaultBillingAddress($customerId);
             $customerTaxClass = null;
         } else {
             $shippingAddressArray = $this->_customerSession->getDefaultTaxShippingAddress();
             $billingAddressArray = $this->_customerSession->getDefaultTaxBillingAddress();
             if (!empty($billingAddressArray)) {
                 $billing = new \Magento\Framework\DataObject($billingAddressArray);
             }
             if (!empty($shippingAddressArray)) {
                 $shipping = new \Magento\Framework\DataObject($shippingAddressArray);
             }
             $customerTaxClass = $this->_customerSession->getCustomerTaxClassId();
         }
     }
     $rateRequest = $calculator->getRateRequest($shipping, $billing, $customerTaxClass, $store, $customerId);
     $defaultRateRequest = $calculator->getDefaultRateRequest($store);
     $productAttributes = $this->getResource()->fetchWeeeTaxCalculationsByEntity($rateRequest->getCountryId(), $rateRequest->getRegionId(), $websiteId, $store->getId(), $product->getId());
     foreach ($productAttributes as $attribute) {
         $value = $attribute['weee_value'];
         if ($value) {
             $taxAmount = $amount = 0;
             $amount = $value;
             $amountExclTax = $value;
             if ($calculateTax && $this->weeeConfig->isTaxable($store)) {
                 /** @var \Magento\Tax\Model\Calculation $calculator */
                 $defaultPercent = $calculator->getRate($defaultRateRequest->setProductClassId($product->getTaxClassId()));
                 $currentPercent = $calculator->getRate($rateRequest->setProductClassId($product->getTaxClassId()));
                 if ($this->_taxData->priceIncludesTax($store)) {
                     $amountInclTax = $value / (100 + $defaultPercent) * (100 + $currentPercent);
                     if ($round) {
                         $amountInclTax = $this->priceCurrency->round($amountInclTax);
                     }
                     $taxAmount = $amountInclTax - $amountInclTax / (100 + $currentPercent) * 100;
                     if ($round) {
                         $taxAmount = $this->priceCurrency->round($taxAmount);
                     }
                     $amountExclTax = $amountInclTax - $taxAmount;
                 } else {
                     $appliedRates = $this->_calculationFactory->create()->getAppliedRates($rateRequest);
                     if (count($appliedRates) > 1) {
                         $taxAmount = 0;
                         foreach ($appliedRates as $appliedRate) {
                             $taxRate = $appliedRate['percent'];
                             if ($round) {
                                 $taxAmount += $this->priceCurrency->round($value * $taxRate / 100);
                             } else {
                                 $taxAmount += $value * $taxRate / 100;
                             }
                         }
                     } else {
                         if ($round) {
                             $taxAmount = $this->priceCurrency->round($value * $currentPercent / 100);
                         } else {
                             $taxAmount = $value * $currentPercent / 100;
                         }
                     }
                 }
             }
             $one = new \Magento\Framework\DataObject();
             $one->setName($attribute['label_value'] ? __($attribute['label_value']) : __($attribute['frontend_label']))->setAmount($amount)->setTaxAmount($taxAmount)->setAmountExclTax($amountExclTax)->setCode($attribute['attribute_code']);
             $result[] = $one;
         }
     }
     return $result;
 }
Пример #28
0
 /**
  * Retrieve attribute source value for search
  *
  * @param int $attributeId
  * @param mixed $value
  * @param int $storeId
  * @return mixed
  */
 protected function getAttributeValue($attributeId, $value, $storeId)
 {
     $attribute = $this->getSearchableAttribute($attributeId);
     if (!$attribute->getIsSearchable()) {
         if ($this->engineProvider->get()->allowAdvancedIndex()) {
             if ($attribute->getAttributeCode() == 'visibility') {
                 return $value;
             } elseif (!($attribute->getIsVisibleInAdvancedSearch() || $attribute->getIsFilterable() || $attribute->getIsFilterableInSearch() || $attribute->getUsedForSortBy())) {
                 return null;
             }
         } else {
             return null;
         }
     }
     if ($attribute->usesSource()) {
         if ($this->engineProvider->get()->allowAdvancedIndex()) {
             return $value;
         }
         $attribute->setStoreId($storeId);
         $value = $attribute->getSource()->getIndexOptionText($value);
         if (is_array($value)) {
             $value = implode($this->separator, $value);
         } elseif (empty($value)) {
             $inputType = $attribute->getFrontend()->getInputType();
             if ($inputType == 'select' || $inputType == 'multiselect') {
                 return null;
             }
         }
     } elseif ($attribute->getBackendType() == 'datetime') {
         $value = $this->getStoreDate($storeId, $value);
     } else {
         $inputType = $attribute->getFrontend()->getInputType();
         if ($inputType == 'price') {
             $value = $this->priceCurrency->round($value);
         }
     }
     $value = preg_replace("#\\s+#siu", ' ', trim(strip_tags($value)));
     return $value;
 }
Пример #29
0
 /**
  * Get product price with all tax settings processing
  *
  * @param   \Magento\Catalog\Model\Product $product
  * @param   float $price inputted product price
  * @param   bool $includingTax return price include tax flag
  * @param   null|\Magento\Customer\Model\Address\AbstractAddress $shippingAddress
  * @param   null|\Magento\Customer\Model\Address\AbstractAddress $billingAddress
  * @param   null|int $ctc customer tax class
  * @param   null|string|bool|int|\Magento\Store\Model\Store $store
  * @param   bool $priceIncludesTax flag what price parameter contain tax
  * @param   bool $roundPrice
  * @return  float
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 public function getTaxPrice($product, $price, $includingTax = null, $shippingAddress = null, $billingAddress = null, $ctc = null, $store = null, $priceIncludesTax = null, $roundPrice = true)
 {
     if (!$price) {
         return $price;
     }
     $store = $this->_storeManager->getStore($store);
     if ($this->_taxConfig->needPriceConversion($store)) {
         if ($priceIncludesTax === null) {
             $priceIncludesTax = $this->_taxConfig->priceIncludesTax($store);
         }
         $shippingAddressDataObject = null;
         if ($shippingAddress === null) {
             $shippingAddressDataObject = $this->convertDefaultTaxAddress($this->_customerSession->getDefaultTaxShippingAddress());
         } elseif ($shippingAddress instanceof \Magento\Customer\Model\Address\AbstractAddress) {
             $shippingAddressDataObject = $shippingAddress->getDataModel();
         }
         $billingAddressDataObject = null;
         if ($billingAddress === null) {
             $billingAddressDataObject = $this->convertDefaultTaxAddress($this->_customerSession->getDefaultTaxBillingAddress());
         } elseif ($billingAddress instanceof \Magento\Customer\Model\Address\AbstractAddress) {
             $billingAddressDataObject = $billingAddress->getDataModel();
         }
         $taxClassKey = $this->_taxClassKeyFactory->create();
         $taxClassKey->setType(TaxClassKeyInterface::TYPE_ID)->setValue($product->getTaxClassId());
         if ($ctc === null && $this->_customerSession->getCustomerGroupId() != null) {
             $ctc = $this->customerGroupRepository->getById($this->_customerSession->getCustomerGroupId())->getTaxClassId();
         }
         $customerTaxClassKey = $this->_taxClassKeyFactory->create();
         $customerTaxClassKey->setType(TaxClassKeyInterface::TYPE_ID)->setValue($ctc);
         $item = $this->_quoteDetailsItemFactory->create();
         $item->setQuantity(1)->setCode($product->getSku())->setShortDescription($product->getShortDescription())->setTaxClassKey($taxClassKey)->setIsTaxIncluded($priceIncludesTax)->setType('product')->setUnitPrice($price);
         $quoteDetails = $this->_quoteDetailsFactory->create();
         $quoteDetails->setShippingAddress($shippingAddressDataObject)->setBillingAddress($billingAddressDataObject)->setCustomerTaxClassKey($customerTaxClassKey)->setItems([$item])->setCustomerId($this->_customerSession->getCustomerId());
         $storeId = null;
         if ($store) {
             $storeId = $store->getId();
         }
         $taxDetails = $this->_taxCalculationService->calculateTax($quoteDetails, $storeId, $roundPrice);
         $items = $taxDetails->getItems();
         $taxDetailsItem = array_shift($items);
         if ($includingTax !== null) {
             if ($includingTax) {
                 $price = $taxDetailsItem->getPriceInclTax();
             } else {
                 $price = $taxDetailsItem->getPrice();
             }
         } else {
             switch ($this->_taxConfig->getPriceDisplayType($store)) {
                 case Config::DISPLAY_TYPE_EXCLUDING_TAX:
                 case Config::DISPLAY_TYPE_BOTH:
                     $price = $taxDetailsItem->getPrice();
                     break;
                 case Config::DISPLAY_TYPE_INCLUDING_TAX:
                     $price = $taxDetailsItem->getPriceInclTax();
                     break;
                 default:
                     break;
             }
         }
     }
     if ($roundPrice) {
         return $this->priceCurrency->round($price);
     } else {
         return $price;
     }
 }
 /**
  * @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;
 }