diff --git a/Model/Config.php b/Model/Config.php index db5a2f1..c00fc24 100644 --- a/Model/Config.php +++ b/Model/Config.php @@ -15,6 +15,9 @@ */ class Config implements ConfigInterface { + const DYNAMIC_TYPE_DEFAULT = 0; + const DYNAMIC_TYPE_HIGHEST_PRODUCT_TAX = 1; + /** * Configuration reader * diff --git a/Model/System/Config/Source/Tax/Dynamic.php b/Model/System/Config/Source/Tax/Dynamic.php new file mode 100644 index 0000000..5b34be2 --- /dev/null +++ b/Model/System/Config/Source/Tax/Dynamic.php @@ -0,0 +1,46 @@ +options) { + $options = [ + [ + 'value' => Config::DYNAMIC_TYPE_DEFAULT, + 'label' => __('No dynamic shipping tax caluclation') + ], + [ + 'value' => Config::DYNAMIC_TYPE_HIGHEST_PRODUCT_TAX, + 'label' => __('Use the highest product tax') + ] + ]; + + $this->options = $options; + } + + return $this->options; + } +} diff --git a/Plugin/Tax/Config/AroundGetShippingTaxClassPlugin.php b/Plugin/Tax/Config/AroundGetShippingTaxClassPlugin.php new file mode 100644 index 0000000..73c3333 --- /dev/null +++ b/Plugin/Tax/Config/AroundGetShippingTaxClassPlugin.php @@ -0,0 +1,167 @@ +scopeConfig = $scopeConfig; + $this->cart = $cart; + $this->customerSession = $customerSession; + $this->groupRepository = $groupRepository; + $this->taxCalculation = $taxCalculation; + } + + /** + * @param \Magento\Tax\Model\Config $subject + * @param \Closure $proceed + * @param null|string|bool|int|Store $store + * @return mixed + */ + public function aroundGetShippingTaxClass(\Magento\Tax\Model\Config $subject, \Closure $proceed, $store) + { + $handle = \fopen('abc.log', 'w+'); + + $dynamicType = (int)$this->scopeConfig->getValue( + self::CONFIG_PATH_DYNAMIC_SHIPPING_TAX_CLASS, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $store + ); + + // TODO: Check for admin quote + + $quoteItems = $this->cart->getItems(); + + // If the default behaviour was configured or there are no products in cart, use default tax class id + if ($dynamicType == Config::DYNAMIC_TYPE_DEFAULT || count($quoteItems) == 0) { + return $proceed($store); + } + + $taxClassId = false; + + // Retrieve the highest product tax class + if ($dynamicType == Config::DYNAMIC_TYPE_HIGHEST_PRODUCT_TAX) { + $taxClassId = $this->getHighestProductTaxClassId($quoteItems, $store); + } + + // If no tax class id was found, use default one + if (!$taxClassId) { + $taxClassId = $proceed($store); + } + + return $taxClassId; + } + + /** + * @param array $quoteItems + * @param null|string|bool|int|Store $store + * @return bool|mixed|null + */ + private function getHighestProductTaxClassId($quoteItems, $store) + { + $taxClassIds = []; + $highestTaxRate = null; + + foreach ($quoteItems as $quoteItem) { + /** @var $quoteItem \Magento\Quote\Model\Quote\Item */ + if ($quoteItem->getParentItem()) { + continue; + } + + // Retrieve the tax percent + $taxPercent = $quoteItem->getTaxPercent(); + if (!$taxPercent) { + $taxPercent = $this->getTaxPercent($quoteItem->getTaxClassId(), $store); + } + + // Add the tax class + if (is_float($taxPercent) && !in_array($taxPercent, $taxClassIds)) { + $taxClassIds[$taxPercent] = $quoteItem->getTaxClassId(); + } + } + + // Fetch the highest tax rate + ksort($taxClassIds); + if (count($taxClassIds) > 0) { + $highestTaxRate = array_pop($taxClassIds); + } + if (!$highestTaxRate || is_null($highestTaxRate)) { + return false; + } + + return $highestTaxRate; + } + + /** + * @param int $productTaxClassId + * @param null|string|bool|int|Store $store + * @return float|int + */ + private function getTaxPercent($productTaxClassId, $store) + { + $groupId = $this->customerSession->getCustomerGroupId(); + $group = $this->groupRepository->getById($groupId); + $customerTaxClassId = $group->getTaxClassId(); + + $request = $this->taxCalculation->getRateRequest(null, null, $customerTaxClassId, $store); + $request->setData('product_class_id', $productTaxClassId); + + $taxPercent = $this->taxCalculation->getRate($request); + if (!$taxPercent) { + $taxPercent = 0; + } + + return $taxPercent; + } +} diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 8b27d65..f61b8ce 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -136,5 +136,13 @@ +
+ + + + FireGento\MageSetup\Model\System\Config\Source\Tax\Dynamic + + +
diff --git a/etc/di.xml b/etc/di.xml index f007547..3c974d7 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -43,4 +43,8 @@ + + + +