282 lines
11 KiB
PHP
282 lines
11 KiB
PHP
<?php
|
|
require_once 'framework/common/curl.php';
|
|
|
|
class Metier_Partenaires_MTva
|
|
{
|
|
public $vatNumber = ''; // Numéro de TVA retourné
|
|
public $vatDefined = false; // Le numéro de TVA est il validé ?
|
|
public $errnum = 0; // Numéro de l'erreur en cas d'erreur
|
|
public $errmsg = ''; // Message de l'erreur en cas d'erreur
|
|
|
|
private $siren;
|
|
protected $iDb;
|
|
|
|
public function __construct($siren, $accesDist=true, $db = null)
|
|
{
|
|
$sirenIn = $siren*1;
|
|
if ( $sirenIn<000001000 ) {
|
|
$this->vatNumber = 'FR00000000000';
|
|
$this->vatDefined = false;
|
|
return false;
|
|
}
|
|
|
|
if ( $db === null ) {
|
|
$this->iDb = new Metier_Util_Db();
|
|
} else {
|
|
$this->iDb = $db;
|
|
}
|
|
|
|
$siren = str_pad($siren, 9, '0', STR_PAD_LEFT);
|
|
|
|
$this->siren = $siren;
|
|
$cleAlgo=$this->genereCleFr();
|
|
|
|
if ($cleAlgo<10) $cleAlgo='0'.$cleAlgo;
|
|
else $cleAlgo=''.$cleAlgo;
|
|
|
|
$tabRep=array();
|
|
if (!$this->valideSiren($siren) && substr($siren,0,4)<>'0000') {
|
|
$this->errnum=102;
|
|
$this->errmsg='Siren invalide';
|
|
return false;
|
|
}
|
|
|
|
$info = $this->iDb->select('sdv1.siren_tva', "LPAD(cle,2,0) AS cle, DATE_FORMAT(dateMod,'%Y%m%d') as DateMAJ", "siren=$siren", false, MYSQL_ASSOC);
|
|
$tab=$info[0];
|
|
if (count($tab)>0) {
|
|
if ( $tab['cle']<>NULL || ( $tab['cle']==NULL && $tab['DateMAJ']>=date('Ymd',mktime(0,0,0,date('m')-6,date('d'),date('Y'))) )) {
|
|
$cle=$tab['cle'];
|
|
if ($cle==NULL) { $attribue=false; $cle=$cleAlgo; }
|
|
else $attribue=true;
|
|
$this->vatNumber="FR$cle$siren";
|
|
$this->vatDefined=$attribue;
|
|
return true;
|
|
}
|
|
}
|
|
$cle=$cleAlgo;
|
|
$nbIndispo=0;
|
|
if ($accesDist) {
|
|
while(true) {
|
|
$postData=array( //'Lang'=>'FR',
|
|
'ms'=>'FR',
|
|
'iso'=>'FR',
|
|
'vat'=>$cle.$siren,
|
|
'BtnSubmitVat'=>'Verify');
|
|
/*$postData=array(
|
|
* 'Lang'=>'FR',
|
|
'VAT'=>$cle.$siren,
|
|
'ISO'=>'FR',
|
|
'MS'=>'FR'
|
|
);*/
|
|
$tdeb = microtime(true);
|
|
// $url='http://ec.europa.eu/taxation_customs/vies/cgi-bin/viesquer';
|
|
// $referer='http://ec.europa.eu/taxation_customs/vies/fr/vieshome.htm';
|
|
$url='http://ec.europa.eu/taxation_customs/vies/viesquer.do';
|
|
$referer='http://ec.europa.eu/taxation_customs/vies/';
|
|
|
|
$page=getUrl($url, '', $postData, $referer, false, 'ec.europa.eu', '', 15);
|
|
$duree = round(microtime(true)-$tdeb, 3);
|
|
if ($page['err_num']<>0) {
|
|
Metier_Util_Log::write('W', 'TVA Erreur CURL n°'. $page['err_num'] .', '. $page['err_msg'] ." sur le Siren $siren, numéro de TVA = FR $cle $siren. Durée = $duree s !", __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
$this->vatNumber="FR$cle$siren";
|
|
$this->vatDefined=false;
|
|
return true;
|
|
}
|
|
$code=$page['code'];// Code réponse Serveur
|
|
$body=$page['body'];
|
|
$header=$page['header'];
|
|
if (preg_match('/Yes, valid VAT number/i', $body)) {
|
|
$tabInsert=array('siren'=>$siren,'cle'=>$cle, 'duree'=>$duree);
|
|
$tabUpdate=array('cle'=>$cle, 'duree'=>$duree);
|
|
if (!$this->iDb->insert('sdv1.siren_tva', $tabInsert))
|
|
if (!$this->iDb->update('sdv1.siren_tva', $tabUpdate, "siren=$siren"))
|
|
Metier_Util_Log::write('W', "Siren $siren, numéro de TVA = FR $cle $siren, impossible de MAJ la clef ($duree s) - ERREUR MySql n°". mysql_errno() .' : '. mysql_error(), __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
//echo date ('Y/m/d - H:i:s') ." - Ligne $k/$nbk, N°TVA FR $cle $siren validé .".$eol;
|
|
Metier_Util_Log::write('I', "Siren $siren, numéro de TVA = FR $cle $siren ($duree s)", __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
$this->vatNumber="FR$cle$siren";
|
|
$this->vatDefined=true;
|
|
return true;
|
|
//return array('error'=>array('errnum'=>0, 'errmsg'=>''), 'result'=>array('siren'=>$siren, 'vatNumber'=>"FR$cle$siren", 'vatDefined'=>true));
|
|
} elseif (strpos($body, 'Service non disponible')>0 || strpos($body, 'ponse trop long.')>0) {
|
|
$nbIndispo++;
|
|
if ($nbIndispo<3) {
|
|
//echo date ('Y/m/d - H:i:s') .' - '.$eol;
|
|
Metier_Util_Log::write('I', "TVA Siren $siren, Service de l'état membre indisponible. Mise en sommeil...", __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
sleep(rand(1, 2));
|
|
$nbIndispo=0;
|
|
//echo date ('Y/m/d - H:i:s') .' - Reprise du Siren = '. $siren . $eol;
|
|
} else {
|
|
$tabInsert=array('siren'=>$siren,'cle'=>'NULL', 'duree'=>$duree);
|
|
$tabUpdate=array('cle'=>'NULL', 'duree'=>$duree);
|
|
if (!$this->iDb->insert('sdv1.siren_tva', $tabInsert))
|
|
if (!$this->iDb->update('sdv1.siren_tva', $tabUpdate, "siren=$siren"))
|
|
Metier_Util_Log::write('W', "Siren $siren, numéro de TVA = FR $cle $siren, impossible de MAJ la clef ($duree s) - ERREUR MySql n°". mysql_errno() .' : '. mysql_error(), __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
Metier_Util_Log::write('I', "Siren $siren, numéro de TVA = FR $cle $siren vérification non disponible ($duree s)", __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
$this->vatNumber="FR$cle$siren";
|
|
$this->vatDefined=false;
|
|
return true;
|
|
}
|
|
//echo date ('Y/m/d - H:i:s') .' - Temporisation n°'.$nbIndispo . $eol;
|
|
} else {
|
|
$tabInsert=array('siren'=>$siren,'cle'=>'NULL', 'duree'=>$duree);
|
|
$tabUpdate=array('cle'=>'NULL', 'duree'=>$duree);
|
|
if (!$this->iDb->insert('sdv1.siren_tva', $tabInsert))
|
|
if (!$this->iDb->update('sdv1.siren_tva', $tabUpdate, "siren=$siren"))
|
|
Metier_Util_Log::write('W', "Siren $siren, numéro de TVA = FR $cle $siren, impossible de MAJ la clef ($duree s) - ERREUR MySql n°". mysql_errno() .' : '. mysql_error(), __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
Metier_Util_Log::write('I', "Siren $siren, numéro de TVA = FR $cle $siren non attribué ($duree s)", __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
$this->vatNumber="FR$cle$siren";
|
|
$this->vatDefined=false;
|
|
return true;
|
|
}
|
|
}
|
|
} else {
|
|
$this->errnum=999;
|
|
$this->errmsg="Pas d'accès à la base TVA";
|
|
$this->vatNumber="FR$cle$siren";
|
|
$this->vatDefined=false;
|
|
return true;
|
|
}
|
|
Metier_Util_Log::write('W', "Erreur impossible (car l'algo ne devrait pas passer par ici) sur le Siren $siren, numéro de TVA = FR $cle $siren. Durée = $duree s. Cas impossible !", __LINE__, __FILE__, __FUNCTION__, __CLASS__);
|
|
return true;//array('error'=>array('errnum'=>800, 'errmsg'=>'Erreur SGBDR'), 'result'=>$tabRet);
|
|
}
|
|
|
|
/**
|
|
* Génère la clé du numéro de TVA pour le siren fournit
|
|
* (la validité du numéro de siren et son existance n'est pas effectué par cette méthode)
|
|
*
|
|
* @return number
|
|
* La clé du numéro de TVA
|
|
*/
|
|
private function genereCleFr()
|
|
{
|
|
// Position du chiffre SIREN (1 à 9)
|
|
$tabFirst = array(
|
|
array( 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
array(62,47,94,89,40,06,22,43,16),
|
|
array(14,81,78,68,67,96,31,73,19),
|
|
array(63,18,62,47,94,89,40,06,22),
|
|
array(15,52,46,26,24,82,49,36,25),
|
|
array(64,86,30,05,51,75,58,66,28),
|
|
array(16,23,14,81,78,68,67,96,31),
|
|
array(65,57,95,60,08,61,76,29,34),
|
|
array(17,91,79,39,35,54,85,59,37),
|
|
array(66,28,63,18,62,47,94,89,40),
|
|
);
|
|
|
|
// Chiffre 0 à 9
|
|
$tabPoids = array(1,34,-16,-21,27,-7,9,30,3);
|
|
$cle = $first = 0;
|
|
for($pos=0; $pos<9; $pos++) {
|
|
$chiffre = $this->siren[$pos];
|
|
if ($first == 0) {
|
|
$first = $cle = $tabFirst[$chiffre][$pos];
|
|
} else {
|
|
$cle += $tabPoids[$pos] * $chiffre;
|
|
}
|
|
}
|
|
while(true) {
|
|
if ($cle > 96) {
|
|
$cle = $cle - 97;
|
|
}
|
|
elseif ($cle < 0) {
|
|
$cle = $cle + 97;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
if ($cle == 0) {
|
|
return 96;
|
|
}
|
|
return ($cle-1);
|
|
}
|
|
|
|
|
|
/**
|
|
* Test de la validité du siren demandé
|
|
*
|
|
* @param int SIREN à tester
|
|
* @param int NIC (facultatif)
|
|
* @param mixed Message textuel d'erreur à afficher en cas d'erreur ou false
|
|
* @return mixed true, false ou Message d'erreur passé en paramètre
|
|
*/
|
|
private function valideSiren($siren, $nic='', $erreur=false)
|
|
{
|
|
$siren = str_pad($siren, 9, '0', STR_PAD_LEFT);
|
|
if (!empty($nic)) {
|
|
$nic = str_pad($nic, 5, '0', STR_PAD_LEFT);
|
|
}
|
|
//Siren non précisé ou incorrect.
|
|
if (!Metier_Util_String::valideData($siren, 9, 9,'N')) {
|
|
return $erreur;
|
|
}
|
|
// Siren vide
|
|
elseif (intval($siren) == 0) {
|
|
return $erreur;
|
|
}
|
|
else {
|
|
if (!isset($nic) || trim($nic)=='') {
|
|
$somme = 0;
|
|
// Traitement IMPAIR
|
|
for ($i=0; $i<=8; $i+=2) {
|
|
$somme+= (integer) substr($siren,$i,1);
|
|
}
|
|
// Traitement PAIR
|
|
for ($i=1; $i<=7; $i+=2) {
|
|
$var_tmp = (string) (2*((integer)substr($siren,$i,1)));
|
|
$som_tmp = 0;
|
|
for($j=0; $j<strlen($var_tmp);$j++) {
|
|
$som_tmp+= (integer)substr($var_tmp,$j,1);
|
|
}
|
|
$somme+= $som_tmp;
|
|
}
|
|
|
|
// Le Siren est faux
|
|
if ((integer) ($somme/10) != ($somme/10)) {
|
|
// Les siren débutant par 200 sont toujours valides (sirens provisoires de la BDF?!)
|
|
if (substr($siren,0,3) != '200') {
|
|
return $erreur;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// Nic de format incorrect.
|
|
if (!Metier_Util_String::valideData($nic,1,5,'N')) {
|
|
return $erreur;
|
|
}
|
|
$SIRET = $siren.$nic;
|
|
if ($siren == '356000000') {
|
|
// Cas particulier du siren de LA POSTE : 356 000 000 00000
|
|
$somme = 14;
|
|
for ($i=9; $i<=13; $i++) {
|
|
$somme+= (integer)substr($SIRET,$i,1);
|
|
}
|
|
// Le NIC de l'établissement de LA POSTE est faux !
|
|
if ($somme%5 != 0) {
|
|
return $erreur;
|
|
}
|
|
} else {
|
|
$somme=0;
|
|
// Traitement PAIR
|
|
for ($i=0; $i<=12; $i+=2) {
|
|
$var_tmp = (string) (2*((integer)substr($SIRET,$i,1)));
|
|
$som_tmp = 0;
|
|
for($j=0; $j<strlen($var_tmp); $j++) {
|
|
$som_tmp+= (integer) substr($var_tmp,$j,1);
|
|
}
|
|
$somme+= $som_tmp;
|
|
}
|
|
// Traitement IMPAIR
|
|
for ($i=1; $i<=13; $i+=2) {
|
|
$somme+= (integer) substr($SIRET,$i,1);
|
|
}
|
|
// Le Siret est faux
|
|
if ((integer) ($somme/10) != ($somme/10)) {
|
|
return $erreur;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
} |