Ejemplo n.º 1
0
 /**
  * If module is enabled, don't run collect totals for shipping
  *
  * Tax calculation for shipping is handled in this class
  * @see \ClassyLlama\AvaTax\Model\Tax\Sales\Total\Quote\Tax::collect()
  * Since this extension doesn't support applying discounts *after* tax, we don't need to run a separate collect
  * process.
  *
  * @param \Magento\Tax\Model\Sales\Total\Quote\Shipping $subject
  * @param \Closure $proceed
  * @param \Magento\Quote\Model\Quote $quote
  * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
  * @param \Magento\Quote\Model\Quote\Address\Total $total
  * @return mixed
  */
 public function aroundCollect(\Magento\Tax\Model\Sales\Total\Quote\Shipping $subject, \Closure $proceed, \Magento\Quote\Model\Quote $quote, \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment, \Magento\Quote\Model\Quote\Address\Total $total)
 {
     $storeId = $quote->getStoreId();
     // If quote is virtual, getShipping will return billing address, so no need to check if quote is virtual
     $address = $shippingAssignment->getShipping()->getAddress();
     if (!$this->config->isModuleEnabled($storeId) || $this->config->getTaxMode($storeId) == Config::TAX_MODE_NO_ESTIMATE_OR_SUBMIT || !$this->config->isAddressTaxable($address, $storeId)) {
         return $proceed($quote, $shippingAssignment, $total);
     }
 }
 /**
  * @param ShippingAssignmentInterface $shippingAssignment
  * @param CartInterface $quote
  * @return void
  * @throws InputException
  */
 public function save(CartInterface $quote, ShippingAssignmentInterface $shippingAssignment)
 {
     /** @var \Magento\Quote\Model\Quote $quote */
     foreach ($shippingAssignment->getItems() as $item) {
         if (!$quote->getItemById($item->getItemId())) {
             $this->cartItemPersister->save($quote, $item);
         }
     }
     $this->shippingProcessor->save($shippingAssignment->getShipping(), $quote);
 }
