Classe abstraite, interface ?

ViPHP
ViPHP | 3607 Messages

22 janv. 2010, 15:03

Bonjour,
J'ai un petit soucis de conception objet...
Je souhaite créer un ensemble de classe permettant de générer des fichier à la norme CFONB (ce sont des fichiers qui permettent d'automatiser des groupes de virements bancaires).
J'ai donc pour l'instant deux types de fichiers, les CFONB 320 Caractères permettant de faire des virements internationaux, et des fichiers CFONB 160 Caractères permettant seulement des virements de la France vers la France.
Le principe général reste le même, récupérations d'informations sur l'émetteur et les destinataires, génération des lignes du fichier, puis envoi/sauvegarde.
Il n'y donc que deux choses qui changent:
  • Les renseignements demandés sont différents pour l'un et l'autre fichiers
  • La construction de chaque ligne du fichier est différente
J'ai donc essayé de créer une classe abstraite générique puisque des méthodes sont partagées entre les deux types.
J'ai abstrait la méthode qui sert à construire les lignes du fichier, afin d'obliger les classes filles à la redéfinir.
J'ai voulu faire de même avec les variables contenant les infos spécifiques aux champs de chaque type de fichier ( $_from_fields & $_to_fields)
Bon bien sûr ça ne fonctionne pas, le mot clé abstract est réservé aux méthodes d'une classe et à la classe elle-même!

Donc la question est: Est-ce que le modèle que j'ai ébauché est bon et viable? Avez-vous de meilleurs propositions?
Si vous avez des remarques toute bête sur la visibilité des variables/méthodes (public,protected, etc...) je vous en pris!

Ci-dessous les classes en question:
<?php


abstract class cfonb {

  /**
  * Variable qui contiendra toutes les lignes du fichier
  */
  public $_lines=array();
  
  /**
  * Variable qui contiendra le contenu du fichier final
  */
  public $_content='';

  /**
  * Variables contenant les champs obligatoires à la construction du
  * fichier
  */
  
  // Dans l'idéal, je voudrais abstraire ces variables
  // Pour que les classes filles soient forcées de les redéfinir
  public $_from_fields=array();
  public $_to_fields=array();

  /**
  * Variables contenant les infos émetteur/destinataires
  */
  public $_from=array();
  public $_to=array();


  /**
  * cfonb::__construct
  *
  * Initialise les données utilisateur
  *
  * @param    array   $from   Issuer informations
  * @param    array   $to     Adressees informations
  * @return   none
  */
  public function __construct($from,$to){
    
    // Vérification des entrées $from & $to,
    // En fonction des tableau de valeurs
    // $this->_to_fields & $this->_from_fields
    // définits dans les classes filles

  }

  /**
  * cfonb::buildLines
  *
  * Construit chaque ligne du fichier
  *
  * @param    none
  * @return   none
  */
  
  // Méthode à définir dans les classes filles, puisqu'elle
  // Diffère celon la type de fichier à générer
  abstract protected function buildLines();

  /**
  * cfonb::buildFile
  *
  * Assemble les lignes construites en un seul tenant
  *
  * @param    none
  * @return   none
  */
  public function buildFile($add_empty_end_line=true){
    // ...
  }


  /**
  * cfonb::getContent
  *
  * Retourne le contenu du fichier cfonb
  *
  * @param    none
  * @return   string  content of file
  */
  public function getContent(){
    return $this->_content;
  }


  /**
  * cfonb::saveFile
  *
  * Enregistre le contenu du cfonb dans un fichier réel
  *
  * @param    string  $path     Path to file
  * @param    string  $content  Replace $this->_content
  * @return   none
  */
  public function saveFile($path, $content=''){
    
    if(empty($content)){
      $content = $this->_content;
    }
    
    if(!file_put_contents($path,$content)){
      throw new Exception('Save the content of cfonb in '.$path.' failed!');
    }
  }


  /**
  * cfonb::send
  *
  * Enregistre le contenu du cfonb dans un fichier réel
  *
  * @param    array   $emails   list of Addressees emails
  * @param    string  $content  Replace $this->_content
  * @return   none
  */
  public function send($emails, $content=''){
    // ...
  }
}

// Virements internationaux
class cfonb320 extends cfonb {

  public $_from_fields=array(
      // Champs présents pour le fihcier cfonb 320 caractères
  );
  
  public $_to_fields=array(
      // Champs présents pour le fihcier cfonb 320 caractères
  );

  public function buildLines(){
   
    // Construction de chaque ligne du fichier
      
  }
}

// Virements français
class cfonb160 extends cfonb {
  
  public $_from_fields=array(
      // Champs présents pour le fihcier cfonb 160 caractères
  );
  
  public $_to_fields=array(
      // Champs présents pour le fihcier cfonb 160 caractères
  );
  
  public function buildLines(){
   
    // Construction de chaque ligne du fichier
    
  }
}
Merci d'avance pour vos lumières ;)

PS: si jamais vous avez des retours d'expèrience sur les gestion de fichiers CFONB/ETEBAC, etc... je suis preneur :-°

Eléphant du PHP | 453 Messages

22 janv. 2010, 18:30

Hello,

Il me semble que ce sujet devrait répondre à ton problème. J'ai lu vite fait ton code et j'ai l'impression que tu oublies des notions POO notamment public/private/protected. :-k Je ne suis pas fortiche en POO et je peux me tromper. Je pense à ce genre de situation :

[*]le modèle véhicule a une propriété de couleur[/*]
[*]le modèle voiture a la propriété de couleur héritée de sa classe mère[/*]
[*]le modèle moto a la propriété de couleur héritée de sa classe mère[/*]

Le carrossier peut changer la couleur de chaque type de véhicule seulement s'il doit par exemple repeindre ses derniers.
[...]des fichier à la norme CFONB (ce sont des fichiers qui permettent d'automatiser des groupes de virements bancaires).
J'ai donc pour l'instant deux types de fichiers, les CFONB 320 Caractères permettant de faire des virements internationaux, et des fichiers CFONB 160 Caractères permettant seulement des virements de la France vers la France.[...]
Comme je suis curieux, aurais tu un/des lien(s) intéressant(s) sur le sujet, STP ? Merci par avance. ^^

Bonne journée à toi
La Tux attitude avec les kiw'z syou plait
Komodo Edit - Inkscape - Dia

ViPHP
ViPHP | 3607 Messages

22 janv. 2010, 18:47

Hello,

Pour répondre déjà à ta curiosité légitime,
voici déjà l'organisme à l'origine de la norme éponyme : http://www.cfonb.org/
Malheureusement il n'y pas beaucoup de ressource sur le sujet: voici un semblant de specs sur le cfonb 160 caractères: http://www.google.fr/url?sa=t&source=we ... Nyg_Ru9IgQ (attention PDF)

En gros ce sont des fichiers normalisés permettant de transmettre des ordres de virements multiples à ta banque, si cette dernière le permet.
C'est utile pour des sociétés en ligne, afin d'automatiser les retraits (genre Ebay -bien qu'à cette échelle, les techniques doivent être tout autre!-)

Ensuite pour revenir à nos moutons,
J'utilise déjà en quelque sorte le pattern Strategy (même si je ne savais pas qu'il s'appelait comme ça...).
J'ai une classe "mère" abstraite qui regroupe les méthodes communes, et indique la méthode à redéfinir dans les classes filles.

Pour ce qui est de la visibilité de mes attributs et méthodes, je n'ai pas tout peaufiner dans le détail, mais j'ai du passer des attributs à public, afin que l'héritage se fasse sans mal...
Mais je suis prêt à refaire le tout comme il faut pour peu qu'on m'indique un début de marche à suivre ;)

Merci d'avance!

Eléphant du PHP | 199 Messages

22 janv. 2010, 19:03

Je tiens à dire que mettre des attributs en public n'est pas sécurisé.
En effet on doit pouvoir accéder aux attributs de ta classe par des accesseurs (set() et get()).
Pour ma part si tu as besoin de travailler avec tes attributs utilise les.

Pierre-Louis

ViPHP
ViPHP | 3607 Messages

28 janv. 2010, 17:31

Bonjour,

Afin de prendre en compte ta remarque, j'ai passé la plupart des attributs en protected (private m'étant interdit vu l'héritage), voici ce que ça donne (code complet):
<?php

/**
 * Classe abstraite CFONB permettant la génération de fichiers de
 * virements banquaire.
 *
 * @since       PHP 5
 * @package     CFONB
 * @abstract
 */
abstract class cfonb {

  /**
  * Variable qui contiendra toutes les lignes du fichier
  */
  protected $_lines=array();
  
  /**
  * Variable qui contiendra le contenu du fichier final
  */
  protected $_content='';

  /**
  * Variables contenant les infos émetteur/destinataires
  */
  protected $_from=array();
  protected $_to=array();

  /**
  * Constante EOF
  */
  const END_OF_LINE=PHP_EOL;

  /**
  * cfonb::__construct
  *
  * Initialise les données utilisateur
  *
  * @param    array   $from   Issuer informations
  * @param    array   $to     Adressees informations
  * @access   public
  * @return   none
  */
  public function __construct($from,$to){
    
    // Vérification des données émetteur
    foreach($this->_from_fields as $field => $properties){
      // Champs obligatoire
      if($properties['mandat']===true){
        if(!array_key_exists($field,$from)){
          throw new Exception('You have to give all Issuer mandatory 
            fields: <b>'.$field.'</b> is not given.');
        }
        else {
          if(isset($properties['default']) && isset($from[$field]) && $from[$field]=='useDefault'){
            $this->_from[$field]=$properties['default'];
          }
          else {
            if($properties['length'] < mb_strlen($from[$field])){
              $from[$field]=substr($from[$field],0,$properties['length']);
            }
            $this->_from[$field]=$from[$field];
          }
        }
      }
      // non obligatoire
      else {
        if(isset($properties['default']) && (!isset($from[$field]) || $from[$field]=='useDefault')){
          $this->_from[$field]=$properties['default'];
        }
        elseif(!empty($from[$field])) {
          if($properties['length'] < mb_strlen($from[$field])){
            $from[$field]=substr($from[$field],0,$properties['length']);
          }
          $this->_from[$field]=$from[$field];
        }
        else {
          $this->_from[$field]='';
        }
      }
    }
  
    // Si un seul enregistrement
    if(!is_array($to[0])){
      $to=array($to);
    }
  
    // Vérification des données émetteur
    foreach($this->_to_fields as $field => $properties){
      // Champs obligatoire
      foreach($to as $key=>$desti){
        if($properties['mandat']===true){
          if(!array_key_exists($field,$desti)){
            throw new Exception('You have to give all Addressees mandatory 
              fields: <b>'.$field.'</b> is not given.');
          }
          else {
            if(isset($properties['default']) && isset($desti[$field]) && $desti[$field]=='useDefault'){
              $this->_to[$key][$field]=$properties['default'];
            }
            else {
              if($properties['length'] < mb_strlen($desti[$field])){
                $desti[$field]=substr($desti[$field],0,$properties['length']);
              }
              $this->_to[$key][$field]=$desti[$field];
            }
          }
        }
        // non obligatoire
        else {
          if(isset($properties['default']) && (!isset($desti[$field]) || $desti[$field]=='useDefault')){
            $this->_to[$key][$field]=$properties['default'];
          }
          elseif(!empty($desti[$field])) {
            if($properties['length'] < mb_strlen($desti[$field])){
              $desti[$field]=substr($desti[$field],0,$properties['length']);
            }
            $this->_to[$key][$field]=$desti[$field];
          }
          else {
            $this->_to[$key][$field]='';
          }
        }
      }
    }
    
    $this->filter($this->_from);
    $this->filter($this->_to);
  }


  /**
  * cfonb::filter
  *
  * Traite récursivement le tableau donné en paramètre à l'aide de
  * cfonb::epure
  *
  * @param    array   $array  Tableau à traiter (passé par référence)
  * @access   private
  * @return   none
  */
  private function filter(&$array){
    // Appel de la méthode cfonb::epure
    array_walk_recursive($array, array($this, 'epure'));
  }

  /**
  * cfonb::epure
  *
  * Traite la variable donnée pour qu'elle ne contienne plus que les
  * caractères:
  *   A-Z0-9 '"' '.' ')' '(' '/' ' ' '-'
  *
  * @param    string   $item  Chaine à traiter (passé par référence)
  * @access   private
  * @return   none
  */
  private function epure(&$item){
    
    // Suppression accents
    $tmp = strtr(
      $item,
      'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ',
      'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY'
    );
    // Mise en majuscule
    $tmp = strtoupper($tmp);
    // Suppression de tout les caractères non-authorisés
    // autorisés: A-Z0-9 '"' '.' ')' '(' '/' ' ' '-'
    $item = preg_replace('#[^A-Z0-9"\.\)\(/ -]#','',$tmp);
  }

  /**
  * cfonb::buildLines
  *
  * Construit chaque ligne du fichier
  *
  * @param    none
  * @access   protected
  * @abstract
  * @return   none
  */
  abstract protected function buildLines();

  /**
  * cfonb::buildFile
  *
  * Assemble les lignes construites en un morceau
  *
  * @param    none
  * @access   protected
  * @return   none
  */
  protected function buildFile($add_empty_end_line=true){
    
    
    if(!empty($this->_lines)){
      
      if($add_empty_end_line){
        end($this->_lines);
        // Le dernier enregistrement est-il une ligne vide?
        if(!empty($this->_lines[key($this->_lines)])){
          $this->_lines[]='';
        }
      }

      $this->_content = implode(self::END_OF_LINE,$this->_lines);
    }
    else {
      throw new Exception('The lines are empty, make sure the 
        informations about the Issuer & the recipients are correct...');
    }
  }


  /**
  * cfonb::getContent
  *
  * Retourne le contenu du fichier cfonb
  *
  * @param    none
  * @access   public
  * @return   string  content of file
  */
  public function getContent(){
    return $this->_content;
  }


  /**
  * cfonb::saveFile
  *
  * Enregistre le contenu du cfonb dans un fichier réel
  *
  * @param    string  $path     Path to file
  * @param    string  $content  Replace $this->_content
  * @access   public
  * @return   none
  */
  public function saveFile($path, $content=''){
    
    if(empty($content)){
      $content = $this->_content;
    }
    
    if(!file_put_contents($path,$content)){
      throw new Exception('Save the content of cfonb in '.$path.' failed!');
    }
  }


  /**
  * cfonb::send
  *
  * Envoi le contenu du fichier à la liste d'emails
  *
  * @param    array   $emails   list of emails
  * @param    string  $content  Replace $this->_content
  * @access   public
  * @return   none
  */
  public function send($emails, $title='Virement CFONB', $content=''){
    
    global $adminemail;
    
    // on génère une frontière
    $boundary = '-----=' . md5( uniqid ( rand() ) );

    if(empty($content)){
      $content = $this->_content;
    }
    $content_encode = chunk_split(base64_encode($content));

    $headers  = "From: \"Codeur.com\"<".$adminemail.">\n";
    $headers .= "MIME-Version: 1.0\n";
    $headers .= "Content-Type: multipart/mixed; boundary=\"".$boundary."\"";

    $message  = "Ceci est un message au format MIME 1.0 multipart/mixed.\n\n";
    $message .= "--" . $boundary . "\n";
    $message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
    $message .= "Content-Transfer-Encoding: 8bit\n\n";
    $message .= $msg;
    $message .= "\n";
    $message .= "--" . $boundary . "\n";
    $message .= "Content-Type: text/plain; name=\"cfonb.txt\"\n";
    $message .= "Content-Transfer-Encoding: base64\n";
    // mettez inline au lieu de attachment
    // pour que l'image s'affiche dans l'email
    $message .= "Content-Disposition: attachment; filename=\"cfonb.txt\"\n\n";
    $message .= $content_encode . "\n";
    $message .= "\n\n";
    $message .= "--" . $boundary . "--\n";

    foreach($emails as $email){
      mail($email, $title, $message, $headers);
    }

  }
}


/**
 * Classe permettant la génération de fichiers CFONB Internationaux.
 *
 * @since       PHP 5
 * @package     CFONB
 * @subpackage  CFONB320
 * @abstract
 */
class cfonb320 extends cfonb {

  /**
  * Variables contenant les informations sur les champs émetteur
  */
  protected $_from_fields=array(
      'date_creation'=>         array('length'=>10,'mandat'=>true,'default'=>'now'),
      'raison_sociale'=>        array('length'=>35,'mandat'=>true),
      'address1'=>              array('length'=>35,'mandat'=>true), 
      'address2'=>              array('length'=>35,'mandat'=>false), 
      'address3'=>              array('length'=>35,'mandat'=>false), 
      'siret'=>                 array('length'=>14,'mandat'=>false,'default'=>'xxxxxxxxxxxx'),
      'reference_virement'=>    array('length'=>16,'mandat'=>true),
      'bic'=>                   array('length'=>11,'mandat'=>false,'default'=>'xxxxxxxx'),
      'type_num_compte'=>       array('length'=>1,'mandat'=>false,'default'=>1),
      'numero_compte'=>         array('length'=>34,'mandat'=>true),
      'devise_compte'=>         array('length'=>3,'mandat'=>false,'default'=>'EUR'),
      'numero_emetteur'=>       array('length'=>16,'mandat'=>false),
      'type_num_compte_frais'=> array('length'=>1,'mandat'=>false,'default'=>1),
      'numero_compte_frais'=>   array('length'=>34,'mandat'=>false),
      'devise_compte_frais'=>   array('length'=>3,'mandat'=>false,'default'=>'EUR'),
      'type_debit'=>            array('length'=>1,'mandat'=>false,'default'=>2),
      'type_remise'=>           array('length'=>1,'mandat'=>false,'default'=>1),
      'date_execution'=>        array('length'=>10,'mandat'=>false,'default'=>'now'),
      'devise'=>                array('length'=>3,'mandat'=>false,'default'=>'EUR')
  );
  
  /**
  * Variables contenant les informations sur les champs destinataires
  */
  protected $_to_fields=array(
      'type_num_compte'=>       array('length'=>1,'mandat'=>false,'default'=>1),
      'numero_compte'=>         array('length'=>34,'mandat'=>false),
      'raison_sociale'=>        array('length'=>35,'mandat'=>true),
      'address1'=>              array('length'=>35,'mandat'=>false),
      'address2'=>              array('length'=>35,'mandat'=>false),
      'address3'=>              array('length'=>35,'mandat'=>false),
      'id_nationale'=>          array('length'=>17,'mandat'=>false),
      'pays'=>                  array('length'=>2,'mandat'=>true,'default'=>'FR'),
      'reference'=>             array('length'=>16,'mandat'=>true),
      'qualifiant'=>            array('length'=>1,'mandat'=>false,'default'=>'D'),
      'montant'=>               array('length'=>14,'mandat'=>true),
      'decimales'=>             array('length'=>1,'mandat'=>false,'default'=>2),
      'code_eco'=>              array('length'=>3,'mandat'=>false,'default'=>'010'),
      'pays_BDF'=>              array('length'=>2,'mandat'=>false,'default'=>'FR'),
      'mode_reglement'=>        array('length'=>1,'mandat'=>false,'default'=>0),
      'frais'=>                 array('length'=>2,'mandat'=>false,'default'=>'13'),
      'type_num_compte_frais'=> array('length'=>1,'mandat'=>false,'default'=>1),
      'numero_compte_frais'=>   array('length'=>34,'mandat'=>false),
      'devise_compte_frais'=>   array('length'=>3,'mandat'=>false,'default'=>'EUR'),
      'date_execution'=>        array('length'=>10,'mandat'=>false,'default'=>'now'),
      'devise'=>                array('length'=>3,'mandat'=>false,'default'=>'EUR')
  );

  /**
  * Variables de comptage
  */
  private $_num_sequentiel=1;
  
  
  /**
  * cfonb::buildLines
  *
  * Construit les lignes d'entête, de détails et de total
  *
  * @param    none
  * @access   public
  * @return   none
  */
  public function buildLines(){
   
    /*
     * Construction de la ligne d'entête (émetteur)
     */
    
    $this->_lines[] =     '03'.
                          'PI'.
                          sprintf('%06s',$this->_num_sequentiel).
                          date('Ymd',($this->_from['date_creation']=='NOW' ? time() : $this->_from['date_creation'])).
                          sprintf('%-35s',$this->_from['raison_sociale']).
                          sprintf('%-35s',$this->_from['address1']).
                          sprintf('%-35s',$this->_from['address2']).
                          sprintf('%-35s',$this->_from['address3']).
                          sprintf('%-14s',$this->_from['siret']).
                          sprintf('%-16s',$this->_from['reference_virement']).
                          sprintf('%-11s',$this->_from['bic']).
                          sprintf('%-1s',$this->_from['type_num_compte']).
                          sprintf('%-34s',$this->_from['numero_compte']).
                          sprintf('%-3s',$this->_from['devise_compte']).
                          sprintf('%-16s',$this->_from['numero_emetteur']).
                          sprintf('%-1s',empty($this->_from['numero_compte_frais']) ? null:$this->_from['type_num_compte_frais']).
                          sprintf('%-34s',$this->_from['numero_compte_frais']).
                          sprintf('%-3s',$this->_from['devise_compte_frais']).
                          sprintf('%16s',null).
                          sprintf('%-1s',$this->_from['type_debit']).  
                          sprintf('%-1s',$this->_from['type_remise']).
                          sprintf('%-8s',
                            ($this->_from['type_remise']==1 || $this->_from['type_remise']==2) ?
                              date(
                                'Ymd',
                                ($this->_from['date_execution']=='NOW' ? time() : $this->_from['date_execution'])
                              ) 
                              : null
                          ).
                          sprintf('%-3s',
                            ($this->_from['type_remise']==1 || $this->_from['type_remise']==3) ?
                              $this->_from['devise']
                              : null
                          );  
    
    /*
     * Construction des lignes de détail (destinataires)
     */
    
    $montantTotal=0;
    $this->_num_sequentiel++;
    
    foreach($this->_to as $desti){
      
      $this->_lines[]=  '04'.
                        'PI'.
                        sprintf('%06s',$this->_num_sequentiel).
                        sprintf('%-1s',$desti['type_num_compte']).
                        sprintf('%-34s',$desti['numero_compte']).
                        sprintf('%-35s',$desti['raison_sociale']).
                        sprintf('%-35s',$desti['address1']).
                        sprintf('%-35s',$desti['address2']).
                        sprintf('%-35s',$desti['address3']).
                        sprintf('%-17s',$desti['id_nationale']).
                        sprintf('%-2s',$desti['pays']).
                        sprintf('%-16s',$desti['reference']).
                        sprintf('%-1s',$desti['qualifiant']).
                        sprintf('%4s',null).
                        sprintf('%014s',$desti['montant']).
                        sprintf('%1s',$desti['decimales']).
                        sprintf('%1s',null).
                        sprintf('%-3s',$desti['code_eco']).
                        sprintf('%-2s',$desti['pays_BDF']).
                        sprintf('%-1s',$desti['mode_reglement']).
                        sprintf('%-2s',$desti['frais']).
                        sprintf('%-1s',empty($desti['numero_compte_frais']) ? null:$desti['type_num_compte_frais']).
                        sprintf('%-34s',$desti['numero_compte_frais']).
                        sprintf('%-3s',$desti['devise_compte_frais']).
                        sprintf('%22s',null).
                        sprintf('%-8s',
                          ($this->_from['type_remise']==3 || $this->_from['type_remise']==4) ?
                            date(
                              'Ymd',
                              ($desti['date_execution']=='NOW' ? time() : $desti['date_execution'])
                            ) 
                            : null
                        ).
                        sprintf('%-3s',
                          ($this->_from['type_remise']==2 || $this->_from['type_remise']==4) ?
                            $desti['devise']
                            : null
                        );
                        
      
      $this->_num_sequentiel++;
      $montantTotal+=(int)$desti['montant'];
    }
    
    /*
     * Construction de la ligne de Total
     */
    $this->_lines[] = '08'.
                      'PI'.
                      sprintf('%06s',$this->_num_sequentiel).
                      date('Ymd',($this->_from['date_creation']=='NOW' ? time() : (int)$this->_from['date_creation'])).
                      sprintf('%140s',null).
                      sprintf('%-14s',$this->_from['siret']).
                      sprintf('%-16s',$this->_from['reference_virement']).
                      sprintf('%11s',null).
                      sprintf('%-1s',$this->_from['type_num_compte']).
                      sprintf('%-34s',$this->_from['numero_compte']).
                      sprintf('%-3s',$this->_from['devise_compte']).
                      sprintf('%-16s',$this->_from['numero_emetteur']).
                      sprintf('%018s',$montantTotal).
                      sprintf('%49s',null);
                      
    $this->buildFile();
    
  }
}


/**
 * Classe permettant la génération de fichiers CFONB Français.
 *
 * @since       PHP 5
 * @package     CFONB
 * @subpackage  CFONB160
 * @abstract
 */
class cfonb160 extends cfonb {

  /**
  * Variables contenant les informations sur les champs emetteur
  */  
  protected $_from_fields=array(
      'numero_emetteur'=>       array('length'=>6,'mandat'=>true),
      'date_de_valeur'=>        array('length'=>5,'mandat'=>true,'default'=>'now'),
      'raison_sociale'=>        array('length'=>24,'mandat'=>true),
      'reference_virement'=>    array('length'=>11,'mandat'=>true),
      'numero_guichet'=>        array('length'=>5,'mandat'=>true),
      'numero_compte'=>         array('length'=>11,'mandat'=>true),
      'numero_etablissement'=>  array('length'=>5,'mandat'=>true)
  );
  
  /**
  * Variables contenant les informations sur les champs destinataires
  */ 
  protected $_to_fields=array(
      'reference_ligne'=>       array('length'=>12,'mandat'=>true),
      'raison_sociale'=>        array('length'=>24,'mandat'=>true),
      'banque'=>                array('length'=>20,'mandat'=>true),
      'numero_guichet'=>        array('length'=>5,'mandat'=>true),
      'numero_compte'=>         array('length'=>11,'mandat'=>true),
      'montant'=>               array('length'=>16,'mandat'=>true),
      'label'=>                 array('length'=>31,'mandat'=>true),
      'numero_etablissement'=>  array('length'=>5,'mandat'=>true)
  );
  
  
  /**
  * cfonb::buildLines
  *
  * Construit les lignes d'entête, de détails et de total
  *
  * @param    none
  * @access   public
  * @return   none
  */  
  public function buildLines(){

    
    /*
     * Construction de la ligne d'entête (émetteur)
     */
    
    $this->_lines[] =     '0302'.
                          sprintf('%8s',null).
                          $this->_from['numero_emetteur'].
                          sprintf('%7s',null).
                          $this->_from['date_de_valeur'].
                          sprintf('%-24s',$this->_from['raison_sociale']).
                          sprintf('%-11s',$this->_from['reference_virement']).
                          sprintf('%15s',null).
                          'E'.
                          sprintf('%5s',null).
                          $this->_from['numero_guichet'].
                          $this->_from['numero_compte'].
                          sprintf('%47s',null).
                          $this->_from['numero_etablissement'].
                          sprintf('%5s',null);                            

    /*
     * Construction des lignes de détail (destinataires)
     */
    
    $totalAmount=0;
    
    foreach($this->_to as $desti){

      $this->_lines[] =     '0602'.
                            sprintf('%8s',null).
                            $this->_from['numero_emetteur'].
                            sprintf('%-12s',$desti['reference_ligne']).
                            sprintf('%-24s',$desti['raison_sociale']).
                            sprintf('%-20s',$desti['banque']).
                            sprintf('%12s',null).
                            $desti['numero_guichet'].
                            $desti['numero_compte'].
                            sprintf('%016s',$desti['montant']).
                            sprintf('%-31s',$desti['label']).
                            $desti['numero_etablissement'].
                            sprintf('%5s',null);
                            
      $totalAmount+=(int)$desti['montant'];
                           
    }
    
    
    /*
     * Construction de la ligne de Total
     */
    $this->_lines[] =     '0802'.
                          sprintf('%8s',null).
                          $this->_from['numero_emetteur'].
                          sprintf('%84s',null).
                          sprintf('%016s',$totalAmount).
                          sprintf('%42s',null);
    
    
    // Assemblage
    $this->buildFile();
  }
}




// Exemple CFONB160

$emetteur = array(
  'numero_emetteur'=>'xxx',
  'date_de_valeur'=>strtotime('+1 day'),
  'raison_sociale'=>'DUPOND',
  'reference_virement'=>'V '.date('d/m/y'),
  'numero_guichet'=>'xxxxxxx',
  'numero_compte'=>'xxxxxxxxxxx',
  'numero_etablissement'=>'xxxx'
);

$destinataires = array(
  array(
    'reference_ligne'=>'VIR.1',
    'raison_sociale'=>'DUPONT',
    'banque'=>'XXXX',
    'numero_guichet'=>'xxxx',
    'numero_compte'=>'xxxxxxxxxxx',
    'montant'=>10000,
    'label'=>'Retrait untel',
    'numero_etablissement'=>'xxxxx'
  ),
  array(
    'reference_ligne'=>'VIR.2',
    'raison_sociale'=>'TOURNESOL',
    'banque'=>'XXXXXX',
    'numero_guichet'=>'xxxxxxx',
    'numero_compte'=>'xxxxxxxxxxxx',
    'montant'=>25000,
    'label'=>'Autre Retrait',
    'numero_etablissement'=>'xxxxx'
  )
);
      

try {

  $wires=new cfonb160($emetteur,$destinataires);
  $wires->buildLines();
  echo '<pre>',$wires->getContent(),'</pre>';

} catch (Exception $e) {  
  
  echo $e->getMessage();
  
}


// Exemple CFONB320

$emetteur = array(
  'date_creation'=>time(),
  'date_execution'=>strtotime('+1 day'),
  'address1'=>'quartier',
  'address2'=>'ville',
  'numero_emetteur'=>'xxxxx',
  'raison_sociale'=>'DUPOND',
  'reference_virement'=>'V '.date('d/m/y'),
  'numero_compte'=>'xxxxxxxxxxxxxxxxxxxxxxxxx',
  'siret'=> 'xxxxxxxxxxxxxxxx',
  'bic'=>'xxxxxxxxxxxx'

);

$destinataires = array(
  array(
    'reference'=>'VIR.1',
    'raison_sociale'=>'MILOU',
    'numero_compte'=>'xxxxxxxxxxxxxxxxxxxxxxxxx',
    'montant'=>10000,
    'pays'=>'FR'
  ),
  array(
    'reference'=>'VIR.2',
    'raison_sociale'=>'TINTIN',
    'numero_compte'=>'xxxxxxxxxxxxxxxxxxxxxxxxx',
    'montant'=>25000,
    'pays'=>'FR'
  )
);


try {

  $wires=new cfonb320($emetteur,$destinataires);
  $wires->buildLines();
  echo '<pre>',$wires->getContent(),'</pre>';
  
} catch (Exception $e) {  
  
  echo $e->getMessage();
  
}
Est-ce que c'est préférable dans cette version? Aves-vous d'autres remarques quand à la structure de l'ensemble?

Merci d'avance :)

ViPHP
ViPHP | 5462 Messages

28 janv. 2010, 17:46

je comprend pas dans le doc du confb pour la date ils disent :
Date de valeur.
Le jour sur deux caractères (24)
Le mois sur deux caractères (03)
L'année sur un caractère (5)

L'année sur un caractère ? je vois pas, comment on met une année sur 1 caratere ?

ViPHP
ViPHP | 3607 Messages

28 janv. 2010, 17:50

Et ben c'est pourtant pas compliqué :p
"11/06/2008" donne "11068" (jjmma)
Voilou ;)

ViPHP
ViPHP | 5462 Messages

28 janv. 2010, 17:55

Et ben c'est pourtant pas compliqué :p
"11/06/2008" donne "11068" (jjmma)
Voilou ;)
ouai c'est pas compliquer mais c'est con :

11-06-2000 == 11-06-2010 == 11-06-1990 == 11-06-2100
11-06-2008 == 11-06-2018 == 11-06-1998 == 11-06-2108

comment on connais la date exact après ?

ViPHP
ViPHP | 3607 Messages

28 janv. 2010, 18:07

Bon déjà, je n'ai aucune responsabilité sur le format hein :langue:
Ensuite, je pense que c'est simplement le fait que des ordres de virements ne courent pas sur des décennies... Donc l'erreur n'est pas possible.

ViPHP
ViPHP | 5462 Messages

28 janv. 2010, 18:14

Bon déjà, je n'ai aucune responsabilité sur le format hein :langue:
Ensuite, je pense que c'est simplement le fait que des ordres de virements ne courent pas sur des décennies... Donc l'erreur n'est pas possible.
ouais on peu le voir comme ca mais bon ca demandais réflexion quand même #-o