Ejemplo n.º 1
0
 /**
  * Convert and format price value for specified store
  *
  * @param   float $value
  * @param   int|\Magento\Store\Model\Store $store
  * @param   bool $format
  * @param   bool $includeContainer
  * @return  float|string
  */
 public function currencyByStore($value, $store = null, $format = true, $includeContainer = true)
 {
     if ($format) {
         $value = $this->priceCurrency->convertAndFormat($value, $includeContainer, PriceCurrencyInterface::DEFAULT_PRECISION, $store);
     } else {
         $value = $this->priceCurrency->convert($value, $store);
     }
     return $value;
 }
Ejemplo n.º 2
0
 /**
  * Collect recurring item parameters and copy to the address items
  *
  * @param \Magento\Sales\Model\Quote\Address $address
  * @return $this
  */
 public function collect(\Magento\Sales\Model\Quote\Address $address)
 {
     parent::collect($address);
     $items = $this->_getAddressItems($address);
     foreach ($items as $item) {
         if ($item->getProduct()->getIsRecurring()) {
             $paymentData = $item->getProduct()->getRecurringPayment();
             if (!empty($paymentData[$this->_paymentDataKey])) {
                 $item->setData($this->_itemRowTotalKey, $this->priceCurrency->convert($paymentData[$this->_paymentDataKey], $address->getQuote()->getStore()));
                 $this->_afterCollectSuccess($address, $item);
             }
         }
     }
     return $this;
 }
Ejemplo n.º 3
0
 /**
  * Get item price converted to quote currency
  * @return float
  */
 public function getConvertedPrice()
 {
     $price = $this->_getData('converted_price');
     if ($price === null) {
         $price = $this->priceCurrency->convert($this->getPrice(), $this->getStore());
         $this->setData('converted_price', $price);
     }
     return $price;
 }
Ejemplo n.º 4
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;
 }
Ejemplo n.º 5
0
 /**
  * Obtain amount
  *
  * @param SaleableInterface $saleableItem
  * @return float
  */
 protected function getAmount(SaleableInterface $saleableItem)
 {
     $weeeTaxAmount = 0;
     $attributes = $this->weeeHelper->getProductWeeeAttributes($saleableItem, null, null, null, true, false);
     if ($attributes != null) {
         foreach ($attributes as $attribute) {
             $weeeTaxAmount += $attribute->getData('tax_amount');
         }
     }
     $weeeTaxAmount = $this->priceCurrency->convert($weeeTaxAmount);
     return $weeeTaxAmount;
 }
Ejemplo n.º 6
0
 /**
  * Calculate item fixed tax and prepare information for discount and regular taxation
  *
  * @param   \Magento\Quote\Model\Quote\Address $address
  * @param   \Magento\Quote\Model\Quote\Address\Total $total
  * @param   \Magento\Quote\Model\Quote\Item\AbstractItem $item
  * @return  void|$this
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  */
 protected function process(\Magento\Quote\Model\Quote\Address $address, \Magento\Quote\Model\Quote\Address\Total $total, $item)
 {
     $attributes = $this->weeeData->getProductWeeeAttributes($item->getProduct(), $address, $address->getQuote()->getBillingAddress(), $this->_store->getWebsiteId());
     $productTaxes = [];
     $totalValueInclTax = 0;
     $baseTotalValueInclTax = 0;
     $totalRowValueInclTax = 0;
     $baseTotalRowValueInclTax = 0;
     $totalValueExclTax = 0;
     $baseTotalValueExclTax = 0;
     $totalRowValueExclTax = 0;
     $baseTotalRowValueExclTax = 0;
     $associatedTaxables = $item->getAssociatedTaxables();
     if (!$associatedTaxables) {
         $associatedTaxables = [];
     } else {
         // remove existing weee associated taxables
         foreach ($associatedTaxables as $iTaxable => $taxable) {
             if ($taxable[CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_TYPE] == self::ITEM_TYPE) {
                 unset($associatedTaxables[$iTaxable]);
             }
         }
     }
     foreach ($attributes as $key => $attribute) {
         $title = $attribute->getName();
         $baseValueExclTax = $baseValueInclTax = $attribute->getAmount();
         $valueExclTax = $valueInclTax = $this->priceCurrency->round($this->priceCurrency->convert($baseValueExclTax, $this->_store));
         $rowValueInclTax = $rowValueExclTax = $this->priceCurrency->round($valueInclTax * $item->getTotalQty());
         $baseRowValueInclTax = $this->priceCurrency->round($baseValueInclTax * $item->getTotalQty());
         $baseRowValueExclTax = $baseRowValueInclTax;
         $totalValueInclTax += $valueInclTax;
         $baseTotalValueInclTax += $baseValueInclTax;
         $totalRowValueInclTax += $rowValueInclTax;
         $baseTotalRowValueInclTax += $baseRowValueInclTax;
         $totalValueExclTax += $valueExclTax;
         $baseTotalValueExclTax += $baseValueExclTax;
         $totalRowValueExclTax += $rowValueExclTax;
         $baseTotalRowValueExclTax += $baseRowValueExclTax;
         $productTaxes[] = ['title' => $title, 'base_amount' => $baseValueExclTax, 'amount' => $valueExclTax, 'row_amount' => $rowValueExclTax, 'base_row_amount' => $baseRowValueExclTax, 'base_amount_incl_tax' => $baseValueInclTax, 'amount_incl_tax' => $valueInclTax, 'row_amount_incl_tax' => $rowValueInclTax, 'base_row_amount_incl_tax' => $baseRowValueInclTax];
         if ($this->weeeData->isTaxable($this->_store)) {
             $weeeItemCode = self::ITEM_CODE_WEEE_PREFIX . $this->getNextIncrement();
             $weeeItemCode .= '-' . $title;
             $associatedTaxables[] = [CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_TYPE => self::ITEM_TYPE, CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_CODE => $weeeItemCode, CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_UNIT_PRICE => $valueExclTax, CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_BASE_UNIT_PRICE => $baseValueExclTax, CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_QUANTITY => $item->getTotalQty(), CommonTaxCollector::KEY_ASSOCIATED_TAXABLE_TAX_CLASS_ID => $item->getProduct()->getTaxClassId()];
             $this->weeeCodeToItemMap[$weeeItemCode] = $item;
         }
     }
     $item->setAssociatedTaxables($associatedTaxables);
     $item->setWeeeTaxAppliedAmount($totalValueExclTax)->setBaseWeeeTaxAppliedAmount($baseTotalValueExclTax)->setWeeeTaxAppliedRowAmount($totalRowValueExclTax)->setBaseWeeeTaxAppliedRowAmnt($baseTotalRowValueExclTax);
     $item->setWeeeTaxAppliedAmountInclTax($totalValueInclTax)->setBaseWeeeTaxAppliedAmountInclTax($baseTotalValueInclTax)->setWeeeTaxAppliedRowAmountInclTax($totalRowValueInclTax)->setBaseWeeeTaxAppliedRowAmntInclTax($baseTotalRowValueInclTax);
     $this->processTotalAmount($total, $totalRowValueExclTax, $baseTotalRowValueExclTax, $totalRowValueInclTax, $baseTotalRowValueInclTax);
     $this->weeeData->setApplied($item, array_merge($this->weeeData->getApplied($item), $productTaxes));
 }
Ejemplo n.º 7
0
 /**
  * Get JSON encoded configuration array which can be used for JS dynamic
  * price calculation depending on product options
  *
  * @return string
  */
 public function getJsonConfig()
 {
     /* @var $product \Magento\Catalog\Model\Product */
     $product = $this->getProduct();
     if (!$this->hasOptions()) {
         $config = ['productId' => $product->getId(), 'priceFormat' => $this->_localeFormat->getPriceFormat()];
         return $this->_jsonEncoder->encode($config);
     }
     $tierPrices = [];
     $tierPricesList = $product->getPriceInfo()->getPrice('tier_price')->getTierPriceList();
     foreach ($tierPricesList as $tierPrice) {
         $tierPrices[] = $this->priceCurrency->convert($tierPrice['price']->getValue());
     }
     $config = ['productId' => $product->getId(), 'priceFormat' => $this->_localeFormat->getPriceFormat(), 'prices' => ['oldPrice' => ['amount' => $this->priceCurrency->convert($product->getPriceInfo()->getPrice('regular_price')->getAmount()->getValue()), 'adjustments' => []], 'basePrice' => ['amount' => $this->priceCurrency->convert($product->getPriceInfo()->getPrice('final_price')->getAmount()->getBaseAmount()), 'adjustments' => []], 'finalPrice' => ['amount' => $this->priceCurrency->convert($product->getPriceInfo()->getPrice('final_price')->getAmount()->getValue()), 'adjustments' => []]], 'idSuffix' => '_clone', 'tierPrices' => $tierPrices];
     $responseObject = new \Magento\Framework\DataObject();
     $this->_eventManager->dispatch('catalog_product_view_config', ['response_object' => $responseObject]);
     if (is_array($responseObject->getAdditionalOptions())) {
         foreach ($responseObject->getAdditionalOptions() as $option => $value) {
             $config[$option] = $value;
         }
     }
     return $this->_jsonEncoder->encode($config);
 }
