/** * @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; }
/** * 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; } }
/** * Get AvaTax Tax Code for a product * * @param \Magento\Catalog\Model\Product $product * @param string $storeId * @return null|string */ public function getAvataxTaxCodeForProduct(\Magento\Catalog\Model\Product $product, $storeId) { if ($product->getTypeId() == self::PRODUCT_TYPE_GIFTCARD) { return $this->getAvataxTaxCodeForGiftOptions($storeId); } else { return $this->getAvaTaxTaxCode($product->getTaxClassId()); } }
/** * Set current attribute to entry (for specified product) * * @param \Magento\Catalog\Model\Product $product * @param \Magento\Framework\Gdata\Gshopping\Entry $entry * @return \Magento\Framework\Gdata\Gshopping\Entry * @throws \Magento\Framework\Exception\LocalizedException */ public function convertAttribute($product, $entry) { $entry->cleanTaxes(); if ($this->_taxData->getConfig()->priceIncludesTax()) { return $entry; } $defaultCustomerTaxClassId = $this->_getDefaultCustomerTaxClassId($product->getStoreId()); $rates = $this->_taxRateManagement->getRatesByCustomerAndProductTaxClassId($defaultCustomerTaxClassId, $product->getTaxClassId()); $targetCountry = $this->_config->getTargetCountry($product->getStoreId()); $ratesTotal = 0; foreach ($rates as $rate) { $countryId = $rate->getTaxCountryId(); $postcode = $rate->getTaxPostcode(); if ($targetCountry == $countryId) { $regions = $this->_getRegionsByRegionId($rate->getTaxRegionId(), $postcode); $ratesTotal += count($regions); if ($ratesTotal > self::RATES_MAX) { throw new \Magento\Framework\Exception\LocalizedException(__('Google shopping only supports %1 tax rates per product', self::RATES_MAX)); } foreach ($regions as $region) { $adjustments = $product->getPriceInfo()->getAdjustments(); if (array_key_exists('tax', $adjustments)) { $taxIncluded = true; } else { $taxIncluded = false; } $quoteDetailsItemDataArray = ['code' => $product->getSku(), 'type' => 'product', 'tax_class_key' => [TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_ID, TaxClassKeyInterface::KEY_VALUE => $product->getTaxClassId()], 'unit_price' => $product->getPrice(), 'quantity' => 1, 'tax_included' => $taxIncluded, 'short_description' => $product->getName()]; $billingAddressDataArray = ['country_id' => $countryId, 'region' => ['region_id' => $rate->getTaxRegionId()], 'postcode' => $postcode]; $shippingAddressDataArray = ['country_id' => $countryId, 'region' => ['region_id' => $rate->getTaxRegionId()], 'postcode' => $postcode]; $quoteDetailsDataArray = ['billing_address' => $billingAddressDataArray, 'shipping_address' => $shippingAddressDataArray, 'customer_tax_class_key' => [TaxClassKeyInterface::KEY_TYPE => TaxClassKeyInterface::TYPE_ID, TaxClassKeyInterface::KEY_VALUE => $defaultCustomerTaxClassId], 'items' => [$quoteDetailsItemDataArray]]; $quoteDetailsObject = $this->_quoteDetailsFactory->create(); $this->dataObjectHelper->populateWithArray($quoteDetailsObject, $quoteDetailsDataArray, '\\Magento\\Tax\\Api\\Data\\QuoteDetailsInterface'); $taxDetails = $this->_taxCalculationService->calculateTax($quoteDetailsObject, $product->getStoreId()); $taxRate = $taxDetails->getTaxAmount() / $taxDetails->getSubtotal() * 100; $entry->addTax(['tax_rate' => $taxRate, 'tax_country' => $countryId, 'tax_region' => $region]); } } } return $entry; }
/** * 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|Address $shippingAddress * @param null|Address $billingAddress * @param null|int $ctc customer tax class * @param null|string|bool|int|Store $store * @param bool $priceIncludesTax flag what price parameter contain tax * @param bool $roundPrice * @return float */ 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 (is_null($priceIncludesTax)) { $priceIncludesTax = $this->_taxConfig->priceIncludesTax($store); } $shippingAddressDataObject = null; if ($shippingAddress instanceof \Magento\Customer\Model\Address\AbstractAddress) { $shippingAddressDataObject = $this->_addressConverter->createAddressFromModel($shippingAddress, null, null); } $billingAddressDataObject = null; if ($billingAddress instanceof \Magento\Customer\Model\Address\AbstractAddress) { $billingAddressDataObject = $this->_addressConverter->createAddressFromModel($billingAddress, null, null); } $item = $this->_quoteDetailsItemBuilder->setQuantity(1)->setCode($product->getSku())->setShortDescription($product->getShortDescription())->setTaxClassKey($this->_taxClassKeyBuilder->setType(TaxClassKey::TYPE_ID)->setValue($product->getTaxClassId())->create())->setTaxIncluded($priceIncludesTax)->setType('product')->setUnitPrice($price)->create(); $quoteDetails = $this->_quoteDetailsBuilder->setShippingAddress($shippingAddressDataObject)->setBillingAddress($billingAddressDataObject)->setCustomerTaxClassKey($this->_taxClassKeyBuilder->setType(TaxClassKey::TYPE_ID)->setValue($ctc)->create())->setItems([$item])->setCustomerId($this->_customerSession->getCustomerId())->create(); $storeId = null; if ($store) { $storeId = $store->getId(); } $taxDetails = $this->_taxCalculationService->calculateTax($quoteDetails, $storeId); $items = $taxDetails->getItems(); $taxDetailsItem = array_shift($items); if (!is_null($includingTax)) { 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 $store->roundPrice($price); } else { return $price; } }
/** * Set current attribute to entry (for specified product) * * @param \Magento\Catalog\Model\Product $product * @param \Magento\Framework\Gdata\Gshopping\Entry $entry * @return \Magento\Framework\Gdata\Gshopping\Entry */ public function convertAttribute($product, $entry) { $entry->cleanTaxes(); if ($this->_taxData->getConfig()->priceIncludesTax()) { return $entry; } $calc = $this->calculation; $customerTaxClass = $calc->getDefaultCustomerTaxClass($product->getStoreId()); $rates = $calc->getRatesByCustomerAndProductTaxClasses($customerTaxClass, $product->getTaxClassId()); $targetCountry = $this->_config->getTargetCountry($product->getStoreId()); $ratesTotal = 0; foreach ($rates as $rate) { if ($targetCountry == $rate['country']) { $regions = $this->_parseRegions($rate['state'], $rate['postcode']); $ratesTotal += count($regions); if ($ratesTotal > self::RATES_MAX) { throw new \Magento\Framework\Model\Exception(__("Google shopping only supports %1 tax rates per product", self::RATES_MAX)); } foreach ($regions as $region) { $entry->addTax(array('tax_rate' => $rate['value'] * 100, 'tax_country' => empty($rate['country']) ? '*' : $rate['country'], 'tax_region' => $region)); } } } return $entry; }