Project

General

Profile

Créer un module de facturation

Le module de facturation est à la charge de chaque association. C'est pour l'instant un choix philosophique.

Il y a peu près autant de modes de facturation que d'associations. Mettre en place un système de configuration de la facturation est compliqué. Le système doit permette de décrire toutes les règles. C'est compliqué à développer mais c'est aussi compliqué à utiliser. En général la configuration de la facturation définie tout un ensemble de variables, de paramètres ainsi qu'une syntaxe pour définir les règles. Il faut que l’utilisateur maîtrise ce système pour pouvoir configurer la facturation. Je vous invite par exemple à configurer la facturation d'OpenFlyers. Souvent ce mécanisme entraine des limitations. Dans GVV, il n'y a aucune limitation des règles de facturation. Par exemple j'ai géré des remorqués vendus par avance à un prix avantageux. Tant que le pilote a des remorqués en compte on les décompte à chaque vol, quand il n'en a plus on le facture au prix fort. C'est important pour un club de définir des règles de facturation qui maximise son activité et ses rentrées d'argent, c'est toujours dommage de devoir se priver de cette possibilité parce que le système informatique ne le supporte pas.

La méthode proposée est de coder directement les règles de facturation en PHP. Le module de facturation est très simple. Il est appelé à chaque fois qu'un vol est saisi. En entrée vous avez tout les paramètres du vol, l'identification du pilote, de la machine, de la durée du vol, si c'est un VI, un vol d'essai, etc. Il faut donc que vous analysiez ces paramètre et que vous en déduisiez les "achats" correspondants, par exemple dans un cas compliqué un vol peu se traduire par de l'achat d'heures de vol, de remorqué, de centaines de metres supplémentaire, etc. Chez nous on facture différemment les pilotes au forfait, et les moins de 25 ans.

Les modules de facturation sont sous application/libraires/Facturation.php, Facturation_accabs.php (pour Abbeville), Facturation_aces.php (pour le Havre). C'est dans la configuration que l'extension (accabs, aces) est spécifié afin que l'aiguillage se fasse.

L'avantage de la méthode, est que vous pouvez créer un module de facturation qui fasse exactement ce que vous avez l'habitude de faire. L'inconvénient est qu'il faut écrire un peu de PHP. En se basant sur les modules existants, avec un peu de support je pense que c'est à la portée d'un débutant en programmation (on en trouve dans les clubs). Si vous n'avez aucune compétence en programation faites vous aider ou cherchez un autre programme.

Dans le future on réalisera peut-être un module de facturation générique qui cherchera à s'adapter aux règles de chaque club par configuration. Ce sera très simple à intégrer, il suffira d'écrire le module Facturation_standard.php et de configurer le club pour utiliser la facturation standard.

Si lors de la configuration d'un club, quelqu'un considère qu'il sait réaliser ce module de facturation standard, applicable à la majorité des clubs, nous serons très heureux de l'intégrer comme module par défaut. Etant donné l'imagination des présidents et trésoriers des clubs de vol à voile, je reste persuadé que l'exercise n'aura rien de trivial.

Exemple de module de facturation