Ejemplo n.º 8
0
 /**
  * Apply discounts to shipping amount
  *
  * @param Address $address
  * @return $this
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 public function processShippingAmount(Address $address)
 {
     $shippingAmount = $address->getShippingAmountForDiscount();
     if ($shippingAmount !== null) {
         $baseShippingAmount = $address->getBaseShippingAmountForDiscount();
     } else {
         $shippingAmount = $address->getShippingAmount();
         $baseShippingAmount = $address->getBaseShippingAmount();
     }
     $quote = $address->getQuote();
     $appliedRuleIds = [];
     foreach ($this->_getRules() as $rule) {
         /* @var \Magento\SalesRule\Model\Rule $rule */
         if (!$rule->getApplyToShipping() || !$this->validatorUtility->canProcessRule($rule, $address)) {
             continue;
         }
         $discountAmount = 0;
         $baseDiscountAmount = 0;
         $rulePercent = min(100, $rule->getDiscountAmount());
         switch ($rule->getSimpleAction()) {
             case \Magento\SalesRule\Model\Rule::TO_PERCENT_ACTION:
                 $rulePercent = max(0, 100 - $rule->getDiscountAmount());
                 // break is intentionally omitted
             // break is intentionally omitted
             case \Magento\SalesRule\Model\Rule::BY_PERCENT_ACTION:
                 $discountAmount = ($shippingAmount - $address->getShippingDiscountAmount()) * $rulePercent / 100;
                 $baseDiscountAmount = ($baseShippingAmount - $address->getBaseShippingDiscountAmount()) * $rulePercent / 100;
                 $discountPercent = min(100, $address->getShippingDiscountPercent() + $rulePercent);
                 $address->setShippingDiscountPercent($discountPercent);
                 break;
             case \Magento\SalesRule\Model\Rule::TO_FIXED_ACTION:
                 $quoteAmount = $this->priceCurrency->convert($rule->getDiscountAmount(), $quote->getStore());
                 $discountAmount = $shippingAmount - $quoteAmount;
                 $baseDiscountAmount = $baseShippingAmount - $rule->getDiscountAmount();
                 break;
             case \Magento\SalesRule\Model\Rule::BY_FIXED_ACTION:
                 $quoteAmount = $this->priceCurrency->convert($rule->getDiscountAmount(), $quote->getStore());
                 $discountAmount = $quoteAmount;
                 $baseDiscountAmount = $rule->getDiscountAmount();
                 break;
             case \Magento\SalesRule\Model\Rule::CART_FIXED_ACTION:
                 $cartRules = $address->getCartFixedRules();
                 if (!isset($cartRules[$rule->getId()])) {
                     $cartRules[$rule->getId()] = $rule->getDiscountAmount();
                 }
                 if ($cartRules[$rule->getId()] > 0) {
                     $quoteAmount = $this->priceCurrency->convert($cartRules[$rule->getId()], $quote->getStore());
                     $discountAmount = min($shippingAmount - $address->getShippingDiscountAmount(), $quoteAmount);
                     $baseDiscountAmount = min($baseShippingAmount - $address->getBaseShippingDiscountAmount(), $cartRules[$rule->getId()]);
                     $cartRules[$rule->getId()] -= $baseDiscountAmount;
                 }
                 $address->setCartFixedRules($cartRules);
                 break;
         }
         $discountAmount = min($address->getShippingDiscountAmount() + $discountAmount, $shippingAmount);
         $baseDiscountAmount = min($address->getBaseShippingDiscountAmount() + $baseDiscountAmount, $baseShippingAmount);
         $address->setShippingDiscountAmount($discountAmount);
         $address->setBaseShippingDiscountAmount($baseDiscountAmount);
         $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId();
         $this->rulesApplier->maintainAddressCouponCode($address, $rule, $this->getCouponCode());
         $this->rulesApplier->addDiscountDescription($address, $rule);
         if ($rule->getStopRulesProcessing()) {
             break;
         }
     }
     $address->setAppliedRuleIds($this->validatorUtility->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds));
     $quote->setAppliedRuleIds($this->validatorUtility->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds));
     return $this;
 }
