public function testCalculateTax()
 {
     $storeId = 3;
     $algorithm = 'algorithm';
     $customerId = 100;
     $taxClassId = 200;
     $taxDetailsData = [\Magento\Tax\Model\TaxDetails\TaxDetails::KEY_SUBTOTAL => 0.0, \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_TAX_AMOUNT => 0.0, \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT => 0.0, \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_APPLIED_TAXES => [], \Magento\Tax\Model\TaxDetails\TaxDetails::KEY_ITEMS => []];
     $quoteDetailsMock = $this->getMock('\\Magento\\Tax\\Api\\Data\\QuoteDetailsInterface');
     $storeMock = $this->getMock('\\Magento\\Store\\Model\\Store', ['getStoreId'], [], '', false);
     $this->storeManager->expects($this->once())->method('getStore')->willReturn($storeMock);
     $storeMock->expects($this->once())->method('getStoreId')->willReturn($storeId);
     $billAddressMock = $this->getMock('Magento\\Customer\\Api\\Data\\AddressInterface', [], [], '', false);
     $shipAddressMock = $this->getMock('Magento\\Customer\\Api\\Data\\AddressInterface', [], [], '', false);
     $taxClassKeyMock = $this->getMock('\\Magento\\Tax\\Api\\Data\\TaxClassKeyInterface');
     $quoteDetailsItemMock = $this->getMock('\\Magento\\Tax\\Api\\Data\\QuoteDetailsItemInterface');
     $quoteDetailsMock->expects($this->once())->method('getItems')->willReturn([$quoteDetailsItemMock]);
     $quoteDetailsMock->expects($this->once())->method('getBillingAddress')->willReturn($billAddressMock);
     $quoteDetailsMock->expects($this->once())->method('getShippingAddress')->willReturn($shipAddressMock);
     $quoteDetailsMock->expects($this->once())->method('getCustomerId')->willReturn($customerId);
     $quoteDetailsMock->expects($this->once())->method('getCustomerTaxClassKey')->willReturn($taxClassKeyMock);
     $this->configMock->expects($this->once())->method('getAlgorithm')->with($storeId)->willReturn($algorithm);
     $this->taxClassManagementMock->expects($this->once())->method('getTaxClassId')->with($taxClassKeyMock, 'customer')->willReturn($taxClassId);
     $calculatorMock = $this->getMock('Magento\\Tax\\Model\\Calculation\\TotalBaseCalculator', [], [], '', false);
     $this->calculatorFactory->expects($this->once())->method('create')->with($algorithm, $storeId, $billAddressMock, $shipAddressMock, $taxClassId, $customerId)->willReturn($calculatorMock);
     $taxDetailsMock = $this->getMock('\\Magento\\Tax\\Api\\Data\\TaxDetailsItemInterface');
     $calculatorMock->expects($this->once())->method('calculate')->willReturn($taxDetailsMock);
     $taxDetailsMock = $this->getMock('\\Magento\\Tax\\Api\\Data\\TaxDetailsInterface');
     $this->taxDetailsDataObjectFactory->expects($this->once())->method('create')->willReturn($taxDetailsMock);
     $this->dataObjectHelperMock->expects($this->once())->method('populateWithArray')->with($taxDetailsMock, $taxDetailsData)->willReturnSelf();
     $this->assertEquals($taxDetailsMock, $this->taxCalculationService->calculateTax($quoteDetailsMock));
 }
 /**
  * @magentoDbIsolation enabled
  * @dataProvider multiRulesUnitBasedDataProvider
  * @magentoConfigFixture default_store tax/calculation/algorithm UNIT_BASE_CALCULATION
  */
 public function testMultiRulesUnitBased($quoteDetailsData, $expectedTaxDetails)
 {
     $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
     $quoteDetails = $this->quoteDetailsFactory->create();
     $this->dataObjectHelper->populateWithArray($quoteDetails, $quoteDetailsData, '\\Magento\\Tax\\Api\\Data\\QuoteDetailsInterface');
     $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails);
     $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails));
 }
Beispiel #3
0
 /**
  * Get all tax rates JSON for all product tax classes.
  *
  * @return string
  */
 public function getAllRatesByProductClassJson()
 {
     $result = [];
     foreach ($this->productTaxClassSource->getAllOptions() as $productTaxClass) {
         $taxClassId = $productTaxClass['value'];
         $taxRate = $this->calculationService->getDefaultCalculatedRate($taxClassId, $this->currentCustomer->getCustomerId(), $this->getStore()->getId());
         $result["value_{$taxClassId}"] = $taxRate;
     }
     return $this->jsonHelper->jsonEncode($result);
 }
Beispiel #4
0
 /**
  * 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;
 }
Beispiel #5
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;
     }
 }