예제 #1
0
 /**
  * @param \Magento\Sales\Model\Quote\Address $address
  * @return $this
  */
 public function collect(\Magento\Sales\Model\Quote\Address $address)
 {
     $store = $address->getQuote()->getStore();
     $address->setTaxAmount(0);
     $address->setBaseTaxAmount(0);
     $address->setAppliedTaxes(array());
     $items = $address->getAllItems();
     if (!count($items)) {
         return $this;
     }
     $custTaxClassId = $address->getQuote()->getCustomerTaxClassId();
     $taxCalculationModel = $this->_calculation;
     /* @var $taxCalculationModel \Magento\Tax\Model\Calculation */
     $request = $taxCalculationModel->getRateRequest($address, $address->getQuote()->getBillingAddress(), $custTaxClassId, $store);
     foreach ($items as $item) {
         /**
          * Child item's tax we calculate for parent
          */
         if ($item->getParentItemId()) {
             continue;
         }
         /**
          * We calculate parent tax amount as sum of children's tax amounts
          */
         if ($item->getHasChildren() && $item->isChildrenCalculated()) {
             foreach ($item->getChildren() as $child) {
                 $discountBefore = $item->getDiscountAmount();
                 $baseDiscountBefore = $item->getBaseDiscountAmount();
                 $rate = $taxCalculationModel->getRate($request->setProductClassId($child->getProduct()->getTaxClassId()));
                 $child->setTaxPercent($rate);
                 $child->calcTaxAmount();
                 if ($discountBefore != $item->getDiscountAmount()) {
                     $address->setDiscountAmount($address->getDiscountAmount() + ($item->getDiscountAmount() - $discountBefore));
                     $address->setBaseDiscountAmount($address->getBaseDiscountAmount() + ($item->getBaseDiscountAmount() - $baseDiscountBefore));
                     $address->setGrandTotal($address->getGrandTotal() - ($item->getDiscountAmount() - $discountBefore));
                     $address->setBaseGrandTotal($address->getBaseGrandTotal() - ($item->getBaseDiscountAmount() - $baseDiscountBefore));
                 }
                 $this->_saveAppliedTaxes($address, $taxCalculationModel->getAppliedRates($request), $child->getTaxAmount(), $child->getBaseTaxAmount(), $rate);
             }
             $itemTaxAmount = $item->getTaxAmount() + $item->getDiscountTaxCompensation();
             $address->setTaxAmount($address->getTaxAmount() + $itemTaxAmount);
             $itemBaseTaxAmount = $item->getBaseTaxAmount() + $item->getBaseDiscountTaxCompensation();
             $address->setBaseTaxAmount($address->getBaseTaxAmount() + $itemBaseTaxAmount);
         } else {
             $discountBefore = $item->getDiscountAmount();
             $baseDiscountBefore = $item->getBaseDiscountAmount();
             $rate = $taxCalculationModel->getRate($request->setProductClassId($item->getProduct()->getTaxClassId()));
             $item->setTaxPercent($rate);
             $item->calcTaxAmount();
             if ($discountBefore != $item->getDiscountAmount()) {
                 $address->setDiscountAmount($address->getDiscountAmount() + ($item->getDiscountAmount() - $discountBefore));
                 $address->setBaseDiscountAmount($address->getBaseDiscountAmount() + ($item->getBaseDiscountAmount() - $baseDiscountBefore));
                 $address->setGrandTotal($address->getGrandTotal() - ($item->getDiscountAmount() - $discountBefore));
                 $address->setBaseGrandTotal($address->getBaseGrandTotal() - ($item->getBaseDiscountAmount() - $baseDiscountBefore));
             }
             $itemTaxAmount = $item->getTaxAmount() + $item->getDiscountTaxCompensation();
             $address->setTaxAmount($address->getTaxAmount() + $itemTaxAmount);
             $itemBaseTaxAmount = $item->getBaseTaxAmount() + $item->getBaseDiscountTaxCompensation();
             $address->setBaseTaxAmount($address->getBaseTaxAmount() + $itemBaseTaxAmount);
             $applied = $taxCalculationModel->getAppliedRates($request);
             $this->_saveAppliedTaxes($address, $applied, $item->getTaxAmount(), $item->getBaseTaxAmount(), $rate);
         }
     }
     $shippingTaxClass = $this->_scopeConfig->getValue(\Magento\Tax\Model\Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
     $shippingTax = 0;
     $shippingBaseTax = 0;
     if ($shippingTaxClass) {
         $rate = $taxCalculationModel->getRate($request->setProductClassId($shippingTaxClass));
         if ($rate) {
             if (!$this->_taxData->shippingPriceIncludesTax()) {
                 $shippingTax = $address->getShippingAmount() * $rate / 100;
                 $shippingBaseTax = $address->getBaseShippingAmount() * $rate / 100;
             } else {
                 $shippingTax = $address->getShippingTaxAmount();
                 $shippingBaseTax = $address->getBaseShippingTaxAmount();
             }
             $shippingTax = $this->priceCurrency->round($shippingTax);
             $shippingBaseTax = $this->priceCurrency->round($shippingBaseTax);
             $address->setTaxAmount($address->getTaxAmount() + $shippingTax);
             $address->setBaseTaxAmount($address->getBaseTaxAmount() + $shippingBaseTax);
             $this->_saveAppliedTaxes($address, $taxCalculationModel->getAppliedRates($request), $shippingTax, $shippingBaseTax, $rate);
         }
     }
     if (!$this->_taxData->shippingPriceIncludesTax()) {
         $address->setShippingTaxAmount($shippingTax);
         $address->setBaseShippingTaxAmount($shippingBaseTax);
     }
     $address->setGrandTotal($address->getGrandTotal() + $address->getTaxAmount());
     $address->setBaseGrandTotal($address->getBaseGrandTotal() + $address->getBaseTaxAmount());
     return $this;
 }