Voici un exemple de module de facturation. Le principe est relativement simple:

  • La routine de facturation est appellée avec les paramètres du vol en entrée
  • On va chercher en base de données les caractéristiques du pilote
  • On va chercher en base les caractéristiques de la machine
  • On utilise les caractéristiques du vol, du pilote et de la machine pour déterminer les achats (lignes de facture) à générer. C'est à dire qu'on appelle la routine nouvel_achat_partage avec les bons paramètres.
    /**
     * Facturation d'un vol avion
     * Génère les lignes de facture correspondante.
     * @param unknown_type $vol
     * 
     * Exemple d'information qu'on trouve dans la structure $vol
     * 
     * array (
     *    'vaid' => 353,
     *    'vadate' => '2012-12-29',
     *    'vapilid' => 'fpeignot',
     *    'vamacid' => 'F-JUFA',
     *    'vacdeb' => '13.90',
     *    'vacfin' => '14.3',
     *    'vaduree' => '0.4',
     *    'vaobs' => '',
     *    'vadc' => false,
     *    'vacategorie' => '0',
     *    'varem' => false,
     *    'vanumvi' => '',
     *    'vanbpax' => '',
     *    'vaprixvol' => false,
     *    'vainst' => '',
     *    'valieudeco' => '',
     *    'valieuatt' => '',
     *    'facture' => false,
     *    'payeur' => '',
     *    'pourcentage' => '0',
     *    'club' => false,
     *    'gel' => false,
     *    'saisie_par' => 'fpeignot',
     *    'vaatt' => '1',
     *    'local' => '0',
     *    'nuit' => false,
     *    'reappro' => '0',
     *    'essence' => '0',
     *    'vahdeb' => '',
     *    'vahfin' => '',
     * )
     * 
     * Exemple d'information pilote
     * 
     * array (
     *    'mlogin' => 'fpeignot',
     *    'mnom' => 'Peignot',
     *    'mprenom' => 'Frédéric',
     *    'memail' => 'frederic.peignot@free.fr',
     *    'memailparent' => '',
     *    'madresse' => 'xxxxx',
     *    'cp' => 'xxxx',
     *    'ville' => 'xxxx',
     *    'mtelf' => '',
     *    'mtelm' => 'xxxxx',
     *    'mdaten' => '1959-08-29',
     *    'm25ans' => '0',
     *    'mlieun' => '0',
     *    'msexe' => 'M',
     *    'mniveaux' => '80128',
     *    'mbranum' => '',
     *    'mbradat' => '2010-12-11',
     *    'mbraval' => '2011-12-30',
     *    'mbrpnum' => 'VV0110001376',
     *    'mbrpdat' => '1976-09-08',
     *    'mbrpval' => '2012-10-31',
     *    'numinstavion' => '',
     *    'dateinstavion' => '0000-00-00',
     *    'numivv' => '1PIC000980',
     *    'dateivv' => '2013-10-31',
     *    'medical' => '2010-10-31',
     *    'numlicencefed' => '',
     *    'vallicencefed' => '0000-00-00',
     *    'manneeins' => '0',
     *    'manneeffvv' => '0',
     *    'manneeffa' => '0',
     *    'msolde' => '0.00',
     *    'mforfvv' => '0',
     *    'macces' => '0',
     *    'club' => '0',
     *    'ext' => '0',
     *    'actif' => '1',
     *    'username' => '0',
     *    'photo' => '',
     *    'compte' => '0',
     *    'profil' => '0',
     *    'comment' => 'Licence annuelle xxxxx1L',
     *    'trigramme' => 'PGT',
     *    'categorie' => '0',
     * )
     * 
     * Exemple d'information machine
     * 
     * array (
     *    'macconstruc' => 'AEROPOOL',
     *    'macmodele' => 'Dynamic',
     *    'macimmat' => 'F-JUFA',
     *    'macnbhdv' => '6.10',
     *    'macplaces' => '2',
     *    'macrem' => '1',
     *    'maprive' => '0',
     *    'club' => '0',
     *    'actif' => '1',
     *    'comment' => 'DY 454/2012',
     *    'maprix' => 'Heure de vol Dynamic',
     *    'maprixdc' => 'Heure de vol Dynamic',
     *    'horametre_en_minutes' => '0',
     * )
     * 
     */
    public function facture_vol_avion($vol) {

        // Cette version réalise une facturation de base. C'est à dire qu'elle établit une ligne de facture 
        // proportionnelle au temps de vol sauf en cas de vol d'essai, de vol d'initiation ou de remorqué.
        // Si cela ne vous satisfait pas il suffit de la surcharger.

        // Quelques variables pour simplifier la systaxe
        $date = $vol['vadate'];            // date du vol
        $duree = $vol['vaduree'];        // durée du vol en heure
        $machine = $vol['vamacid'];        // immatriculation de l'avion
        $vol_id = $vol['vaid'];            // identifiant du vol
        $payeur = $vol['payeur'];        // identifiant du payeur si ce n'est pas le pilote
        $pourcentage = $vol['pourcentage']; // pourcentage à la charge du payeur

        // On va chercher en base les informations suplémentaire sur le pilote,
        // l'avion, les tarifs à appliquer
        $pilote = $vol['vapilid'];
        $pilote_info = $this->CI->membres_model->get_by_id('mlogin', $vol['vapilid']);
        $machine_info = $this->CI->avions_model->get_by_id('macimmat', $machine);
        $tarif_info = $this->CI->tarifs_model->get_by_id('id', $machine_info['maprix']);
        $tarif_dc_info = $this->CI->tarifs_model->get_by_id('id', $machine_info['maprixdc']);

        // On facture la double en sus si un tarif DC existe pour l'avion
        $dc_a_facturer = ($vol['vadc'] && $tarif_dc_info['prix'] > 0) ;

        // Chaine de caractère identifiant le vol (date + machine)
        $image = $this->CI->vols_avion_model->image($vol['vaid']);

        // desc contient le commentaire qu'on affichera sur la facture
        // ce commentaire est enrichi en fonction des décisions prises pour la facturation
        $desc = $image;

        // Le vol est-il gratuit ?
        $free = FALSE;

        if ($vol['vacategorie'] == 1) {
            $desc .= " VI"; // est-ce un vol d'initiation ?
            $free = TRUE;
        } elseif ($vol['vacategorie'] == 2) {
            // est-ce un vol d'essai ?
            $desc .= " vol d'essai";
            $free = TRUE;
        } elseif ($vol['vacategorie'] == 3) {
            // est-ce un remorquage ?
            $desc .= " remorquage";
            $free = TRUE;
        }

        // Cas de base, le vol est payé par le pilote, au prix de l'heure de vol 
        // de l'avion. On génère une nouvelle ligne de facturation
        $this->nouvel_achat_partage(array (
            'date' => $date,
            'produit' => $machine_info['maprix'],
            'quantite' => ($free) ? 0 : $duree,
            'description' => $desc,
            'pilote' => $pilote,
            'machine' => $machine,
            'vol_avion' => $vol_id
        ), $pilote, $payeur, $pourcentage);

        if ($dc_a_facturer) {
            // Si il y a un surcout pour la double commande
            $this->nouvel_achat_partagee(array (
                'date' => $date,
                'produit' => $machine_info['maprixdc'],
                'quantite' => ($free) ? 0 : $duree,
                'description' => $tarif_dc_info['description'],
                'pilote' => $pilote,
                'machine' => $machine,
                'vol_avion' => $vol_id
            ), $pilote, $payeur, $pourcentage);
        }
    }