Jump to content
MarcoPLY

[SOLVED]LoginRegister add validation for VAT Number

Recommended Posts

Hi, 
I need to check the VAT number before the user make a registration. I start from here https://github.com/herdani/vat-validation, and this work well. But now I have to integrate this with the LoginRegister module, I'm not sure who do it, at moment I try to make the hook in this way:

wire()->addHookAfter('LoginRegister::processRegisterForm', function ($event) {
	  $form = $event->arguments[0];

		$company = wire('input')->post->register_Iam; // check if you are a person or a company
			if ($company == '2') {

			// Get country code
			$options = wire('fieldtypes')->get('FieldtypeOptions')->getOptions(wire('fields')->get('shipping_countrycode'));
			foreach ($options as $value) {
					if(wire('input')->post->register_shipping_countrycode == $value->id) {
							$country_title = $value->title;
							$countryCode = substr($country_title, 0, 2);
					}
			}
			// Get VAT number
			$vatNumber = wire('input')->post->register_invoice_VAT;

			$check = new WireFileTools();
      		$check->include('vatValidation.class.php');
			$vatValidation = new vatValidation( array('debug' => false));
			$vatValidation->check($countryCode, $vatNumber);

			if ($vatValidation->isValid()) {
				return true;
			} else {
				$vatError = 'this VAT N° does not exist';
 				$vatNumber->error($vatError);
			}
		}
});

I'm not sure but I think that everything works well until validation. How I can add the verification system?
I feel like one of the problem is adding the vatValidation.class.php file in the hook. But I can't debug well this. I try to follow this post.
Also I read the problem could be a namespace in the vatValidation.class file. But also, I'm not sure.  

vatValidation.class.php

UPDATE

I try also to use this

				$company = wire('input')->post->register_Iam;
				if ($company == '2'){
					// Get country code
					$options = wire('fieldtypes')->get('FieldtypeOptions')->getOptions(wire('fields')->get('shipping_countrycode'));
					foreach ($options as $value) {
							if(wire('input')->post->register_shipping_countrycode == $value->id) {
									$country_title = $value->title;
									$countryCode = substr($country_title, 0, 2);
							}
					}
					// Get VAT number
					$vatNumber = wire('input')->post->register_invoice_VAT;

					function viesCheckVAT($countryCode, $vatNumber, $timeout = 30) {
							$response = array ();
							$pattern = '/<(%s).*?>([\s\S]*)<\/\1/';
							$keys = array (
											'countryCode',
											'vatNumber',
											'requestDate',
											'valid',
											'name',
											'address'
							);

							$content = "<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
									<s11:Body>
										<tns1:checkVat xmlns:tns1='urn:ec.europa.eu:taxud:vies:services:checkVat:types'>
											<tns1:countryCode>%s</tns1:countryCode>
											<tns1:vatNumber>%s</tns1:vatNumber>
										</tns1:checkVat>
									</s11:Body>
								</s11:Envelope>";

							$opts = array (
											'http' => array (
															'method' => 'POST',
															'header' => "Content-Type: text/xml; charset=utf-8; SOAPAction: checkVatService",
															'content' => sprintf ( $content, $countryCode, $vatNumber ),
															'timeout' => $timeout
											)
							);

							$ctx = stream_context_create ( $opts );
							$result = file_get_contents ( 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService', false, $ctx );

							if (preg_match ( sprintf ( $pattern, 'checkVatResponse' ), $result, $matches )) {
									foreach ( $keys as $key )
											preg_match ( sprintf ( $pattern, $key ), $matches [2], $value ) && $response [$key] = $value [2];
							}
							return $response;
					}

					$arr = viesCheckVAT($countryCode, $vatNumber);

					if ($arr[valid] == fasle) {
						...
					}

				}

This probably are better, but I'm not able to integrate with the validation of the module.

ONE SOLUTION

In the end I failed to make the hook as I wanted. So I thought I'd check the VAT before the module registered the user. Ok maybe it's not the best solution but it works.

So, with the help of one person, we started from the PHP function I posted above, changing it this way: We sent a request via Ajax, this is activated when data is entered the input, this call via curl and returns a value that, following the logic in this case with a nice callback, enables or disables the send button 🙂 

<?php
  if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['task'] ) && $_POST['task']=='check' ){
  	ob_clean();

    $result=null;

    function curl( $url=NULL, $options=NULL, $headers=false ){
      /* Initialise curl request object */
      $curl=curl_init();
      /* Define standard options */
      curl_setopt( $curl, CURLOPT_URL,trim( $url ) );
      curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
      curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
      curl_setopt( $curl, CURLOPT_FAILONERROR, true );
      curl_setopt( $curl, CURLOPT_HEADER, false );
      curl_setopt( $curl, CURLINFO_HEADER_OUT, false );
      curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
      curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
      curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 20 );
      curl_setopt( $curl, CURLOPT_TIMEOUT, 60 );
      curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' );
      curl_setopt( $curl, CURLOPT_MAXREDIRS, 10 );
      curl_setopt( $curl, CURLOPT_ENCODING, '' );

      /* Assign runtime parameters as options */
      if( isset( $options ) && is_array( $options ) ){
        foreach( $options as $param => $value ) curl_setopt( $curl, $param, $value );
      }

      if( $headers && is_array( $headers ) ){
        curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers );
      }

      /* Execute the request and store responses */
      $res=(object)array(
        'response'  =>  curl_exec( $curl ),
        'info'      =>  (object)curl_getinfo( $curl ),
        'errors'    =>  curl_error( $curl )
      );
        curl_close( $curl );
        return $res;
      }

      function checkvat( $code, $vatnumber, $timeout=30 ){
        $url='http://ec.europa.eu/taxation_customs/vies/services/checkVatService';

        $content = "<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
          <s11:Body>
            <tns1:checkVat xmlns:tns1='urn:ec.europa.eu:taxud:vies:services:checkVat:types'>
              <tns1:countryCode>%s</tns1:countryCode>
              <tns1:vatNumber>%s</tns1:vatNumber>
            </tns1:checkVat>
          </s11:Body>
        </s11:Envelope>";

        $headers=array(
          'Content-Type'  =>  'text/xml; charset=utf-8',
          'SOAPAction'    =>  'checkVatService'
        );
        $options=array(
          CURLOPT_POST        =>  true,
          CURLOPT_POSTFIELDS  =>  sprintf ( $content, $code, $vatnumber )
        );
      return curl( $url, $options, $headers );
    }

    $code=$_POST['code'];
    $vatnumber=$_POST['vat'];

    /* check the VAT number etc */
    $obj=checkvat( $code, $vatnumber );

    /* if we received a valid response, process it */
    if( $obj->info->http_code==200 ){
    	$dom=new DOMDocument;
      $dom->loadXML( $obj->response );

      $reqdate=$dom->getElementsByTagName('requestDate')->item(0)->nodeValue;
      $valid=$dom->getElementsByTagName('valid')->item(0)->nodeValue;
      $address=$dom->getElementsByTagName('address')->item(0)->nodeValue;

	  if ($valid == "true") {
		$result = "<p style='background-color: #fff;width: 30%;color:green;position: absolute;'>Valid Number</p>";
	  } else {
	    $result = "<p style='background-color: #fff;width: 30%;color:red;position: absolute;'>Not Valid Number</p>";
	  }
    }
    exit( $result );
  }
