From 3d8fb60f945e09385f93cbbce3594c469a93370d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 30 Mar 2014 20:22:54 +0200 Subject: [PATCH] Start to implement sepa format. Need serious tests. --- htdocs/admin/prelevement.php | 10 + .../class/bonprelevement.class.php | 387 +++++++++++++----- 2 files changed, 305 insertions(+), 92 deletions(-) diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index d0c0b2fb3a5..8420953737d 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -51,6 +51,9 @@ if ($action == "set") if (! $res > 0) $error++; } + $res = dolibarr_set_const($db, "PRELEVEMENT_ICS", GETPOST("PRELEVEMENT_ICS"),'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + $id=GETPOST('PRELEVEMENT_ID_BANKACCOUNT','int'); $account = new Account($db, $id); @@ -148,6 +151,13 @@ print ''.$langs->trans("BankToReceiveWithdraw").''; print ''; print $form->select_comptes($conf->global->PRELEVEMENT_ID_BANKACCOUNT,'PRELEVEMENT_ID_BANKACCOUNT',0,"courant=1",1); print ''; + +// ICS +print ''.$langs->trans("ICS").''; +print ''; +print ''; +print ''; + print ''; print '
'; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index aba6d7ee3ee..2d2466272e4 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -30,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; + /** * Class to manage withdrawal receipts */ @@ -44,6 +45,11 @@ class BonPrelevement extends CommonObject var $emetteur_numero_compte; var $emetteur_code_banque; var $emetteur_number_key; + + var $emetteur_iban; + var $emetteur_bic; + var $emetteur_ics; + var $total; var $_fetched; var $statut; // 0-Wait, 1-Trans, 2-Done @@ -74,6 +80,10 @@ class BonPrelevement extends CommonObject $this->emetteur_code_banque = ""; $this->emetteur_number_key = ""; + $this->emetteur_iban = ""; + $this->emetteur_bic = ""; + $this->emetteur_ics = ""; + $this->factures = array(); $this->numero_national_emetteur = ""; @@ -655,9 +665,9 @@ class BonPrelevement extends CommonObject $resql = $this->db->query($sql); if ( $resql ) { - $row = $this->db->fetch_row($resql); + $obj = $this->db->fetch_object($resql); - return $row[0]; + return $obj->nb; $this->db->free($resql); } @@ -680,7 +690,7 @@ class BonPrelevement extends CommonObject { global $conf; - $sql = "SELECT count(f.rowid)"; + $sql = "SELECT count(f.rowid) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql.= ", ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd"; if ($banque || $agence) $sql.=", ".MAIN_DB_PREFIX."societe_rib as sr"; @@ -698,11 +708,11 @@ class BonPrelevement extends CommonObject if ( $resql ) { - $row = $this->db->fetch_row($resql); + $obj = $this->db->fetch_object($resql); $this->db->free($resql); - return $row[0]; + return $obj->nb; } else { @@ -1006,6 +1016,9 @@ class BonPrelevement extends CommonObject $bonprev->emetteur_code_guichet = $conf->global->PRELEVEMENT_CODE_GUICHET; $bonprev->emetteur_numero_compte = $conf->global->PRELEVEMENT_NUMERO_COMPTE; $bonprev->emetteur_number_key = $conf->global->PRELEVEMENT_NUMBER_KEY; + $bonprev->emetteur_iban = $conf->global->PRELEVEMENT_IBAN; + $bonprev->emetteur_bic = $conf->global->PRELEVEMENT_BIC; + $bonprev->emetteur_ics = $conf->global->PRELEVEMENT_ICS; // TODO Add this into setup of admin/prelevement.php. Ex: PRELEVEMENT_ICS = "FR78ZZZ123456"; $bonprev->factures = $factures_prev_id; @@ -1225,11 +1238,15 @@ class BonPrelevement extends CommonObject // TODO Move code for es and fr into an external module file with selection into setup of prelevement module + $found=0; + // Build file for Spain if ($mysoc->country_code=='ES') { if (! empty($conf->esaeb->enabled)) { + $found++; + dol_include_once('/esaeb/class/esaeb19.class.php'); //Head @@ -1278,102 +1295,125 @@ class BonPrelevement extends CommonObject $i++; } } - else - { + { $result = -2; } fputs($this->file, $esaeb19->generaRemesa()); } - else - { - $this->total = 0; - $sql = "SELECT pl.amount"; - $sql.= " FROM"; - $sql.= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql.= " ".MAIN_DB_PREFIX."facture as f,"; - $sql.= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; - $sql.= " WHERE pl.fk_prelevement_bons = ".$this->id; - $sql.= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql.= " AND pf.fk_facture = f.rowid"; - - //Lines - $i = 0; - $resql=$this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $this->total = $this->total + $obj->amount; - $i++; - } - } - else - { - $result = -2; - } - $langs->load('withdrawals'); - fputs($this->file, $langs->trans('WithdrawalFileNotCapable')); - } } - // Build file for France - elseif ($mysoc->country_code=='FR') + + // Build file for European countries + if (! $found && $mysoc->isInEEC()) { - /* - * En-tete Emetteur - */ - $this->EnregEmetteur(); + $found++; - /* - * Lines - */ - $this->total = 0; + /** + * SECTION CREATION FICHIER SEPA + * SECTION CREATION FICHIER SEPA + * SECTION CREATION FICHIER SEPA + */ + // SEPA Initialisation + $CrLf = "\n"; + $date_actu = dol_now(); + $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d'); + $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S'); + $dateTime_ECMA = dol_print_date($date_actu, '%Y-%m-%dT%H:%M:%S'); + $fileDebiteurSection = ''; + $fileEmetteurSection = ''; + $i = 0; + $this->total = 0; - $sql = "SELECT pl.rowid, pl.client_nom, pl.code_banque, pl.code_guichet, pl.number, pl.amount,"; - $sql.= " f.facnumber, pf.fk_facture"; - $sql.= " FROM"; - $sql.= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql.= " ".MAIN_DB_PREFIX."facture as f,"; - $sql.= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; - $sql.= " WHERE pl.fk_prelevement_bons = ".$this->id; - $sql.= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql.= " AND pf.fk_facture = f.rowid"; + /* + * section Debiteur (sepa Debiteurs bloc lines) + */ + $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, soc.datec, p.code as country_code,"; + $sql.= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; + $sql.= " f.facnumber as fac, pf.fk_facture as idfac, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum"; + $sql.= " FROM"; + $sql.= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; + $sql.= " ".MAIN_DB_PREFIX."facture as f,"; + $sql.= " ".MAIN_DB_PREFIX."prelevement_facture as pf,"; + $sql.= " ".MAIN_DB_PREFIX."societe as soc,"; + $sql.= " ".MAIN_DB_PREFIX."c_pays as p,"; + $sql.= " ".MAIN_DB_PREFIX."societe_rib as rib"; + $sql.= " WHERE pl.fk_prelevement_bons = ".$this->id; + $sql.= " AND pl.rowid = pf.fk_prelevement_lignes"; + $sql.= " AND pf.fk_facture = f.rowid"; + $sql.= " AND soc.fk_pays = p.rowid"; + $sql.= " AND soc.rowid = f.fk_soc"; + $sql.= " AND rib.fk_soc = f.fk_soc"; + $sql.= " AND rib.default_rib = 1"; - $i = 0; + //echo $sql; + $resql=$this->db->query($sql); + if ($resql) + { $num = $this->db->num_rows($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, + $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->facnumber, $obj->idfac, $obj->iban, $obj->bic, $obj->datec, $obj->drum); + $this->total = $this->total + $obj->somme; + $i++; + } + } + else + { fputs($this->file, 'ERREUR DEBITEUR '.$sql.$CrLf); + $result = -2; + } - $resql=$this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); + /* + * section Emetteur(sepa Emetteur bloc lines) + */ + if ($result != -2) + { $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $i, $this->total, $CrLf); + } + else + { fputs($this->file, 'ERREUR EMETTEUR'.$CrLf); + } - while ($i < $num) - { - $row = $this->db->fetch_row($resql); + /** + * SECTION CREATION FICHIER SEPA + * SECTION CREATION FICHIER SEPA + * SECTION CREATION FICHIER SEPA + */ + // SEPA File Header + fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); + fputs($this->file, ''.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA Group header + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.('PREL'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); + fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); + fputs($this->file, ' '.$i.''.$CrLf); + fputs($this->file, ' '.$this->total.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$this->raison_sociale.''.$CrLf); +/* fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' 0533883248'.$CrLf); + fputs($this->file, ' KBO-BCE'.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); +*/ fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA File Emetteur + if ($result != -2) + { fputs($this-> file, $fileEmetteurSection);} + // SEPA File Debiteurs + if ($result != -2) + { fputs($this-> file, $fileDebiteurSection);} + // SEPA FILE FOOTER + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ''.$CrLf); - $this->EnregDestinataire($row[0],$row[1],$row[2],$row[3],$row[4],$row[5],$row[6],$row[7]); - - $this->total = $this->total + $row[5]; - - $i++; - } - } - else - { - $result = -2; - } - - /* - * Pied de page total - */ - - $this->EnregTotal($this->total); } + // Build file for Other Countries with unknow format - else + if (! $found) { $this->total = 0; $sql = "SELECT pl.amount"; @@ -1426,9 +1466,10 @@ class BonPrelevement extends CommonObject * @param float $amount amount * @param string $facnumber ref of invoice * @param int $facid id of invoice + * @param string $rib_dom rib domiciliation * @return void */ - function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $facnumber, $facid) + function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $facnumber, $facid, $rib_dom='') { fputs($this->file, "06"); fputs($this->file, "08"); // Prelevement ordinaire @@ -1445,11 +1486,11 @@ class BonPrelevement extends CommonObject // Raison Sociale Destinataire C2 - fputs($this->file, substr($client->nom. " ",0,24)); + fputs($this->file, substr(strtoupper($client_nom)." ",0,24)); // Domiciliation facultative D1 - - fputs($this->file, substr(" ",0,24)); + $domiciliation = strtr($rib_dom, array(" " => "-", CHR(13) => " ", CHR(10) => "")); + fputs($this->file, substr($domiciliation." ",0,24)); // Zone Reservee D2 @@ -1471,8 +1512,7 @@ class BonPrelevement extends CommonObject // Libelle F - fputs($this->file, substr("*".$this->ref.$rowid." ",0,13)); - fputs($this->file, substr(" ",0,18)); + fputs($this->file, substr("*_".$facnumber."_RDVnet".$rowid." ", 0, 31)); // Code etablissement G1 @@ -1480,12 +1520,80 @@ class BonPrelevement extends CommonObject // Zone Reservee G2 - fputs($this->file, substr(" ",0,5)); + fputs($this->file, substr(" ", 0, 5)); fputs($this->file, "\n"); } + /** + * Write recipient of request (customer) + * + * @param string $row_code_client soc.code_client as code, + * @param string $row_nom pl.client_nom AS nom, + * @param string $row_address soc.address AS adr, + * @param string $row_zip soc.zip + * @param string $row_town soc.town + * @param string $row_country_code p.code AS pays, + * @param string $row_cb pl.code_banque AS cb, + * @param string $row_cg pl.code_guichet AS cg, + * @param string $row_cc pl.number AS cc, + * @param string $row_somme pl.amount AS somme, + * @param string $row_facnumber f.facnumber + * @param string $row_idfac pf.fk_facture AS idfac, + * @param string $row_iban rib.iban_prefix AS iban, + * @param string $row_bic rib.bic AS bic, + * @param string $row_datec soc.datec, + * @param string $row_drum soc.rowid AS drum + * @retrun void + */ + function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, + $row_somme, $row_facnumber, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum) + { + $CrLf = "\n"; + $Rowing = sprintf("%06d", $row_idfac); + $Date_Rum = strtotime($row_datec); + $pre = ($date_Rum > 1359673200) ? 'Rum' : '++R'; + $Rum = $pre.$row_code_client.$row_drum.'-0'.date('U', $Date_Rum); + $XML_DEBITOR =''; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.('AS-'.$row_facnumber.'-'.$Rowing).''.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.round($row_somme, 2).''.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$Rum.''.$CrLf; + $XML_DEBITOR .=' '.$row_datec.''.$CrLf; + $XML_DEBITOR .=' false'.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$row_iban.''.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.strtoupper($row_nom).''.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$row_country_code.''.$CrLf; + $XML_DEBITOR .=' '.strtr($row_adr, array(CHR(13) => ", ", CHR(10) => "")).''.$CrLf; + $XML_DEBITOR .=' '.$row_zip.' '.$row_town.''.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$row_iban.''.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.($row_facnumber.'/'.$Rowing.'/'.$Rum).''.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + $XML_DEBITOR .=' '.$CrLf; + return $XML_DEBITOR; + } + + /** * Write sender of request (me) * @@ -1552,6 +1660,101 @@ class BonPrelevement extends CommonObject } + /** + * Write sender of request (me) + * + * @return SEPA + */ + function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf='\n') + { // SEPA INITIALISATION + global $confs; + + $dateTime_YMD = dol_print_date($ladate, '%Y%m%d'); + $dateTime_ETAD = dol_print_date($ladate, '%Y-%m-%d'); + $dateTime_YMDHMS = dol_print_date($ladate, '%Y-%m-%dT%H:%M:%S'); + + // Récupération info demandeur + $sql = "SELECT rowid, ref"; + $sql.= " FROM"; + $sql.= " ".MAIN_DB_PREFIX."prelevement_bons as pb"; + $sql.= " WHERE pb.rowid = ".$this->id; + + $resql=$this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + + // DONNEES BRUTES : par la suite Rows['XXX'] de la requete au dessus + $pays = explode(':', $configuration->global->MAIN_INFO_SOCIETE_COUNTRY); + $IdBon = sprintf("%05d", $obj->rowid); + $RefBon = $obj->ref; + $type = (nombre == 1) ? 'FRST' : 'RCUR' ; + // SEPA Paiement Information + $XML_SEPA_INFO = ''; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' DD'.$CrLf; + $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; + $XML_SEPA_INFO .= ' '.$total.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' NORM'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' CORE'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$type.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$dateTime_ETAD.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$configuration->global->PRELEVEMENT_RAISON_SOCIALE.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$pays[1].''.$CrLf; + $XML_SEPA_INFO .= ' '.$configuration->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$configuration->global->MAIN_INFO_SOCIETE_ZIP.' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $configuration->global->PRELEVEMENT_IBAN).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$configuration->global->PRELEVEMENT_BIC.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; +/* $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$configuration->global->PRELEVEMENT_RAISON_SOCIALE.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$pays[1].''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; +*/ $XML_SEPA_INFO .= ' SLEV'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$configuration->global->PRELEVEMENT_ICS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + } + else + { + fputs($this->file, 'INCORRECT EMETTEUR '.$XML_SEPA_INFO.$CrLf); + $result = -2; + } + return $XML_SEPA_INFO; + } + /** * Write end *