Skip to content

Commit

Permalink
[FEATURE] #22 Added dynamic shipping tax class calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
therouv committed Jul 3, 2016
1 parent 0f94788 commit 5257977
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Model/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
class Config implements ConfigInterface
{
const DYNAMIC_TYPE_DEFAULT = 0;
const DYNAMIC_TYPE_HIGHEST_PRODUCT_TAX = 1;

/**
* Configuration reader
*
Expand Down
46 changes: 46 additions & 0 deletions Model/System/Config/Source/Tax/Dynamic.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Copyright © 2016 FireGento e.V.
* See LICENSE.md bundled with this module for license details.
*/
namespace FireGento\MageSetup\Model\System\Config\Source\Tax;

use FireGento\MageSetup\Model\Config;

/**
* Class Dynamic
*
* @package FireGento\MageSetup\Model\System\Config\Source\Tax
*/
class Dynamic implements \Magento\Framework\Option\ArrayInterface
{
/**
* @var array
*/
protected $options = null;

/**
* To option array
*
* @return array
*/
public function toOptionArray()
{
if (null === $this->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;
}
}
167 changes: 167 additions & 0 deletions Plugin/Tax/Config/AroundGetShippingTaxClassPlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php
/**
* Copyright © 2016 FireGento e.V.
* See LICENSE.md bundled with this module for license details.
*/
namespace FireGento\MageSetup\Plugin\Tax\Config;

use Magento\Store\Model\Store;
use FireGento\MageSetup\Model\Config;

/**
* Class AroundGetShippingTaxClassPlugin
*
* @package FireGento\MageSetup\Plugin\Tax\Config
*/
class AroundGetShippingTaxClassPlugin
{
const CONFIG_PATH_DYNAMIC_SHIPPING_TAX_CLASS = 'tax/classes/dynamic_shipping_tax_class';

/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
private $scopeConfig;

/**
* @var \Magento\Checkout\Model\Cart
*/
private $cart;
/**
* @var \Magento\Customer\Model\Session
*/
private $customerSession;
/**
* @var \Magento\Customer\Model\ResourceModel\GroupRepository
*/
private $groupRepository;
/**
* @var \Magento\Tax\Model\Calculation\Proxy
*/
private $taxCalculation;

/**
* AroundGetShippingTaxClassPlugin constructor.
*
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Magento\Checkout\Model\Cart $cart
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Customer\Model\ResourceModel\GroupRepository $groupRepository
* @param \Magento\Tax\Model\Calculation\Proxy $taxCalculation
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Checkout\Model\Cart $cart,
\Magento\Customer\Model\Session $customerSession,
\Magento\Customer\Model\ResourceModel\GroupRepository $groupRepository,
\Magento\Tax\Model\Calculation\Proxy $taxCalculation
)
{
$this->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;
}
}
8 changes: 8 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,13 @@
</field>
</group>
</section>
<section id="tax">
<group id="classes">
<field id="dynamic_shipping_tax_class" translate="label" type="select" sortOrder="11" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Dynamic Shipping Tax Class</label>
<source_model>FireGento\MageSetup\Model\System\Config\Source\Tax\Dynamic</source_model>
</field>
</group>
</section>
</system>
</config>
4 changes: 4 additions & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@
<type name="Magento\CheckoutAgreements\Model\Agreement">
<plugin name="mageSetupFilterAgreementContent" type="FireGento\MageSetup\Plugin\Agreements\AfterGetContent" sortOrder="1"/>
</type>

<type name="Magento\Tax\Model\Config">
<plugin name="mageSetupDynamicShippingTaxClass" type="FireGento\MageSetup\Plugin\Tax\Config\AroundGetShippingTaxClassPlugin" sortOrder="1"/>
</type>
</config>

1 comment on commit 5257977

@drexlma
Copy link

@drexlma drexlma commented on 5257977 Dec 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

funktioniert :) jedoch ist der namespace der klasse Config falsch.

Please sign in to comment.