Ejemplo n.º 9
0
 /**
  * Obtain amount
  *
  * @param SaleableInterface $saleableItem
  * @return float
  */
 protected function getAmount(SaleableInterface $saleableItem)
 {
     $weeeAmount = $this->weeeHelper->getAmountExclTax($saleableItem);
     $weeeAmount = $this->priceCurrency->convert($weeeAmount);
     return $weeeAmount;
 }
Ejemplo n.º 10
0
 /**
  * @param float $price
  * @param bool $format
  * @return float
  */
 public function convertPrice($price, $format = true)
 {
     return $format ? $this->priceCurrency->convertAndFormat($price) : $this->priceCurrency->convert($price);
 }
Ejemplo n.º 11
0
 /**
  * Collect totals information about shipping
  *
  * @param \Magento\Quote\Model\Quote\Address $address
  * @return $this
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 public function collect(\Magento\Quote\Model\Quote\Address $address)
 {
     parent::collect($address);
     $address->setWeight(0);
     $address->setFreeMethodWeight(0);
     $this->_setAmount(0)->_setBaseAmount(0);
     $items = $this->_getAddressItems($address);
     if (!count($items)) {
         return $this;
     }
     $method = $address->getShippingMethod();
     $freeAddress = $address->getFreeShipping();
     $addressWeight = $address->getWeight();
     $freeMethodWeight = $address->getFreeMethodWeight();
     $addressQty = 0;
     foreach ($items as $item) {
         /**
          * Skip if this item is virtual
          */
         if ($item->getProduct()->isVirtual()) {
             continue;
         }
         /**
          * Children weight we calculate for parent
          */
         if ($item->getParentItem()) {
             continue;
         }
         if ($item->getHasChildren() && $item->isShipSeparately()) {
             foreach ($item->getChildren() as $child) {
                 if ($child->getProduct()->isVirtual()) {
                     continue;
                 }
                 $addressQty += $child->getTotalQty();
                 if (!$item->getProduct()->getWeightType()) {
                     $itemWeight = $child->getWeight();
                     $itemQty = $child->getTotalQty();
                     $rowWeight = $itemWeight * $itemQty;
                     $addressWeight += $rowWeight;
                     if ($freeAddress || $child->getFreeShipping() === true) {
                         $rowWeight = 0;
                     } elseif (is_numeric($child->getFreeShipping())) {
                         $freeQty = $child->getFreeShipping();
                         if ($itemQty > $freeQty) {
                             $rowWeight = $itemWeight * ($itemQty - $freeQty);
                         } else {
                             $rowWeight = 0;
                         }
                     }
                     $freeMethodWeight += $rowWeight;
                     $item->setRowWeight($rowWeight);
                 }
             }
             if ($item->getProduct()->getWeightType()) {
                 $itemWeight = $item->getWeight();
                 $rowWeight = $itemWeight * $item->getQty();
                 $addressWeight += $rowWeight;
                 if ($freeAddress || $item->getFreeShipping() === true) {
                     $rowWeight = 0;
                 } elseif (is_numeric($item->getFreeShipping())) {
                     $freeQty = $item->getFreeShipping();
                     if ($item->getQty() > $freeQty) {
                         $rowWeight = $itemWeight * ($item->getQty() - $freeQty);
                     } else {
                         $rowWeight = 0;
                     }
                 }
                 $freeMethodWeight += $rowWeight;
                 $item->setRowWeight($rowWeight);
             }
         } else {
             if (!$item->getProduct()->isVirtual()) {
                 $addressQty += $item->getQty();
             }
             $itemWeight = $item->getWeight();
             $rowWeight = $itemWeight * $item->getQty();
             $addressWeight += $rowWeight;
             if ($freeAddress || $item->getFreeShipping() === true) {
                 $rowWeight = 0;
             } elseif (is_numeric($item->getFreeShipping())) {
                 $freeQty = $item->getFreeShipping();
                 if ($item->getQty() > $freeQty) {
                     $rowWeight = $itemWeight * ($item->getQty() - $freeQty);
                 } else {
                     $rowWeight = 0;
                 }
             }
             $freeMethodWeight += $rowWeight;
             $item->setRowWeight($rowWeight);
         }
     }
     if (isset($addressQty)) {
         $address->setItemQty($addressQty);
     }
     $address->setWeight($addressWeight);
     $address->setFreeMethodWeight($freeMethodWeight);
     $address->collectShippingRates();
     $this->_setAmount(0)->_setBaseAmount(0);
     if ($method) {
         foreach ($address->getAllShippingRates() as $rate) {
             if ($rate->getCode() == $method) {
                 $amountPrice = $this->priceCurrency->convert($rate->getPrice(), $address->getQuote()->getStore());
                 $this->_setAmount($amountPrice);
                 $this->_setBaseAmount($rate->getPrice());
                 $shippingDescription = $rate->getCarrierTitle() . ' - ' . $rate->getMethodTitle();
                 $address->setShippingDescription(trim($shippingDescription, ' -'));
                 break;
             }
         }
     }
     return $this;
 }
