Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Vat.php
Go to the documentation of this file.
1 <?php
6 namespace Magento\Customer\Model;
7 
12 use Magento\Store\Model\Information as StoreInformation;
13 use Psr\Log\LoggerInterface as PsrLogger;
15 
19 class Vat
20 {
24  const XML_PATH_CUSTOMER_VIV_INTRA_UNION_GROUP = 'customer/create_account/viv_intra_union_group';
25 
26  const XML_PATH_CUSTOMER_VIV_DOMESTIC_GROUP = 'customer/create_account/viv_domestic_group';
27 
28  const XML_PATH_CUSTOMER_VIV_INVALID_GROUP = 'customer/create_account/viv_invalid_group';
29 
30  const XML_PATH_CUSTOMER_VIV_ERROR_GROUP = 'customer/create_account/viv_error_group';
31 
35  const VAT_CLASS_DOMESTIC = 'domestic';
36 
37  const VAT_CLASS_INTRA_UNION = 'intra_union';
38 
39  const VAT_CLASS_INVALID = 'invalid';
40 
41  const VAT_CLASS_ERROR = 'error';
42 
47  const VAT_VALIDATION_WSDL_URL = 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService?wsdl';
48 
52  const XML_PATH_CUSTOMER_GROUP_AUTO_ASSIGN = 'customer/create_account/auto_group_assign';
53 
57  const XML_PATH_EU_COUNTRIES_LIST = 'general/country/eu_countries';
58 
62  protected $scopeConfig;
63 
67  protected $logger;
68 
73  public function __construct(
75  PsrLogger $logger
76  ) {
77  $this->scopeConfig = $scopeConfig;
78  $this->logger = $logger;
79  }
80 
87  public function getMerchantCountryCode($store = null)
88  {
89  return (string)$this->scopeConfig->getValue(
90  StoreInformation::XML_PATH_STORE_INFO_COUNTRY_CODE,
91  ScopeInterface::SCOPE_STORE,
92  $store
93  );
94  }
95 
102  public function getMerchantVatNumber($store = null)
103  {
104  return (string)$this->scopeConfig->getValue(
105  StoreInformation::XML_PATH_STORE_INFO_VAT_NUMBER,
106  ScopeInterface::SCOPE_STORE,
107  $store
108  );
109  }
110 
119  public function getCustomerGroupIdBasedOnVatNumber($customerCountryCode, $vatValidationResult, $store = null)
120  {
121  $groupId = null;
122 
123  $isAutoGroupAssign = $this->scopeConfig->isSetFlag(
124  self::XML_PATH_CUSTOMER_GROUP_AUTO_ASSIGN,
125  ScopeInterface::SCOPE_STORE,
126  $store
127  );
128  if (!$isAutoGroupAssign) {
129  return $groupId;
130  }
131 
132  $vatClass = $this->getCustomerVatClass($customerCountryCode, $vatValidationResult, $store);
133 
134  $vatClassToGroupXmlPathMap = [
135  self::VAT_CLASS_DOMESTIC => self::XML_PATH_CUSTOMER_VIV_DOMESTIC_GROUP,
136  self::VAT_CLASS_INTRA_UNION => self::XML_PATH_CUSTOMER_VIV_INTRA_UNION_GROUP,
137  self::VAT_CLASS_INVALID => self::XML_PATH_CUSTOMER_VIV_INVALID_GROUP,
138  self::VAT_CLASS_ERROR => self::XML_PATH_CUSTOMER_VIV_ERROR_GROUP,
139  ];
140 
141  if (isset($vatClassToGroupXmlPathMap[$vatClass])) {
142  $groupId = (int)$this->scopeConfig->getValue(
143  $vatClassToGroupXmlPathMap[$vatClass],
144  ScopeInterface::SCOPE_STORE,
145  $store
146  );
147  }
148 
149  return $groupId;
150  }
151 
162  public function checkVatNumber($countryCode, $vatNumber, $requesterCountryCode = '', $requesterVatNumber = '')
163  {
164  // Default response
165  $gatewayResponse = new DataObject([
166  'is_valid' => false,
167  'request_date' => '',
168  'request_identifier' => '',
169  'request_success' => false,
170  'request_message' => __('Error during VAT Number verification.'),
171  ]);
172 
173  if (!extension_loaded('soap')) {
174  $this->logger->critical(new LocalizedException(__('PHP SOAP extension is required.')));
175  return $gatewayResponse;
176  }
177 
178  if (!$this->canCheckVatNumber($countryCode, $vatNumber, $requesterCountryCode, $requesterVatNumber)) {
179  return $gatewayResponse;
180  }
181 
182  try {
183  $soapClient = $this->createVatNumberValidationSoapClient();
184 
185  $requestParams = [];
186  $requestParams['countryCode'] = $countryCode;
187  $vatNumberSanitized = $this->isCountryInEU($countryCode)
188  ? str_replace([' ', '-', $countryCode], ['', '', ''], $vatNumber)
189  : str_replace([' ', '-'], ['', ''], $vatNumber);
190  $requestParams['vatNumber'] = $vatNumberSanitized;
191  $requestParams['requesterCountryCode'] = $requesterCountryCode;
192  $reqVatNumSanitized = $this->isCountryInEU($requesterCountryCode)
193  ? str_replace([' ', '-', $requesterCountryCode], ['', '', ''], $requesterVatNumber)
194  : str_replace([' ', '-'], ['', ''], $requesterVatNumber);
195  $requestParams['requesterVatNumber'] = $reqVatNumSanitized;
196  // Send request to service
197  $result = $soapClient->checkVatApprox($requestParams);
198 
199  $gatewayResponse->setIsValid((bool)$result->valid);
200  $gatewayResponse->setRequestDate((string)$result->requestDate);
201  $gatewayResponse->setRequestIdentifier((string)$result->requestIdentifier);
202  $gatewayResponse->setRequestSuccess(true);
203 
204  if ($gatewayResponse->getIsValid()) {
205  $gatewayResponse->setRequestMessage(__('VAT Number is valid.'));
206  } else {
207  $gatewayResponse->setRequestMessage(__('Please enter a valid VAT number.'));
208  }
209  } catch (\Exception $exception) {
210  $gatewayResponse->setIsValid(false);
211  $gatewayResponse->setRequestDate('');
212  $gatewayResponse->setRequestIdentifier('');
213  }
214 
215  return $gatewayResponse;
216  }
217 
224  protected function createVatNumberValidationSoapClient($trace = false)
225  {
226  return new \SoapClient(self::VAT_VALIDATION_WSDL_URL, ['trace' => $trace]);
227  }
228 
241  public function canCheckVatNumber($countryCode, $vatNumber, $requesterCountryCode, $requesterVatNumber)
242  {
243  return !(!is_string($countryCode)
244  || !is_string($vatNumber)
245  || !is_string($requesterCountryCode)
246  || !is_string($requesterVatNumber)
247  || empty($countryCode)
248  || !$this->isCountryInEU($countryCode)
249  || empty($vatNumber)
250  || empty($requesterCountryCode) && !empty($requesterVatNumber)
251  || !empty($requesterCountryCode) && empty($requesterVatNumber)
252  || !empty($requesterCountryCode) && !$this->isCountryInEU($requesterCountryCode)
253  );
254  }
255 
264  public function getCustomerVatClass($customerCountryCode, $vatValidationResult, $store = null)
265  {
266  $vatClass = null;
267 
268  $isVatNumberValid = $vatValidationResult->getIsValid();
269 
270  if (is_string($customerCountryCode)
271  && !empty($customerCountryCode)
272  && $customerCountryCode === $this->getMerchantCountryCode($store)
273  && $isVatNumberValid
274  ) {
275  $vatClass = self::VAT_CLASS_DOMESTIC;
276  } elseif ($isVatNumberValid) {
277  $vatClass = self::VAT_CLASS_INTRA_UNION;
278  } else {
279  $vatClass = self::VAT_CLASS_INVALID;
280  }
281 
282  if (!$vatValidationResult->getRequestSuccess()) {
283  $vatClass = self::VAT_CLASS_ERROR;
284  }
285 
286  return $vatClass;
287  }
288 
296  public function isCountryInEU($countryCode, $storeId = null)
297  {
298  $euCountries = explode(
299  ',',
300  $this->scopeConfig->getValue(self::XML_PATH_EU_COUNTRIES_LIST, ScopeInterface::SCOPE_STORE, $storeId)
301  );
302  return in_array($countryCode, $euCountries);
303  }
304 }
getCustomerVatClass($customerCountryCode, $vatValidationResult, $store=null)
Definition: Vat.php:264
createVatNumberValidationSoapClient($trace=false)
Definition: Vat.php:224
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
__construct(ScopeConfigInterface $scopeConfig, PsrLogger $logger)
Definition: Vat.php:73
canCheckVatNumber($countryCode, $vatNumber, $requesterCountryCode, $requesterVatNumber)
Definition: Vat.php:241
__()
Definition: __.php:13
const XML_PATH_CUSTOMER_VIV_DOMESTIC_GROUP
Definition: Vat.php:26
const VAT_VALIDATION_WSDL_URL
Definition: Vat.php:47
const VAT_CLASS_INTRA_UNION
Definition: Vat.php:37
const XML_PATH_CUSTOMER_VIV_INTRA_UNION_GROUP
Definition: Vat.php:24
const XML_PATH_CUSTOMER_VIV_ERROR_GROUP
Definition: Vat.php:30
const XML_PATH_CUSTOMER_VIV_INVALID_GROUP
Definition: Vat.php:28
const XML_PATH_CUSTOMER_GROUP_AUTO_ASSIGN
Definition: Vat.php:52
checkVatNumber($countryCode, $vatNumber, $requesterCountryCode='', $requesterVatNumber='')
Definition: Vat.php:162
getMerchantCountryCode($store=null)
Definition: Vat.php:87
getCustomerGroupIdBasedOnVatNumber($customerCountryCode, $vatValidationResult, $store=null)
Definition: Vat.php:119
isCountryInEU($countryCode, $storeId=null)
Definition: Vat.php:296
const XML_PATH_EU_COUNTRIES_LIST
Definition: Vat.php:57
getMerchantVatNumber($store=null)
Definition: Vat.php:102