?>
<script>
	const ajax=function( url, params, callback ){
    let xhr=new XMLHttpRequest();
    xhr.onload=function(){
      if( this.status==200 && this.readyState==4 )callback( this.response )
    };
    xhr.open( 'POST', url, true );
    xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
    xhr.send( buildparams( params ) );
  };

  const buildparams=function(p){/* construct payload/querystring from object */
    if( p && typeof( p )==='object' ){
      p=Object.keys( p ).map(function( k ){
        return typeof( p[ k ] )=='object' ? buildparams( p[ k ] ) : [ encodeURIComponent( k ), encodeURIComponent( p[ k ] ) ].join('=')
      }).join('&');
    }
    return p;
  };

  document.addEventListener('DOMContentLoaded', ()=>{
    let form = document.getElementById('LoginRegisterForm');
      form.register_invoice_IVA_VAT.addEventListener('keyup', e=>{
        let url=location.href;
        let params={
          'task':'check',
          'vat': form.register_invoice_IVA_VAT.value,
          'code':'IT' /*need to hook the select filed because now return the ID number*/
        };
        let callback=function(r){
		let vatF = document.getElementById('register_invoice_IVA_VAT');
		var thisreturn = r.includes("Not");
		var divNew = document.createElement("div");
		divNew.innerHTML = r;
		if (thisreturn == false) {
			vatF.classList.add('success');
			vatF.classList.remove('error');
			document.getElementById("register_submit").disabled = false;
			document.getElementById('wrap_register_invoice_IVA_VAT').appendChild(divNew);
		} else {
			vatF.classList.add('error');
			vatF.classList.remove('success');
			document.getElementById("register_submit").disabled = true;
			document.getElementById('wrap_register_invoice_IVA_VAT').appendChild(divNew);
		}
      }
     ajax.call( this, url, params, callback );
   })
});
</script>

So, I didn't make the hard coding part to be complete honest I ask in stackoverflow here, but anyway I want also add this post here if anyone in this form needed it, it can be a starting point. (Maybe could be a interesting features for the new Padloper or some ecosystm module @kongondo)

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...