Ejemplo n.º 12
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());
 }
Ejemplo n.º 13
0
 /**
  * Convert price
  *
  * @param float $value
  * @param bool $format
  * @return float
  */
 public function convertPrice($value, $format = true)
 {
     return $format ? $this->priceCurrency->convertAndFormat($value, true, PriceCurrencyInterface::DEFAULT_PRECISION, $this->getStore()) : $this->priceCurrency->convert($value, $this->getStore());
 }
Ejemplo n.º 14
0
 /**
  * Get product price including store convertion rate
  *
  * @param \Magento\Catalog\Model\Product $product
  * @param null|string $format
  * @return float|string
  * @deprecated
  */
 public function getProductPrice($product, $format = null)
 {
     try {
         $value = $product->getPrice();
         $value = $format ? $this->priceCurrency->convertAndFormat($value) : $this->priceCurrency->convert($value);
     } catch (\Exception $e) {
         $value = $e->getMessage();
     }
     return $value;
 }
Ejemplo n.º 15
0
 /**
  * Returns JSON encoded config to be used in JS scripts
  *
  * @return string
  * 
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 public function getJsonConfig()
 {
     /** @var \Magento\Bundle\Model\Option[] $optionsArray */
     $optionsArray = $this->getOptions();
     $options = array();
     $selected = array();
     $currentProduct = $this->getProduct();
     if ($preConfiguredFlag = $currentProduct->hasPreconfiguredValues()) {
         $preConfiguredValues = $currentProduct->getPreconfiguredValues();
         $defaultValues = array();
     }
     $position = 0;
     foreach ($optionsArray as $optionItem) {
         /* @var $optionItem \Magento\Bundle\Model\Option */
         if (!$optionItem->getSelections()) {
             continue;
         }
         $optionId = $optionItem->getId();
         $option = array('selections' => array(), 'title' => $optionItem->getTitle(), 'isMulti' => in_array($optionItem->getType(), array('multi', 'checkbox')), 'position' => $position++);
         $selectionCount = count($optionItem->getSelections());
         foreach ($optionItem->getSelections() as $selectionItem) {
             /* @var $selectionItem \Magento\Catalog\Model\Product */
             $selectionId = $selectionItem->getSelectionId();
             $qty = !($selectionItem->getSelectionQty() * 1) ? '1' : $selectionItem->getSelectionQty() * 1;
             // recalculate currency
             $tierPrices = $selectionItem->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\TierPrice::PRICE_CODE)->getTierPriceList();
             foreach ($tierPrices as &$tierPriceInfo) {
                 /** @var \Magento\Framework\Pricing\Amount\Base $price */
                 $price = $tierPriceInfo['price'];
                 $priceBaseAmount = $price->getBaseAmount();
                 $priceValue = $price->getValue();
                 $bundleProductPrice = $this->_productPrice->create();
                 $priceBaseAmount = $bundleProductPrice->getLowestPrice($currentProduct, $priceBaseAmount);
                 $priceValue = $bundleProductPrice->getLowestPrice($currentProduct, $priceValue);
                 $tierPriceInfo['price'] = $this->priceCurrency->convert($this->_taxData->displayPriceIncludingTax() ? $priceValue : $priceBaseAmount);
                 $tierPriceInfo['exclTaxPrice'] = $this->priceCurrency->convert($priceBaseAmount);
                 $tierPriceInfo['inclTaxPrice'] = $this->priceCurrency->convert($priceValue);
             }
             // break the reference with the last element
             $canApplyMAP = false;
             $bundleOptionPriceAmount = $currentProduct->getPriceInfo()->getPrice('bundle_option')->getOptionSelectionAmount($selectionItem);
             $priceInclTax = $bundleOptionPriceAmount->getValue();
             $priceExclTax = $bundleOptionPriceAmount->getBaseAmount();
             $selection = array('qty' => $qty, 'customQty' => $selectionItem->getSelectionCanChangeQty(), 'inclTaxPrice' => $this->priceCurrency->convert($priceInclTax), 'exclTaxPrice' => $this->priceCurrency->convert($priceExclTax), 'priceType' => $selectionItem->getSelectionPriceType(), 'tierPrice' => $tierPrices, 'name' => $selectionItem->getName(), 'plusDisposition' => 0, 'minusDisposition' => 0, 'canApplyMAP' => $canApplyMAP);
             $selection['price'] = $this->_taxData->displayPriceIncludingTax() ? $selection['inclTaxPrice'] : $selection['exclTaxPrice'];
             $responseObject = new \Magento\Framework\Object();
             $args = array('response_object' => $responseObject, 'selection' => $selectionItem);
             $this->_eventManager->dispatch('bundle_product_view_config', $args);
             if (is_array($responseObject->getAdditionalOptions())) {
                 foreach ($responseObject->getAdditionalOptions() as $index => $value) {
                     $selection[$index] = $value;
                 }
             }
             $option['selections'][$selectionId] = $selection;
             if (($selectionItem->getIsDefault() || $selectionCount == 1 && $optionItem->getRequired()) && $selectionItem->isSalable()) {
                 $selected[$optionId][] = $selectionId;
             }
         }
         $options[$optionId] = $option;
         // Add attribute default value (if set)
         if ($preConfiguredFlag) {
             $configValue = $preConfiguredValues->getData('bundle_option/' . $optionId);
             if ($configValue) {
                 $defaultValues[$optionId] = $configValue;
             }
         }
     }
     $isFixedPrice = $this->getProduct()->getPriceType() == \Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED;
     $productAmount = $currentProduct->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)->getAmount();
     $baseProductAmount = $currentProduct->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\RegularPrice::PRICE_CODE)->getAmount();
     $config = array('options' => $options, 'selected' => $selected, 'bundleId' => $currentProduct->getId(), 'priceFormat' => $this->_localeFormat->getPriceFormat(), 'basePrice' => $this->priceCurrency->convert($baseProductAmount->getValue()), 'finalBasePriceInclTax' => $isFixedPrice ? $this->priceCurrency->convert($productAmount->getValue()) : 0, 'finalBasePriceExclTax' => $isFixedPrice ? $this->priceCurrency->convert($productAmount->getBaseAmount()) : 0, 'priceType' => $currentProduct->getPriceType(), 'specialPrice' => $currentProduct->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\SpecialPrice::PRICE_CODE)->getValue(), 'includeTax' => $this->_taxData->priceIncludesTax() ? 'true' : 'false', 'isFixedPrice' => $isFixedPrice);
     $config['finalPrice'] = $this->_taxData->displayPriceIncludingTax() ? $config['finalBasePriceInclTax'] : $config['finalBasePriceExclTax'];
     if ($preConfiguredFlag && !empty($defaultValues)) {
         $config['defaultValues'] = $defaultValues;
     }
     return $this->jsonEncoder->encode($config);
 }
