Hello Michel, Marc
Have any of you have a working Vat-controle for Belgium vat numbers ? I want to check if new customers are having a correct vat number and maybe the option of filling in the customer data from online data.
Belgium VAT-Controle function
- Marc Venken
- Posts: 727
- Joined: Tue Jun 14, 2016 7:51 am
Belgium VAT-Controle function
Marc Venken
Using: FWH 20.08 with Harbour
Using: FWH 20.08 with Harbour
- Silvio.Falconi
- Posts: 4956
- Joined: Thu Oct 18, 2012 7:17 pm
Re: Belgium VAT-Controle function
You could always use our Italian control if the customer VAT number is created in the same way also in Belgium
I fiund this
https://vatcalculator.eu/belgium-vat-calculator/
but you perhaps mean another vat number
I found VAT number format: BE 0999.999.999 (10 digits)
https://github.com/DragonBe/vies/issues/76
there is a php source code
https://github.com/DragonBe/vies/blob/m ... sponse.php
I fiund this
https://vatcalculator.eu/belgium-vat-calculator/
but you perhaps mean another vat number
I found VAT number format: BE 0999.999.999 (10 digits)
https://github.com/DragonBe/vies/issues/76
there is a php source code
https://github.com/DragonBe/vies/blob/m ... sponse.php
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
Re: Belgium VAT-Controle function
Hi Marc,
This is the function I have made to check a Belgian VAT-number.
The picture of the VAT-number = "BE0999.999.999"
The code is :Good luck.
This is the function I have made to check a Belgian VAT-number.
The picture of the VAT-number = "BE0999.999.999"
The code is :
Code: Select all
FUNCTION Contr_BTW(nBTWNUM,nLAND,nDlg,nONDNUM,nBTWLIST) // Controle Belgisch BTW-nummer
LOCAL OldPar := ALIAS()
LOCAL TN1 := 0
LOCAL TN2 := 0
LOCAL cTel := 0
LOCAL cRet := .T.
IF ALLTRIM(nLAND) = "B" .AND. !EMPTY(&nBTWNUM) .AND. ALLTRIM(&nBTWNUM) <> ". ." .AND. LEFT(UPPER(&nBTWNUM),2) = "BE"
&nBTWNUM := LEFT(ALLTRIM(&nBTWNUM),14)
FOR x = 4 TO LEN(ALLTRIM(SUBSTR(&nBTWNUM,4,11)))
IF (SUBSTR(ALLTRIM(&nBTWNUM),x,1) < "0" .OR. SUBSTR(ALLTRIM(&nBTWNUM),x,1) > "9") .AND. ((x <> 7 .AND. x <> 11) .OR. ((x = 7 .OR. x = 11) .AND. SUBSTR(ALLTRIM(&nBTWNUM),x,1) <> "."))
cTel++
ENDIF
NEXT
IF cTel = 0
IF LEN(ALLTRIM(&nBTWNUM)) = 12
&nBTWNUM := LEFT(SUBSTR(ALLTRIM(&nBTWNUM),1,6) + "." + SUBSTR(ALLTRIM(&nBTWNUM),7,3) + "." + RIGHT(ALLTRIM(&nBTWNUM),10,3) + SPACE(20),20)
nDlg:Update()
ENDIF
TN1 := VAL(SUBSTR(ALLTRIM(&nBTWNUM),3,4) + SUBSTR(ALLTRIM(&nBTWNUM),8,3) + SUBSTR(ALLTRIM(&nBTWNUM),12,1))
TN2 := (( TN1 / 97) - INT(TN1 / 97)) * 97
IF !(cTel = 0 .AND. INT(VAL(SUBSTR(ALLTRIM(&nBTWNUM),13,2))) = 97 - INT(TN2 + 0.5))
cRet := .F.
ENDIF
ELSEIF LEFT(UPPER(&nBTWNUM),2) = "BE"
cRet := .F.
ENDIF
IF cRet
IF LEFT(UPPER(ALLTRIM(&nBTWNUM)),2) = "BE"
IF !EMPTY(nONDNUM) .AND. (EMPTY(&nONDNUM) .OR. ALLTRIM(&nONDNUM) = ". .")
&nONDNUM := RIGHT(ALLTRIM(&nBTWNUM),12)
IF !EMPTY(nBTWLIST) .AND. !EMPTY(&nBTWNUM)
&nBTWLIST := .T.
ENDIF
ENDIF
nDlg:Update()
ENDIF
ENDIF
IF LEN(ALLTRIM(&nBTWNUM)) < 14
&nBTWNUM := LEFT(ALLTRIM(&nBTWNUM) + SPACE(14),14)
cRet := .F.
ENDIF
IF !cRet
MsgAlert("Dit Belgisch BTW-nummer is niet correct !!!","Opgelet")
ENDIF
ENDIF
RETURN(cRet)
Regards,
Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 21.01 - Harbour 3.2.0 (October 2020) - xHarbour Builder (January 2020) - Bcc7
Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 21.01 - Harbour 3.2.0 (October 2020) - xHarbour Builder (January 2020) - Bcc7
- Marc Venken
- Posts: 727
- Joined: Tue Jun 14, 2016 7:51 am
Re: Belgium VAT-Controle function
I have seen this code working I believe (don't know where I got it)
Now it's not ok anymore
Now it's not ok anymore
Code: Select all
#include "fivewin.ch"
#if ! defined( DEFAULT_MAX_RECORDS )
#define DEFAULT_MAX_RECORDS 20000
#endif
Static cDoc , cHttp
Function Main()
TRY
cDoc := CreateObject( "MSXML2.DOMDocument" )
CATCH
Alert("Error object MSXML2.DOMDocument : " + Ole2TxtError())
return NIL
END
TRY
cHttp := CreateObject( "MSXML2.XMLHTTP" )
CATCH
Alert("Error object MSXML2.XMLHTTP : " + Ole2TxtError())
END
checkVies( "BE", "0452109872" )
Return nil
//=========================================================================================
Function checkVies(cCountry, cVatNumber )
Local cResponse := " " ,hVar
Local cRequestXML := ""
local aData:={}
DEFAULT cCountry := "BE"
DEFAULT cVatNumber := "0452109872"
editvars cVatnumber
cRequestXML := [<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" ] +;
[xmlns:tns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types" ] +;
[xmlns:impl="urn:ec.europa.eu:taxud:vies:services:checkVat"> ] +;
[<soap:Header> ]+;
[</soap:Header> ]+;
[<soap:Body> ]+;
[<tns1:checkVat xmlns:tns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types" ]+;
[xmlns="urn:ec.europa.eu:taxud:vies:services:checkVat:types"> ]+;
[<tns1:countryCode>] + cCountry + [</tns1:countryCode> ] +;
[<tns1:vatNumber>] + cVatNumber + [</tns1:vatNumber> ] +;
[</tns1:checkVat> ]+;
[</soap:Body> ]+;
[</soap:Envelope> ]
//
//cHttp:Open( "POST","http://ec.europa.eu/taxation_customs/vies/services/checkVatService", .t.)
// Wait...
cHttp:Open( "POST","http://ec.europa.eu/taxation_customs/vies/services/checkVatService", .F.)
cHttp:SetRequestHeader( "Content-Type" , "application/x-www-form-urlencoded" )
cHttp:setRequestHeader('User-Agent', 'node-soap')
cHttp:setRequestHeader('Accept' , 'text/html,application/xhtml+xml,application/xml,text/xml;q=0.9,*/*;q=0.8')
cHttp:setRequestHeader('Accept-Encoding', 'none')
cHttp:setRequestHeader('Accept-Charset', 'utf-8')
//cHttp:setRequestHeader('Connection', 'close')
//cHttp:setRequestHeader('Host', 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService')
cHttp:setRequestHeader('SOAPAction', 'urn:ec.europa.eu:taxud:vies:services:checkVat/checkVat')
//MsgGet( 'Wait',,@cRequestXML)
//cDoc:LoadXML( cRequestXML )
//lXmlHttp.send(lXmlDoc);
cHttp:send(cRequestXML)
//cHttp:send(cDOc:xml )
//If cHttp:status == 200
// ? cResponse
cResponse := cHttp:responseText
? cResponse
aadd(aData,BETWEENTAGSARRAY("name","/name",cResponse))
aadd(aData,BETWEENTAGSARRAY("address","/address",cResponse))
//xbrowser( BETWEENTAGSARRAY("faultstring","/faultstring",cResponse) )
xbrowser( aData )
//endif
RETURN NIL
FUNCTION BETWEENTAGSARRAY( cStartTag, cEndTag, cInputString, lIncludeTags )
LOCAL nStartPoint, nEndPoint
LOCAL nRecords := 00, nFetchLength := 00, aFoundText := Array( DEFAULT_MAX_RECORDS )
LOCAL cMDML
LOCAL cInputStringUpper := Upper( cInputString )
LOCAL cStartTagUpper := Upper( cStartTag )
LOCAL cEndTagUpper := Upper( cEndTag )
hb_Default( @lIncludeTags, .F. )
DO WHILE .T.
// Find the starting point of the starting tag.
nStartPoint := At( cStartTagUpper, SubStr( cInputStringUpper, 01 ) )
IF nStartPoint > 00
// Adjust starting point to end of starting tag
nStartPoint += Len( cStartTagUpper )
// If the first tag is found strip off string up to and including the starting tag itself
cInputStringUpper := SubStr( cInputStringUpper, nStartPoint )
cInputString := SubStr( cInputString, nStartPoint )
// Find the starting point of the second tag, beginning from end of first tag.
nEndPoint := At( cEndTagUpper, cInputStringUpper )
IF nEndPoint > 00
// If the second tag is found calculate its position from start of string.
nFetchLength := nEndPoint - 1
IF lIncludeTags
cMDML := cStartTag + LTrim( SubStr( cInputString, 01, nFetchLength ) ) + cEndTag
ELSE
cMDML := LTrim( SubStr( cInputString, 01, nFetchLength ) )
ENDIF
IF ++nRecords <= DEFAULT_MAX_RECORDS
aFoundText[ nRecords ] := cMDML
ELSE
// IF we get here it is gonna be oh so slow.
AAdd( aFoundText, cMDML )
ENDIF
// clip off the front of the string then loop to find the next
cInputStringUpper := SubStr( cInputStringUpper, nFetchLength + 01 )
cInputString := SubStr( cInputString, nFetchLength + 01 )
ELSE
EXIT
ENDIF
ELSE
EXIT
ENDIF
ENDDO
IF nRecords < DEFAULT_MAX_RECORDS
aFoundText := ASize( aFoundText, nRecords )
ENDIF
RETURN ( aFoundText )
Marc Venken
Using: FWH 20.08 with Harbour
Using: FWH 20.08 with Harbour
Re: Belgium VAT-Controle function
Marc,
Do you know the principle of checking a Belgian VAT-number?
A Belgian VAT-number looks like BE0574.774.488.
Take "BE0" at the start away. You keep 574.774.488.
Get rid of the points. You keep 574774488.
Take the first 7 digits. You keep 5747744.
Divide this result by 97. The result is 59255.0927835.
You keep the decimals : 0.0927835.
Multiply this by 97 and round it with 0 decimals.
The result is 9.
Substract 9 from 97 and this results into 88.
IF 88 is equal to the last 2 figures of you VAT-number, the Belgian VAT-number is correct.
This is what my function does.
Do you know the principle of checking a Belgian VAT-number?
A Belgian VAT-number looks like BE0574.774.488.
Take "BE0" at the start away. You keep 574.774.488.
Get rid of the points. You keep 574774488.
Take the first 7 digits. You keep 5747744.
Divide this result by 97. The result is 59255.0927835.
You keep the decimals : 0.0927835.
Multiply this by 97 and round it with 0 decimals.
The result is 9.
Substract 9 from 97 and this results into 88.
IF 88 is equal to the last 2 figures of you VAT-number, the Belgian VAT-number is correct.
This is what my function does.
Regards,
Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 21.01 - Harbour 3.2.0 (October 2020) - xHarbour Builder (January 2020) - Bcc7
Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 21.01 - Harbour 3.2.0 (October 2020) - xHarbour Builder (January 2020) - Bcc7
- nageswaragunupudi
- Posts: 8017
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Contact:
Re: Belgium VAT-Controle function
I tried to implement the above logic in this function:driessen wrote:Marc,
Do you know the principle of checking a Belgian VAT-number?
A Belgian VAT-number looks like BE0574.774.488.
Take "BE0" at the start away. You keep 574.774.488.
Get rid of the points. You keep 574774488.
Take the first 7 digits. You keep 5747744.
Divide this result by 97. The result is 59255.0927835.
You keep the decimals : 0.0927835.
Multiply this by 97 and round it with 0 decimals.
The result is 9.
Substract 9 from 97 and this results into 88.
IF 88 is equal to the last 2 figures of you VAT-number, the Belgian VAT-number is correct.
This is what my function does.
Code: Select all
function BelgiumVat( cVat )
local lValid := .f.
if Left( cVat, 3 ) == "BE0" .and. Len( cVat ) == 14
cVat := SubStr( cVat, 4 )
if SubStr( cVat, 4, 1 ) == "." .and. SubStr( cVat, 8, 1 ) == "."
cVat := StrTran( cVat, ".", "" )
if cVat == Str( Val( cVat ), 9 )
if 97 - Val( Left( cVat, 7 ) ) % 97 == Val( Right( cVat, 2 ) )
lValid := .t.
endif
endif
endif
endif
return lValid
Even this check is valid, there is no guarantee that the number does exist. Checking with the Government's website is the final check.
Regards
G. N. Rao.
Hyderabad, India
G. N. Rao.
Hyderabad, India