IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Gestion numéro de facture [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre éclairé
    Inscrit en
    Décembre 2006
    Messages
    411
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 411
    Par défaut Gestion numéro de facture
    Bonjour,

    Je cherche une solution à un problème qui est sans doute simple mais je n'y trouve pas de solution
    Je veux générer des numéros de facture (donc unique) tel que F09030001
    F pour Facture
    09 pour l'année 2009
    03 pour le mois de mars
    0001 un numéro unique indiquant le numéro de facture dans le mois, ici présent c'est la première du mois de mars
    J'aimerais sachant celà générer un numéro de facture de ce type lors d'un paiement en ligne
    Si quelqu'un aurait une idée je suis preneur
    Merci d'avance

  2. #2
    Membre très actif Avatar de myz-rix
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Ariège (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 143
    Par défaut
    bonjour,

    Je te propose ceci, tu commence par génerer ton entete
    FYYMM exemple F0902 ou F0903... à partir donc du mois et de l'année.

    Ensuite tu fait une boucle de 1000 à 9000 (je te conseil de commencer à 1000 au lieu de 0001 c'est plus simple)
    donc $i ton chiffre qui s'incrémente à partir de 1000.
    Cette boucle va tester dans ta base si il existe une facture du nom de:
    FYYMM + $i exemple
    F09031000 => test si existe => non
    F09031001 => test si existe => non
    F09031002 => test si existe => oui
    hop tu coupe la boucle et tu as ton numéro de facture

    c'est expliqué simplement, à toi de le programmer maintenant
    entre nous, une facture avec un simple numéro de 1000000 à 9000000 attribué aléatoirement et hop personne sait combien tu fais de facture par an

    Ensuite dans ton cas, je sais pas le commerce en question mais tu te limites à 9000 facture par mois, faut le savoir

  3. #3
    Membre éclairé
    Inscrit en
    Décembre 2006
    Messages
    411
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 411
    Par défaut
    Il y a beaucoup plus simple que çà je pense c'est clair parce que la boucle de 1000 à 9000
    mysql gère les valeurs incrémentales uniques (champ autoincrément) déjà c'est une piste je pense

  4. #4
    Membre chevronné Avatar de defcon_suny
    Homme Profil pro
    Non pas trop...
    Inscrit en
    Décembre 2006
    Messages
    441
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Non pas trop...
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 441
    Par défaut
    Ben oui en effet! il y a plus simple!
    Mysql gère cela très bien...

    Voici un modèle de table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    CREATE TABLE IF NOT EXISTS `facture` (
      `id` int(4) unsigned zerofill NOT NULL AUTO_INCREMENT,
      `numero` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;
     
    --
    -- Contenu de la table `facture`
    --
     
    INSERT INTO `facture` (`id`, `numero`) VALUES
    (0001, 'F09030001'),
    (0002, 'F09030001'),
    (0003, 'F09030001'),
    (0004, 'F09030001');
    Le champ id est entier auto_increment de 4 avec comme attribut unsigned zerofill. Ce qui créera automatiquement un numéro incrémenté au format 0001,0002,0003,...

    voilà voilà
    ++

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2009
    Messages : 28
    Par défaut
    Heuu bravo pour les reponses mais c'est plus complique que ca, son numero doit revenir a 1 chaque mois (du moins je suppose, sinon au moins par an), donc avec l'auto_increment il va jouir.


    La solution est tout autre, il faut une table dans laquelle se trouve le dernier numero de facture sur la periode demandee. (donc avec comme cle par exemple '200903')

    Et la tu dois faire une routine qui va te chercher le dernier numero, et ensuite fait l'update dans la table.

    Maintenant comme ca, ca a l'air simple mais c'est pas encore fini, il faut tenir compte des acces concurentiels sur la table, donc que se passe t'il si 2 personnes font une demande en meme temps ???

    Pour ca il y a une solution, tu dois locker la table

    Voici un exemple pour faire ce genre de procedure :

    mysql_query("lock table cntnum write");
    mysql_query("update cntnum set number=number+1 where type='$type'");
    $q = mysql_query("select * from cntnum where type='$type'");
    $r = mysql_fetch_array($q);
    mysql_query("unlock tables");
    return sprintf("%s%05d",$r["seq"],$r["number"]);

  6. #6
    Membre chevronné Avatar de defcon_suny
    Homme Profil pro
    Non pas trop...
    Inscrit en
    Décembre 2006
    Messages
    441
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Non pas trop...
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 441
    Par défaut
    Ah bien vu chromo!!!

    Es tu d'accord avec ce gnre de structure de table pour éviter le problème de l'auto_increment?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    CREATE TABLE IF NOT EXISTS `facture` (
      `an` year(4) NOT NULL,
      `mois` int(2) unsigned zerofill NOT NULL,
      `numero` int(4) unsigned zerofill NOT NULL,
      `montant` decimal(6,2) NOT NULL,
      PRIMARY KEY (`an`,`mois`,`numero`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    --
    -- Contenu de la table `facture`
    --
     
    INSERT INTO `facture` (`an`, `mois`, `numero`, `montant`) VALUES
    (2009, 03, 0001, '30.85'),
    (2009, 03, 0002, '65.23');
    ++

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2009
    Messages : 28
    Par défaut
    Non pas trop, ca complique les affichages et recherches sur numeros de facture.

    Non en fait il faut 2 tables, une contenant seulement le dernier numero de facture du genre

    type char(3)
    number int
    seq varchar(10)

    Le type permet de definir d'autre systeme de numero de sequence, par exemple pour les bons de commande, les devis, les factures, ...
    Le seq contient la partie fixe du numero, donc la racine (200903 par exemple)
    Et number le dernier numero pour ce type;

    Et une autres pour les factures.

    Ensuite dans la table des factures tu stockes le numeros dans un varchar par exemple.

  8. #8
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 3
    Par défaut
    Moi j'ai trouvé une solution (je parle en même temps au telephone avec l'intéressé)

    Il a une table avec cette structure :
    nom de la table : factures
    Id (en autoincrement)
    num_facture
    date (en timestamp)

    mon systeme marche même avec plusieurs personnes de connectées
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $facture = date("\Fym");// génération d'une facture du type F0903
    mysql_query("INSERT INTO factures VALUES ('','$facture','".time()."');");//on insere une facture avec un numero pré rempli
    $id_actuel = mysql_insert_id(); //cette valeur est toujours correcte même si d'autres insertions on lieu en même temps
    $debut_mois = mktime(0,0,0,date("n"),1,date("Y"));//génération du timestamp du début du mois actuel
    $sql = "SELECT COUNT(*) AS nb FROM factures WHERE date<".$debut_mois;//ce truc la va compter le nombre de factures éditées AVANT le mois en cours
    $reponse = mysql_query($sql);
    $data = mysql_fetch_array($reponse);
    $nb_fac = $data['nb'];
    //ensuite on va faire une simple soustraction
    $new_id = $id_actuel - $nb_fac;
    /*
    Un exemple pour illustrer :
    L'auto increment vaut 57, et on est en février, en janvier il y avait déja eu 46 factures, donc cette facture ci, vaut 57-46 = 11, et c'est bien la 11eme facture du mois de février
    */
    mysql_query("UPDATE factures SET num_facture = CONCAT(num_facture, '$new_id') WHERE Id = $id_actuel");//on met a jour le numero de facture
    Qu'en pensez vous ?

  9. #9
    Membre chevronné Avatar de defcon_suny
    Homme Profil pro
    Non pas trop...
    Inscrit en
    Décembre 2006
    Messages
    441
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Non pas trop...
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 441
    Par défaut
    Effectivement chromo, après une réflexion plus approfondie, ton système me paraît plus pertinent.

    Je prends bonne note

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2009
    Messages : 28
    Par défaut
    J'aime pas trop pour plusieurs raisons :

    1. Tu risques de te retrouver avec des factures sans numero si l'update se plante. En principe l'insert doit etre complet ca evite les problemes
    2. Ton systeme sous entend que l'on ne fera jamais aucun delete dans la table. Ca c'est pas sur, il suffit par exemple de faire une manipulation a la main (pour recupere un backup par exemple) pour que la sequence soit rompue
    3. Et comment gerer les suppressions de factures ? En theorie on ne peut pas, mais il arrive parfois que l'on fasse se genre de manip suite a un probleme
    4. Ca necessite que l'on encode de facon chronologique les factures, et en debut d'exercice il arrive qu'on encode encore des factures de la période précédente. Donc tu aurais par exemple
    serial numero reel
    1 2008120001
    2 2008120002
    3 2009010001
    4 2008120003 /*Pour celle-ci t'a un soucis*/

  11. #11
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 3
    Par défaut
    Citation Envoyé par chromo Voir le message
    4. Ca necessite que l'on encode de facon chronologique les factures, et en debut d'exercice il arrive qu'on encode encore des factures de la période précédente. Donc tu aurais par exemple
    serial numero reel
    1 2008120001
    2 2008120002
    3 2009010001
    4 2008120003 /*Pour celle-ci t'a un soucis*/
    Ou est le soucis ?
    Et non, il n'y aura pas de factures de la période précédente a mon avis ...

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2009
    Messages : 28
    Par défaut
    Le soucis vient du faite que tu es obliger d'avoir les serials ET les dates qui se suivent dans ta procedure.
    Et il est tout a fait possible d'avoir ce cas. Principalement en fin d'annee, ou les clients souhaite parfois avoirs les factures sur l'ancien exercice comptable pour des raisons de deduction fiscale.

    Sinon pour ton soucis voici un exemple

    Serial-Numero-Ton numero-id_actuel-nb_fac-new_id
    1-2009010001-2009010001-1-0-1
    2-2009010002-2009010002-2-0-2
    3-2008120001-2008120003-3-0-3 /*Et la tu t'es fait avoir*/

  13. #13
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 3
    Par défaut
    Citation Envoyé par chromo Voir le message
    Sinon pour ton soucis voici un exemple

    Serial-Numero-Ton numero-id_actuel-nb_fac-new_id
    1-2009010001-2009010001-1-0-1
    2-2009010002-2009010002-2-0-2
    3-2008120001-2008120003-3-0-3 /*Et la tu t'es fait avoir*/
    Hum, si je suis ton exemple, avec mon systeme ca génèrerai 2008120003 pour la 3eme facture ?
    Hum, son truc des factures est généré automatiquement (a ce que j'ai compris au téléphone) donc a mon avis y'aura jamais ce cas la ...

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2009
    Messages : 28
    Par défaut
    Peut-etre mais dans le doute vaut mieux mettre en place une solution qui fonctionne dans tous les cas. C'est plus sur et pas plus complique.

  15. #15
    Membre éclairé
    Inscrit en
    Décembre 2006
    Messages
    411
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 411
    Par défaut
    deux tables oui en effet c'est sans doute le mieux
    je propose une idée mais bon après faudrait voir
    une table facture avec un varchar contenant le numéro de facture çà c'est ok
    une autre avec un champ année, un champ mois, un autre champ pour stocké le F et un autre pour le numéro
    Donc :
    F 09 03 1

    mais bon je ne voudrais pas faire de LOCK TABLES (dont le but est d'éviter les accès concurrentiels)
    Soit je génère un numéro de facture unique je locke j'insère dans ma table facture et je délocke
    peut-on faire celà avec une seule requête mysql ?

  16. #16
    Membre éclairé
    Inscrit en
    Décembre 2006
    Messages
    411
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 411
    Par défaut
    Personne ne voit une solution afin de générer un numéro automatique et UNIQUE et celà même en cas de connexion simultanée sans utiliser LOCK TABLE ???
    En fait l'idée serait pour simplifier au maximum :
    de générer d'abord le numéro de facture
    ensuite le récupérer et l'insérer avec la facture dans la table des factures
    Le plus compliqué est de générer ce numéro unique :
    Exemple :
    On est le 21 Mars je paie en ligne et celà génère la facture
    on récupère en php le mois et l'année soit 09 pour l'année et 03 pour le mois
    on a une ligne dans l'autre table tel que :
    Année Mois numéro
    09 02 400
    09 03 255

    Celà signifie qu'à ce jour on a 255 factures pour le mois de mars 2009 (400 pour le mois de Février) et que la prochaine facture sera donc la 256
    Avec celà pourrait générer une requête dans cette table qui permettent d'insérer une nouvelle ligne si première facture du mois ou de mettre à jour la ligne en ajoutant un au numéro (sachant que dans ce cas il faudra récupérer ce numéro par la suite)
    Il existe insert on duplicate keys update qui ferait une chose similaire et qui permet de gérer les connexions simultanées car une seule requête est réalisé
    Merci de votre aide

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2009
    Messages : 28
    Par défaut
    Ta seconde table me semble un peu complique, tu aurais pu mettre directement la concatenation de tes champs dans un seul, et le numero dans un autre, donc
    F09031 + 1 (avec le 1 qui s'incremente evidement)
    C'est beaucoup plus simple que de le splitter dans plusieurs champs, deja pour l'index, et ensuite pour tes requetes.

    Mais pour le fait de tout faire en une seule requete c'est pas possible. Et le lock table ne pose pas de probleme, il met simplement en attente les autres requetes sans pour autant generer d'erreur, ni les planter.

  18. #18
    Membre éclairé
    Inscrit en
    Décembre 2006
    Messages
    411
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 411
    Par défaut
    ok je mets le tag RESOLU car je vais appliquer la méthode la plus simple avec LOCK TABLE et finalement je locke juste la table des factures je récupère le max des numéros de facture du mois en cours, j'ajoute un et j'affecte dans ma table facture la nouvelle facture et je délocke FACILE en fait
    Merci de votre aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Numéro de facture
    Par edophie dans le forum SharePoint
    Réponses: 8
    Dernier message: 10/07/2008, 22h58
  2. Incrémentation du numéro de facture
    Par Toison dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 23/05/2008, 15h09
  3. Création d'un numéro de Facture
    Par chelmi95 dans le forum IHM
    Réponses: 2
    Dernier message: 23/04/2008, 11h23
  4. Création d'un numéro de Facture
    Par chelmi95 dans le forum VBA Access
    Réponses: 6
    Dernier message: 18/06/2007, 17h49
  5. numéro de facture
    Par Polux95 dans le forum Excel
    Réponses: 4
    Dernier message: 04/04/2007, 11h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo