I am adding tax programmatically on checkout using this code:
class Tax extends MagentoTaxModelSalesTotalQuoteTax
{
/**
* Class constructor
*
* @param MagentoTaxModelConfig $taxConfig
* @param MagentoTaxApiTaxCalculationInterface $taxCalculationService
* @param MagentoTaxApiDataQuoteDetailsInterfaceFactory $quoteDetailsDataObjectFactory
* @param MagentoTaxApiDataQuoteDetailsItemInterfaceFactory $quoteDetailsItemDataObjectFactory
* @param MagentoTaxApiDataTaxClassKeyInterfaceFactory $taxClassKeyDataObjectFactory
* @param CustomerAddressFactory $customerAddressFactory
* @param CustomerAddressRegionFactory $customerAddressRegionFactory
* @param MagentoTaxHelperData $taxData
*/
public function __construct(
MagentoTaxModelConfig $taxConfig,
MagentoTaxApiTaxCalculationInterface $taxCalculationService,
MagentoTaxApiDataQuoteDetailsInterfaceFactory $quoteDetailsDataObjectFactory,
MagentoTaxApiDataQuoteDetailsItemInterfaceFactory $quoteDetailsItemDataObjectFactory,
MagentoTaxApiDataTaxClassKeyInterfaceFactory $taxClassKeyDataObjectFactory,
CustomerAddressFactory $customerAddressFactory,
CustomerAddressRegionFactory $customerAddressRegionFactory,
MagentoTaxModelCalculation $taxCalculation,
MagentoTaxHelperData $taxData,
MagentoCustomerModelSession $session,
MagentoCustomerModelGroup $group
) {
$this->setCode('tax');
$this->taxCalculation = $taxCalculation;
$this->session = $session;
$this->group = $group;
parent::__construct(
$taxConfig,
$taxCalculationService,
$quoteDetailsDataObjectFactory,
$quoteDetailsItemDataObjectFactory,
$taxClassKeyDataObjectFactory,
$customerAddressFactory,
$customerAddressRegionFactory,
$taxData
);
}
/**
* Custom Collect tax totals for quote address
*
* @param Quote $quote
* @param ShippingAssignmentInterface $shippingAssignment
* @param AddressTotal $total
* @return $this
*/
public function collect(
MagentoQuoteModelQuote $quote,
MagentoQuoteApiDataShippingAssignmentInterface $shippingAssignment,
MagentoQuoteModelQuoteAddressTotal $total
) {
parent::collect($quote, $shippingAssignment, $total);
$taxamount = 0;
$customerSession = $this->session;
$customerGroup = $this->group;
$customerGroupId = $customerSession->getCustomer()->getGroupId();
$collection = $customerGroup->load($customerGroupId);
$customerGroup = $collection->getCustomerGroupCode();
$shippingAddress = $quote->getShippingAddress();
$shippingMethod = $shippingAddress->getShippingMethod();
if($shippingMethod == 'shqpickup1_collect'){
foreach($quote->getAllVisibleItems() as $item) {
// Tax Calculation
$productTaxClassId = $item->getTaxClassId();
$request = new MagentoFrameworkDataObject(
[
'country_id' => 'US',
'region_id' =>'43',
'postcode' => '10001',
'customer_class_id' => '3',
'product_class_id' => $productTaxClassId
]
);
// Calculate tax
$taxInfo = $this->taxCalculation->getResource()->getRateInfo($request);
// Classify different taxes
if (count($taxInfo['process']) > 0) {
foreach ($taxInfo['process'][0]['rates'] as $key => $rate) {
$itemPrice = $item->getQty() * $item->getPrice();
if($item->getDiscountAmount() > 0){
$itemPrice = ($item->getQty() * $item->getPrice())-$item->getDiscountAmount();
}
$taxamount += ($itemPrice * $rate['percent']) / 100;
}
}
}
// echo 'Tax amount: '.$taxamount;
if($customerSession->isLoggedIn()){
// Tax Exempt Customer
if($customerGroup != 'Tax Exempt Customer'){
$total->setTaxAmount($taxamount);
$total->setBaseTaxAmount($taxamount);
$total->setTotalAmount($this->getCode(),$taxamount);
$total->setBaseTotalAmount($this->getCode(),$taxamount);
}
}else{
$total->setTaxAmount($taxamount);
$total->setBaseTaxAmount($taxamount);
$total->setTotalAmount($this->getCode(),$taxamount);
$total->setBaseTotalAmount($this->getCode(),$taxamount);
}
}
return $this;
}
}
And this:
class UpdateTax
{
/**
* @var MagentoCheckoutModelSession
*/
protected $_checkoutSession;
const AMOUNT_SUBTOTAL = 'subtotal';
public function __construct(
MagentoCheckoutModelSession $checkoutSession,
MagentoTaxModelCalculation $taxCalculation,
MagentoCustomerModelSession $session,
MagentoCustomerModelGroup $group
) {
$this->_checkoutSession = $checkoutSession;
$this->taxCalculation = $taxCalculation;
$this->session = $session;
$this->group = $group;
}
public function afterGetAmounts($cart,$result)
{
$quote = $this->_checkoutSession->getQuote();
$paymentMethod = $quote->getPayment()->getMethod();
$paypalMehodList = ['payflowpro','payflow_link','payflow_advanced','braintree_paypal','paypal_express_bml','payflow_express_bml','payflow_express','paypal_express'];
$taxamount = 0;
$customerSession = $this->session;
$customerGroup = $this->group;
$customerGroupId = $customerSession->getCustomer()->getGroupId();
$collection = $customerGroup->load($customerGroupId);
$customerGroup = $collection->getCustomerGroupCode();
$shippingAddress = $quote->getShippingAddress();
$shippingMethod = $shippingAddress->getShippingMethod();
if($shippingMethod == 'shqpickup1_collect'){
foreach($quote->getAllVisibleItems() as $item) {
// Tax Calculation
$productTaxClassId = $item->getTaxClassId();
$request = new MagentoFrameworkDataObject(
[
'country_id' => 'US',
'region_id' =>'43',
'postcode' => '10001',
'customer_class_id' => '3',
'product_class_id' => $productTaxClassId
]
);
// Calculate tax
$taxInfo = $this->taxCalculation->getResource()->getRateInfo($request);
// Classify different taxes
if (count($taxInfo['process']) > 0) {
foreach ($taxInfo['process'][0]['rates'] as $key => $rate) {
$itemPrice = $item->getQty() * $item->getPrice();
if($item->getDiscountAmount() > 0){
$itemPrice = ($item->getQty() * $item->getPrice())-$item->getDiscountAmount();
}
$taxamount += ($itemPrice * $rate['percent']) / 100;
}
}
}
// to check the paypal payment method
if(in_array($paymentMethod,$paypalMehodList)){
$result[self::AMOUNT_SUBTOTAL] = $result[self::AMOUNT_SUBTOTAL] + $taxamount;
}
}
return $result;
}
}
It works fine with all payment methods except Paypal. Paypal adds the tax twice to the total amount.
Checkout: