Bonjour,
Pour Prestashop 1.7, il faut surcharger les classes TaxRulesTaxManagerCore et CartCore.
1) Créer le fichier /override/classes/tax/TaxRulesTaxManager.php (ou créer un module dédié) et ajouter le code suivant :
class TaxRulesTaxManager extends TaxRulesTaxManagerCore { public function getTaxCalculator() { if ($this->address->id_country != Configuration::get('PS_COUNTRY_DEFAULT')) { $vatNumber = $this->address->vat_number; if (empty($vatNumber)) { $id_customer = $this->address->id_customer; $context = Context::getContext(); if (isset($context->cart)) { $billingAddress = new Address((int)$context->cart->id_address_invoice); if ($billingAddress->id_country != Configuration::get('PS_COUNTRY_DEFAULT')) { $vatNumber = $billingAddress->vat_number; } } } if (!empty($vatNumber) && preg_match('/^[A-Z]{2}[A-Z0-9]{2,14}$/', $vatNumber)) return new TaxCalculator(array()); } return parent::getTaxCalculator(); } }
La vérification du numéro de TVA intracommunautaire repose sur un REGEX sommaire.
Vérifier le numéro de TVA à l'aide du service VIES avec la fonction suivante (fonction à exécuter de façon asynchrone en raison du temps de latence élevé du service VIES) :
private function isVATValid($countryCode, $vatNumber) { $url = "http://ec.europa.eu/taxation_customs/vies/services/checkVatService"; $xmlRequest = '<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types"> <SOAP-ENV:Body> <ns1:checkVat> <ns1:countryCode>'.$countryCode.'</ns1:countryCode> <ns1:vatNumber>'.$vatNumber.'</ns1:vatNumber> </ns1:checkVat> </SOAP-ENV:Body> </SOAP-ENV:Envelope>'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); $response = curl_exec($ch); curl_close($ch); $xmlResponse = simplexml_load_string($response); $valid = (string)$xmlResponse->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children()->checkVatResponse->valid; return ($valid === 'true'); }
2) Créer le fichier /override/classes/Cart.php (ou créer un module dédié) et ajouter le code suivant :
class Cart extends CartCore { public function getOrderTotal($withTaxes = true, $type = Cart::BOTH, $products = null, $id_carrier = null, $use_cache = true, $keepOrderPrices = false) { $address_delivery = new Address((int)$this->id_address_delivery); if ($address_delivery->id_country != Configuration::get('PS_COUNTRY_DEFAULT')) { $vatNumber = $address_delivery->vat_number; if (empty($vatNumber)) { $address_invoice = new Address((int)$this->id_address_invoice); if ($address_invoice->id_country != Configuration::get('PS_COUNTRY_DEFAULT')) { $vatNumber = $address_invoice->vat_number; } } // Ajouter une vérification supplémentaire avec isVATValid() if (!empty($vatNumber) && preg_match('/^[A-Z]{2}[A-Z0-9]{2,14}$/', $vatNumber)) { $withTaxes = false; } } return parent::getOrderTotal($withTaxes, $type, $products, $id_carrier, $use_cache, $keepOrderPrices); } }