Ejemplo n.º 16
0
 /**
  * Prepare additional options/information for order item which will be
  * created from this product
  *
  * @param \Magento\Catalog\Model\Product $product
  * @return array
  */
 public function getOrderOptions($product)
 {
     $optionArr = parent::getOrderOptions($product);
     $bundleOptions = [];
     if ($product->hasCustomOptions()) {
         $customOption = $product->getCustomOption('bundle_option_ids');
         $optionIds = unserialize($customOption->getValue());
         $options = $this->getOptionsByIds($optionIds, $product);
         $customOption = $product->getCustomOption('bundle_selection_ids');
         $selectionIds = unserialize($customOption->getValue());
         $selections = $this->getSelectionsByIds($selectionIds, $product);
         foreach ($selections->getItems() as $selection) {
             if ($selection->isSalable()) {
                 $selectionQty = $product->getCustomOption('selection_qty_' . $selection->getSelectionId());
                 if ($selectionQty) {
                     $price = $product->getPriceModel()->getSelectionFinalTotalPrice($product, $selection, 0, $selectionQty->getValue());
                     $option = $options->getItemById($selection->getOptionId());
                     if (!isset($bundleOptions[$option->getId()])) {
                         $bundleOptions[$option->getId()] = ['option_id' => $option->getId(), 'label' => $option->getTitle(), 'value' => []];
                     }
                     $bundleOptions[$option->getId()]['value'][] = ['title' => $selection->getName(), 'qty' => $selectionQty->getValue(), 'price' => $this->priceCurrency->convert($price)];
                 }
             }
         }
     }
     $optionArr['bundle_options'] = $bundleOptions;
     /**
      * Product Prices calculations save
      */
     if ($product->getPriceType()) {
         $optionArr['product_calculations'] = self::CALCULATE_PARENT;
     } else {
         $optionArr['product_calculations'] = self::CALCULATE_CHILD;
     }
     $optionArr['shipment_type'] = $product->getShipmentType();
     return $optionArr;
 }
Ejemplo n.º 17
0
 /**
  * Convert prices for template
  *
  * @param float $amount
  * @param bool $format
  * @return float
  */
 public function convertPrice($amount, $format = false)
 {
     return $format ? $this->priceCurrency->convertAndFormat($amount) : $this->priceCurrency->convert($amount);
 }
Ejemplo n.º 18
0
 /**
  * Convert price from default currency to current currency
  *
  * @param float $price
  * @param boolean $format             Format price to currency format
  * @param boolean $includeContainer   Enclose into <span class="price"><span>
  * @return float
  */
 public function formatPrice($price, $format = true, $includeContainer = true)
 {
     return $format ? $this->priceCurrency->convertAndFormat($price, $includeContainer) : $this->priceCurrency->convert($price);
 }
 /**
  * Convert a quote/order/invoice/credit memo item to a tax details item objects
  *
  * This includes tax for the item as well as any additional line item tax information like Gift Wrapping
  *
  * @param QuoteDetailsItemInterface $item
  * @param GetTaxResult $getTaxResult
  * @param bool $useBaseCurrency
  * @param \Magento\Framework\App\ScopeInterface $scope
  * @return \Magento\Tax\Api\Data\TaxDetailsItemInterface
  */
 protected function getTaxDetailsItem(QuoteDetailsItemInterface $item, GetTaxResult $getTaxResult, $useBaseCurrency, $scope)
 {
     $price = $item->getUnitPrice();
     /* @var $taxLine \AvaTax\TaxLine  */
     $taxLine = $getTaxResult->getTaxLine($item->getCode());
     // Items that are children of other items won't have lines in the response
     if (!$taxLine instanceof \AvaTax\TaxLine) {
         return false;
     }
     $rate = (double) ($taxLine->getRate() * Tax::RATE_MULTIPLIER);
     $tax = (double) $taxLine->getTax();
     /**
      * Magento uses base rates for determining what to charge a customer, not the currency rate (i.e., the non-base
      * rate). Because of this, the base amounts are what is being sent to AvaTax for rate calculation. When we get
      * the base tax amounts back from AvaTax, we have to convert those to the current store's currency using the
      * \Magento\Framework\Pricing\PriceCurrencyInterface::convert() method. However if we simply convert the AvaTax
      * base tax amount * currency multiplier, we may run into issues due to rounding.
      *
      * For example, a $9.90 USD base price * a 6% tax rate equals a tax amount of $0.59 (.594 rounded). Assume the
      * current currency has a conversion rate of 2x. The price will display to the user as $19.80. There are two
      * ways we can calculate the tax amount:
      * 1. Multiply the tax amount received back from AvaTax, which would be $1.18 ($0.59 * 2).
      * 2. Multiply using this formula (base price * currency rate) * tax rate) ((9.99 * 2) * .06)
      *    which would be $1.19 (1.188 rounded)
      *
      * The second approach is more accurate and is what we are doing here.
      */
     if (!$useBaseCurrency) {
         /**
          * We could recalculate the amount using the same logic found in this class:
          * @see \ClassyLlama\AvaTax\Framework\Interaction\Line::convertTaxQuoteDetailsItemToData,
          * but using the taxable amount returned back from AvaTax is the only way to get an accurate amount as
          * some items sent to AvaTax may be tax exempt
          */
         $taxableAmount = (double) $taxLine->getTaxable();
         $amount = $this->priceCurrency->convert($taxableAmount, $scope);
         $tax = $amount * $taxLine->getRate();
         $tax = $this->calculationTool->round($tax);
     }
     $rowTax = $tax;
     /**
      * In native Magento, the "row_total_incl_tax" and "base_row_total_incl_tax" fields contain the tax before
      * discount. The AvaTax 15 API doesn't have the concept of before/after discount tax, so in order to determine
      * the "before discount tax amount", we need to multiply the discount by the rate returned by AvaTax.
      * @see \Magento\Tax\Model\Calculation\AbstractAggregateCalculator::calculateWithTaxNotInPrice
      *
      * If the rate is 0, then this product doesn't have taxes applied and tax on discount shouldn't be calculated.
      * If tax is 0, then item was tax-exempt for some reason and tax on discount shouldn't be calculated
      */
     if ($taxLine->getRate() > 0 && $tax > 0) {
         /**
          * Accurately calculating what AvaTax would have charged before discount requires checking to see if any
          * of the tax amount is tax exempt. If so, we need to find out what percentage of the total amount AvaTax
          * deemed as taxable and then use that percentage when calculating the discount amount. This partially
          * taxable scenario can arise in a situation like this:
          * @see https://help.avalara.com/kb/001/Why_is_freight_taxed_partially_on_my_sale
          *
          * To test this functionality, you can create a "Base Override" Tax Rule in the AvaTax admin to mark certain
          * jurisdictions as partially taxable.
          */
         $taxableAmountPercentage = 1;
         if ($taxLine->getExemption() > 0) {
             // This value is the total amount sent to AvaTax for tax calculation, before AvaTax determined what
             // portion of the amount is taxable
             $totalAmount = $taxLine->getTaxable() + $taxLine->getExemption();
             // Avoid division by 0
             if ($totalAmount != 0) {
                 $taxableAmountPercentage = $taxLine->getTaxable() / $totalAmount;
             }
         }
         $effectiveDiscountAmount = $taxableAmountPercentage * $item->getDiscountAmount();
         $taxOnDiscountAmount = $effectiveDiscountAmount * $taxLine->getRate();
         $taxOnDiscountAmount = $this->calculationTool->round($taxOnDiscountAmount);
         $rowTaxBeforeDiscount = $rowTax + $taxOnDiscountAmount;
     } else {
         $rowTaxBeforeDiscount = 0;
     }
     $extensionAttributes = $item->getExtensionAttributes();
     if ($extensionAttributes) {
         $quantity = $extensionAttributes->getTotalQuantity() !== null ? $extensionAttributes->getTotalQuantity() : $item->getQuantity();
     } else {
         $quantity = $item->getQuantity();
     }
     $rowTotal = $price * $quantity;
     $rowTotalInclTax = $rowTotal + $rowTaxBeforeDiscount;
     $priceInclTax = $rowTotalInclTax / $quantity;
     /**
      * Since the AvaTax extension does not support merchants adding products with tax already factored into the
      * price, we don't need to do any calculations for this number. The only time this value would be something
      * other than 0 is when this method runs:
      * @see \Magento\Tax\Model\Calculation\AbstractAggregateCalculator::calculateWithTaxInPrice
      */
     $discountTaxCompensationAmount = 0;
     /**
      * The \Magento\Tax\Model\Calculation\AbstractAggregateCalculator::calculateWithTaxNotInPrice method that this
      * method is patterned off of has $round as a variable, but any time that method is used in the context of a
      * collect totals on a quote, rounding is always used.
      */
     $round = true;
     if ($round) {
         $priceInclTax = $this->calculationTool->round($priceInclTax);
     }
     $appliedTax = $this->getAppliedTax($getTaxResult, $rowTax);
     $appliedTaxes = [$appliedTax->getTaxRateKey() => $appliedTax];
     return $this->taxDetailsItemDataObjectFactory->create()->setCode($item->getCode())->setType($item->getType())->setRowTax($rowTax)->setPrice($price)->setPriceInclTax($priceInclTax)->setRowTotal($rowTotal)->setRowTotalInclTax($rowTotalInclTax)->setDiscountTaxCompensationAmount($discountTaxCompensationAmount)->setAssociatedItemCode($item->getAssociatedItemCode())->setTaxPercent($rate)->setAppliedTaxes($appliedTaxes);
 }