Ejemplo n.º 3
0
 /**
  * Collect totals process.
  *
  * @param \Magento\Quote\Model\Quote $quote
  * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
  * @param \Magento\Quote\Model\Quote\Address\Total $total
  * @return $this
  */
 public function collect(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment, \Magento\Quote\Model\Quote\Address\Total $total)
 {
     $this->_setAddress($shippingAssignment->getShipping()->getAddress());
     $this->_setTotal($total);
     /**
      * Reset amounts
      */
     $this->_setAmount(0);
     $this->_setBaseAmount(0);
     return $this;
 }
 /**
  * Collect address discount amount
  *
  * @param \Magento\Quote\Model\Quote                          $quote
  * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
  * @param \Magento\Quote\Model\Quote\Address\Total            $total
  *
  * @return $this
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 public function collect(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment, \Magento\Quote\Model\Quote\Address\Total $total)
 {
     $address = $shippingAssignment->getShipping()->getAddress();
     if ($this->_getDiscountCondition($address, $shippingAssignment)) {
         parent::collect($quote, $shippingAssignment, $total);
         $balance = $this->_getDiscountAmount();
         $address->setDiscountCouponAmount($balance);
         $address->setBaseDiscountCouponAmount($balance);
         $total->setDiscountCouponDescription($this->getCode());
         $total->setDiscountCouponAmount($balance);
         $total->setBaseDiscountCouponAmount($balance);
     }
     $total->addTotalAmount($this->getCode(), $address->getDiscountCouponAmount());
     $total->addBaseTotalAmount($this->getCode(), $address->getBaseDiscountCouponAmount());
     return $this;
 }
Ejemplo n.º 5
0
 /**
  * Call tax calculation service to get tax details on the quote and items
  *
  * @param ShippingAssignmentInterface $shippingAssignment
  * @param Address\Total $total
  * @param bool $useBaseCurrency
  * @return \Magento\Tax\Api\Data\TaxDetailsInterface
  */
 protected function getQuoteTaxDetails($shippingAssignment, $total, $useBaseCurrency)
 {
     $address = $shippingAssignment->getShipping()->getAddress();
     //Setup taxable items
     $priceIncludesTax = $this->_config->priceIncludesTax($address->getQuote()->getStore());
     $itemDataObjects = $this->mapItems($shippingAssignment, $priceIncludesTax, $useBaseCurrency);
     //Add shipping
     $shippingDataObject = $this->getShippingDataObject($shippingAssignment, $total, $useBaseCurrency);
     if ($shippingDataObject != null) {
         $itemDataObjects[] = $shippingDataObject;
     }
     //process extra taxable items associated only with quote
     $quoteExtraTaxables = $this->mapQuoteExtraTaxables($this->quoteDetailsItemDataObjectFactory, $address, $useBaseCurrency);
     if (!empty($quoteExtraTaxables)) {
         $itemDataObjects = array_merge($itemDataObjects, $quoteExtraTaxables);
     }
     //Preparation for calling taxCalculationService
     $quoteDetails = $this->prepareQuoteDetails($shippingAssignment, $itemDataObjects);
     $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails, $address->getQuote()->getStore()->getStoreId());
     return $taxDetails;
 }
 /**
  * Update tax related fields for shipping
  *
  * @param ShippingAssignmentInterface $shippingAssignment
  * @param QuoteAddress\Total $total
  * @param TaxDetailsItemInterface $shippingTaxDetails
  * @param TaxDetailsItemInterface $baseShippingTaxDetails
  * @return $this
  */
 protected function processShippingTaxInfo(ShippingAssignmentInterface $shippingAssignment, QuoteAddress\Total $total, $shippingTaxDetails, $baseShippingTaxDetails)
 {
     $total->setTotalAmount('shipping', $shippingTaxDetails->getRowTotal());
     $total->setBaseTotalAmount('shipping', $baseShippingTaxDetails->getRowTotal());
     $total->setTotalAmount('shipping_discount_tax_compensation', $shippingTaxDetails->getDiscountTaxCompensationAmount());
     $total->setBaseTotalAmount('shipping_discount_tax_compensation', $baseShippingTaxDetails->getDiscountTaxCompensationAmount());
     $total->setShippingInclTax($shippingTaxDetails->getRowTotalInclTax());
     $total->setBaseShippingInclTax($baseShippingTaxDetails->getRowTotalInclTax());
     $total->setShippingTaxAmount($shippingTaxDetails->getRowTax());
     $total->setBaseShippingTaxAmount($baseShippingTaxDetails->getRowTax());
     //Add the shipping tax to total tax amount
     $total->addTotalAmount('tax', $shippingTaxDetails->getRowTax());
     $total->addBaseTotalAmount('tax', $baseShippingTaxDetails->getRowTax());
     if ($this->_config->discountTax($shippingAssignment->getShipping()->getAddress()->getQuote()->getStore())) {
         $total->setShippingAmountForDiscount($shippingTaxDetails->getRowTotalInclTax());
         $total->setBaseShippingAmountForDiscount($baseShippingTaxDetails->getRowTotalInclTax());
     }
     return $this;
 }
Ejemplo n.º 7
0
 /**
  * Generate \Magento\Tax\Model\Sales\Quote\QuoteDetails object based on shipping assignment
  *
  * Base closely on this method, with the exception of the tax calculation call to calculate taxes:
  * @see \Magento\Tax\Model\Sales\Total\Quote\Tax::getQuoteTaxDetails()
  *
  * @param ShippingAssignmentInterface $shippingAssignment
  * @param Address\Total $total
  * @param bool $useBaseCurrency
  * @param string $storeId
  * @return \Magento\Tax\Api\Data\QuoteDetailsInterface
  */
 protected function getTaxQuoteDetails($shippingAssignment, $total, $storeId, $useBaseCurrency)
 {
     // If quote is virtual, getShipping will return billing address, so no need to check if quote is virtual
     $address = $shippingAssignment->getShipping()->getAddress();
     //Setup taxable items
     $priceIncludesTax = $this->_config->priceIncludesTax($address->getQuote()->getStore());
     $itemDataObjects = $this->mapItems($shippingAssignment, $priceIncludesTax, $useBaseCurrency);
     //Add shipping
     $shippingDataObject = $this->getShippingDataObject($shippingAssignment, $total, $useBaseCurrency);
     if ($shippingDataObject != null) {
         $this->addInfoToQuoteDetailsItemForShipping($shippingDataObject, $storeId);
         $itemDataObjects[] = $shippingDataObject;
     }
     //process extra taxable items associated only with quote
     $quoteExtraTaxables = $this->mapQuoteExtraTaxables($this->quoteDetailsItemDataObjectFactory, $address, $useBaseCurrency);
     if (!empty($quoteExtraTaxables)) {
         $itemDataObjects = array_merge($itemDataObjects, $quoteExtraTaxables);
     }
     //Preparation for calling taxCalculationService
     $quoteDetails = $this->prepareQuoteDetails($shippingAssignment, $itemDataObjects);
     return $quoteDetails;
 }
