"""Client for interacting with VIES EU API.""" from marshmallow import ValidationError import zeep from payee.connectors import sentry from payee.constants.constants import VAT_NUMBER_REGEXPS, VIES_WS_ENDPOINT from payee.constants.error import ( ERROR_VAT_VIES_API_CHECK_FAILED, ERROR_VIES_API_ERROR, ERROR_VIES_API_UNREACHABLE, ) from payee.utils.exception import ViesApiException class Vies: """Class for interacting with Vies API.""" def clean(self, vat_number, vat_country_code=None): """Check input data with local rules and regex.""" try: vat_number = str(vat_number) except Exception: raise ValidationError(ERROR_VAT_VIES_API_CHECK_FAILED) vat_number = vat_number.replace(' ', '') if vat_country_code is not None: try: vat_country_code = str(vat_country_code) except Exception: raise ValidationError(ERROR_VAT_VIES_API_CHECK_FAILED) vat_country_code = vat_country_code.replace(' ', '') vat_country_code = vat_country_code.upper() # if no vat_country_code provided we try to extract it from vat_number else: try: vat_country_code = vat_number[:2] except Exception: raise ValidationError(ERROR_VAT_VIES_API_CHECK_FAILED) vat_country_code = vat_country_code.upper() if vat_country_code == 'GR': vat_country_code = 'EL' else: vat_number = vat_number[2:] if vat_country_code not in VAT_NUMBER_REGEXPS.keys(): raise ValidationError(ERROR_VAT_VIES_API_CHECK_FAILED) if len(vat_number) > 2: if vat_number[:2].upper() == vat_country_code: vat_number = vat_number[2:] # validate the vat number against VAT_NUMBER_REGEXPS if not VAT_NUMBER_REGEXPS[vat_country_code].match(vat_number): raise ValidationError(ERROR_VAT_VIES_API_CHECK_FAILED) return vat_number, vat_country_code def request(self, vat_number, vat_country_code=None, extended_info=True): """Check input data via request to Vies API.""" try: vat_number, vat_country_code = self.clean(vat_number, vat_country_code) except Exception as e: raise ValidationError(str(e)) # check VIES try: client = zeep.Client(wsdl=VIES_WS_ENDPOINT) except Exception as e: sentry.send_to_sentry( 'Vies VAT API Error!', str(e), 'error', ERROR_VIES_API_UNREACHABLE.format(error=str(e)), ) raise ViesApiException(ERROR_VIES_API_ERROR.format(error=str(e))) try: if extended_info is True: result = client.service.checkVatApprox(vat_country_code, vat_number) else: result = client.service.checkVat(vat_country_code, vat_number) except Exception as e: sentry.send_to_sentry( 'Vies VAT API Error!', str(e), 'error', ERROR_VIES_API_ERROR.format(error=str(e)), ) raise ViesApiException(ERROR_VIES_API_ERROR.format(error=str(e))) if not result['valid']: raise ValidationError(ERROR_VAT_VIES_API_CHECK_FAILED) return True