/** * 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); } }
/** * Check to see if there are any native tax rules created that may affect AvaTax * * @return array */ public function checkNativeTaxRules() { $errors = []; if ($this->avaTaxConfig->isModuleEnabled() && $this->avaTaxConfig->getTaxMode($this->storeManager->getDefaultStoreView()) != Config::TAX_MODE_NO_ESTIMATE_OR_SUBMIT && !$this->avaTaxConfig->isNativeTaxRulesIgnored()) { $taxRules = $this->taxRuleRepository->getList($this->searchCriteriaBuilder->create()); if (count($taxRules->getItems())) { $errors[] = __('You have %1 native Magento Tax Rule(s) configured. ' . 'Please <a href="%2">review the tax rule(s)</a> and delete any that you do not specifically want enabled. ' . 'You should only have rules setup if you want to use them as backup rules in case of AvaTax ' . 'errors (see <a href="#row_tax_avatax_error_handling_header">Error Action setting</a>) ' . 'or if you need to support VAT tax. ' . '<a href="%3">Ignore this notification</a>.', count($taxRules->getItems()), $this->backendUrl->getUrl('tax/rule'), $this->backendUrl->getUrl('avatax/tax/ignoreTaxRuleNotification')); } } return $errors; }
/** * Check whether notification is displayed * * @return bool */ public function isDisplayed() { // Check configuration to see if this should be evaluated further if ($this->avaTaxConfig->isModuleEnabled() == false || $this->avaTaxConfig->getTaxMode($this->storeManager->getDefaultStoreView()) != Config::TAX_MODE_ESTIMATE_AND_SUBMIT || $this->avaTaxConfig->getQueueAdminNotificationEnabled() == false) { return false; } // Query the database to get some stats about the queue $this->loadQueueStats(); // Determine if we need to notify the admin user if ($this->authorization->isAllowed('ClassyLlama_AvaTax::manage_avatax') && $this->statQueueCount > 0) { return true; } else { return false; } }
/** * @param \Magento\Sales\Model\Spi\InvoiceResourceInterface $subject * @param \Closure $proceed * * I include both the extended AbstractModel and implemented Interface here for the IDE's benefit * @param \Magento\Framework\Model\AbstractModel|\Magento\Sales\Api\Data\InvoiceInterface $entity * @return \Magento\Sales\Model\Spi\InvoiceResourceInterface * @throws \Magento\Framework\Exception\CouldNotSaveException */ public function aroundSave(InvoiceResourceInterface $subject, \Closure $proceed, AbstractModel $entity) { // Check to see if this is a newly created entity and store the determination for later evaluation after // the entity is saved via plugin closure. After the entity is saved it will not be listed as new any longer. $isObjectNew = $entity->isObjectNew(); // Save AvaTax extension attributes if ($this->avaTaxConfig->isModuleEnabled($entity->getStoreId())) { // check to see if any extension attributes exist and set them on the model for saving to the db $extensionAttributes = $entity->getExtensionAttributes(); if ($extensionAttributes && $extensionAttributes->getAvataxIsUnbalanced() !== null) { $entity->setData('avatax_is_unbalanced', $extensionAttributes->getAvataxIsUnbalanced()); } if ($extensionAttributes && $extensionAttributes->getBaseAvataxTaxAmount() !== null) { $entity->setData('base_avatax_tax_amount', $extensionAttributes->getBaseAvataxTaxAmount()); } // Updating a field to trigger a change to the record when avatax_is_unbalanced and base_avatax_tax_amount // are both false or 0 which evaluate the same as null in the isModified check if ($extensionAttributes && ($extensionAttributes->getAvataxIsUnbalanced() !== null && ($entity->getOrigData('avatax_is_unbalanced') === null || $extensionAttributes->getAvataxIsUnbalanced() != $entity->getOrigData('avatax_is_unbalanced')) || $extensionAttributes->getBaseAvataxTaxAmount() !== null && ($entity->getOrigData('base_avatax_tax_amount') === null || $extensionAttributes->getBaseAvataxTaxAmount() != $entity->getOrigData('base_avatax_tax_amount')))) { $entity->setUpdatedAt($this->dateTime->gmtDate()); } } /** @var \Magento\Sales\Model\Spi\InvoiceResourceInterface $resultEntity */ $resultEntity = $proceed($entity); /** @var \Magento\Sales\Model\Order $order */ $order = $entity->getOrder(); $isVirtual = $order->getIsVirtual(); $address = $isVirtual ? $entity->getBillingAddress() : $entity->getShippingAddress(); $storeId = $entity->getStoreId(); // Queue the entity to be sent to AvaTax if ($this->avaTaxConfig->isModuleEnabled($entity->getStoreId()) && $this->avaTaxConfig->getTaxMode($entity->getStoreId()) == Config::TAX_MODE_ESTIMATE_AND_SUBMIT && $this->avaTaxConfig->isAddressTaxable($address, $storeId)) { // Add this entity to the avatax processing queue if this is a new entity if ($isObjectNew) { /** @var Queue $queue */ $queue = $this->queueFactory->create(); $queue->build($entity->getStoreId(), Queue::ENTITY_TYPE_CODE_INVOICE, $entity->getEntityId(), $entity->getIncrementId(), Queue::QUEUE_STATUS_PENDING); $queue->save(); $this->avaTaxLogger->debug(__('Added entity to the queue'), ['queue_id' => $queue->getId(), 'entity_type_code' => Queue::ENTITY_TYPE_CODE_INVOICE, 'entity_id' => $entity->getEntityId()]); } } return $resultEntity; }
/** * Map extra taxables associated with quote. Add AvaTax details to extension objects. * * @param QuoteDetailsItemInterfaceFactory $itemDataObjectFactory * @param Address $address * @param bool $useBaseCurrency * @return \Magento\Tax\Api\Data\QuoteDetailsItemInterface[] */ public function mapQuoteExtraTaxables(QuoteDetailsItemInterfaceFactory $itemDataObjectFactory, Address $address, $useBaseCurrency) { $itemDataObjects = parent::mapQuoteExtraTaxables($itemDataObjectFactory, $address, $useBaseCurrency); $storeId = $address->getQuote()->getStore()->getId(); if (!$this->config->isModuleEnabled($storeId) || $this->config->getTaxMode($storeId) == Config::TAX_MODE_NO_ESTIMATE_OR_SUBMIT || !$this->config->isAddressTaxable($address, $storeId)) { return $itemDataObjects; } foreach ($itemDataObjects as $itemDataObject) { switch ($itemDataObject->getType()) { case Giftwrapping::QUOTE_TYPE: $itemCode = $this->config->getSkuGiftWrapOrder($storeId); $taxCode = $this->taxClassHelper->getAvataxTaxCodeForGiftOptions($storeId); $this->addExtensionAttributesToTaxQuoteDetailsItem($itemDataObject, $itemCode, $taxCode, \ClassyLlama\AvaTax\Framework\Interaction\Line::GIFT_WRAP_ORDER_LINE_DESCRIPTION); break; case Giftwrapping::PRINTED_CARD_TYPE: $itemCode = $this->config->getSkuShippingGiftWrapCard($storeId); $taxCode = $this->taxClassHelper->getAvataxTaxCodeForGiftOptions($storeId); $this->addExtensionAttributesToTaxQuoteDetailsItem($itemDataObject, $itemCode, $taxCode, \ClassyLlama\AvaTax\Framework\Interaction\Line::GIFT_WRAP_ORDER_LINE_DESCRIPTION); break; } } return $itemDataObjects; }
/** * Check whether notification is displayed * * @return bool */ public function isDisplayed() { return $this->getText() && $this->isQueuePage() && $this->config->isModuleEnabled() && $this->config->getTaxMode($this->storeManager->getDefaultStoreView()) != Config::TAX_MODE_ESTIMATE_AND_SUBMIT; }