Ejemplo n.º 8
0
 /**
  * Convert Tax Quote Details into data to be converted to a GetTax Request
  *
  * @param \Magento\Tax\Api\Data\QuoteDetailsInterface $taxQuoteDetails
  * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
  * @param \Magento\Quote\Api\Data\CartInterface $quote
  * @return array|null
  */
 protected function convertTaxQuoteDetailsToData(\Magento\Tax\Api\Data\QuoteDetailsInterface $taxQuoteDetails, \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment, \Magento\Quote\Api\Data\CartInterface $quote)
 {
     $lines = [];
     $items = $taxQuoteDetails->getItems();
     $keyedItems = $this->taxCalculation->getKeyedItems($items);
     $childrenItems = $this->taxCalculation->getChildrenItems($items);
     /** @var \Magento\Tax\Api\Data\QuoteDetailsItemInterface $item */
     foreach ($keyedItems as $item) {
         /**
          * If a quote has children and they are calculated (e.g., Bundled products with dynamic pricing)
          * @see \Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector::mapItems
          * then we only need to pass child items to AvaTax. Due to the logic in
          * @see \ClassyLlama\AvaTax\Framework\Interaction\TaxCalculation::calculateTaxDetails
          * the parent tax gets calculated based on children items
          */
         //
         if (isset($childrenItems[$item->getCode()])) {
             /** @var \Magento\Tax\Api\Data\QuoteDetailsItemInterface $childItem */
             foreach ($childrenItems[$item->getCode()] as $childItem) {
                 $line = $this->interactionLine->getLine($childItem);
                 if ($line) {
                     $lines[] = $line;
                 }
             }
         } else {
             $line = $this->interactionLine->getLine($item);
             if ($line) {
                 $lines[] = $line;
             }
         }
     }
     // Shipping Address not documented in the interface for some reason
     // they do have a constant for it but not a method in the interface
     //
     // If quote is virtual, getShipping will return billing address, so no need to check if quote is virtual
     $shippingAddress = $shippingAssignment->getShipping()->getAddress();
     $address = $this->address->getAddress($shippingAddress);
     $store = $this->storeRepository->getById($quote->getStoreId());
     $currentDate = $this->getFormattedDate($store);
     // Quote created/updated date is not relevant, so just pass the current date
     $docDate = $currentDate;
     $customerUsageType = $quote->getCustomer() ? $this->taxClassHelper->getAvataxTaxCodeForCustomer($quote->getCustomer()) : null;
     return ['StoreId' => $store->getId(), 'Commit' => false, 'CurrencyCode' => $quote->getCurrency()->getQuoteCurrencyCode(), 'CustomerCode' => $this->getCustomerCode($quote), 'CustomerUsageType' => $customerUsageType, 'DestinationAddress' => $address, 'DocCode' => self::AVATAX_DOC_CODE_PREFIX . $quote->getId(), 'DocDate' => $docDate, 'DocType' => DocumentType::$SalesOrder, 'ExchangeRate' => $this->getExchangeRate($store, $quote->getCurrency()->getBaseCurrencyCode(), $quote->getCurrency()->getQuoteCurrencyCode()), 'ExchangeRateEffDate' => $currentDate, 'Lines' => $lines, 'DetailLevel' => DetailLevel::$Line, 'PurchaseOrderNo' => $quote->getReservedOrderId()];
 }