Manipulation prix ttc,ht, float, decimal etc...

ViPHP
ViPHP | 3607 Messages

05 oct. 2010, 16:36

Bonjour à tous,

Je cherche actuellement comment faire pour rendre mon système de paiement le plus précis possible, afin d'avoir les même prix partout, de garder de la précision etc...
En gros les prix sont aujourd'hui établis sur du TTC. jusque là pas de problème, en général ce ne sont que des entiers.

Seulement, je dois déclarer la TVA donc avoir aussi le prix HT et/ou la TVA (ex sur un produit à 30€ TTC, il faut que je fasse figurer les 25,0836€ HT ou les 4,9164€ de TVA)

S'ajoute à cela le fait que j'ai des commandes comportant plusieurs produits, donc une somme de TTC, une somme de HT, une somme de TVA...

Forcément, il y a des imprécisions, je ne vais pas afficher 4,91638796€ de TVA au client...

Donc plusieurs questions:
  • je suppose qu'il faut stocker le maximum de chiffres après la virgule dans la bdd (en restant raisonnable), pour cela FLOAT? DECIMAL?
  • où faire mes arrondis? seulement à l'affichage, et de partout ailleurs je garde toutes mes virgules?
  • Comment faire mes calculs? prenons un exemple d'une commande comportant 3 produits:
    • produit 1 à 20€ TTC
    • produit 2 à 15€ TTC
    • produit 3 à 40€ TTC
    je vais avoir ce tableau-là:

    Code : Tout sélectionner

    ID | HT | TTC 1 | 16,72 | 20 2 | 12,54 | 15 3 | 33,44 | 40
    Comment afficher le total pour ne pas avoir d'imprécisions?
    TOTAL HT = HT1+HT2+HT3 ou
    TOTAL_HT = TOTAL_TTC / 1.196 ?
Bon je sens bien que ce n'est pas très clair, mais c'est pareil dans ma tête :-°
Je suis preneur de tout conseils sur ces points ;)

Merci d'avance!

ViPHP
xTG
ViPHP | 7331 Messages

05 oct. 2010, 17:16

C'est un prix calculable non ?
Donc dans la méthode on ne le stocke pas, on stocke les informations permettant de refaire le calcul (dont la TVA à l'instant t).
Et quand tu en as besoin ailleurs tu le recalcules à partir des informations enregistrées.

Ainsi tu n'as des arrondis qu'à l'affichage et dans tous les calculs possibles tu garde la meilleure précision possible.

Mammouth du PHP | 1511 Messages

07 oct. 2010, 13:31

Je ne stockerais que le prix HT pour ma part...
Sachant que la TVA ne varie pas, rien ne sert de stocker deux données.

Eléphant du PHP | 314 Messages

07 oct. 2010, 13:37

je ne sais pas tu gères quel type de services mais t'as une TVA a 19.6 et une à 5.5%

Le mieux est de stocker en base les prix HT, et d'associer un taux qui se trouve dans une autre table, comme ça si un jour tu veux faire une offre TVA Offerte, tu auras juste à creer une TVA à 0% et l'associer au produit :D
Cordialement,
Julien - http://laravel.fr/

ViPHP
ViPHP | 3607 Messages

07 oct. 2010, 14:37

Bonjour,

Je suis en train de modifier le tout pour ne stocker que le prix HT...
Par contre je suis obligé de stocker le taux de TVA, car bien que nous soyons à 19.6 de partout, pour les clients européens (hors france), on ne doit pas leurs faire payer la TVA, et ils doivent (théoriquement) la payer chez eux.
Du coup les taux sont différents selon les pays.
Et comme je me dois de faire apparaitre le détail dans les factures ;)

Du coup je me retrouve pour l'instant avec des prix hors taxes en base. Par contre j'ai mis FLOAT comme type, et lorsque j'entre un prix le plus précis possible: 24.247491639
il enregistre seulement 24.2475... Donc sachant que je n'ai pas besoin non plus d'énorme précision, est-ce qu'un type DOUBLE suffirait? (pour l'instant les arrondis ont l'air de bien se comporter, et je retombe bien exactement sur mes prix TTC, mais j'aimerais quand même avoir plus de marge (pour l'exemple avec le produit à 29€ TTC, après calculs, je tombe à 29,00001€ sans arrondir, donc pour un peu que je gonfle les prix, la virgule va se déplacer ;) )

ViPHP
xTG
ViPHP | 7331 Messages

07 oct. 2010, 14:48

Quel est ce flottant que tu tentes de stocker ? Cela me semble bizarre de stocker une telle chose.
Est-ce le prix de ton produit ?
Pour moi cela ressemble plutôt à un prix après application de la TVA.

ViPHP
ViPHP | 3607 Messages

07 oct. 2010, 14:53

Vu que je stocke finalement seulement les prix HT...
Mais qu'a l'affichage (sauf cas de personnes européennes, etc...) j'affiche un total TTC et que la grille des prix a été faite sur du TTC, ce sont ces derniers qui sont "rond".

Du coup pour mon produit à 29€ TTC (parce que la pub est comme ça, que les prix sont comme ça pour l'instant, etc...), le prix que vais stocker dans ma bdd et 29/1.196...
Voilà pourquoi je cherche un peu de précision ;)

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 oct. 2010, 15:21

D'un point de vue comptable, la norme est de ne stocker que des prix tronqués à 2 chiffres après la virgule.
Exemples :

Code : Tout sélectionner

12,3€ => 12.34€ 12,34€ => 12,34€ 12,341€ => 12,34€ 12,345€ => 12,34€ 12,349€ => 12,34€
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
ViPHP | 3607 Messages

07 oct. 2010, 15:36

Aie aie aie...
Je ne sais pas trop comment faire, en fait je stocke pour l'instant tout les prix en HT avec pleins de virgule dans la base, mais pour tout les affichages, j'arrondis au centième (que ce soit pour les utilisateurs, pour les documents comptables, les factures etc...)
J'ai pris le partit de stocker suffisamment de précision pour ne pas avoir à leur faire une facture avec un TTC de 289,99€.
En sachant que la majorité des clients payent le TTC et que seul un minorité paye le HT...

J'avoue que je suis un peu perdu... je regarde un peu partout et je vois que chez certains, c'est le HT qui est "rond" par exemple chez gandi:
Nom de domaine
testeuh.at (1 an)
18,00 €
Total HT 18,00 €
Total TTC 21,53 €
Donc ben la question reste entière :/

Merci encore!

Eléphant du PHP | 314 Messages

07 oct. 2010, 15:53

- Quand on s'adresse à Mr Tout le monde, c'est TTC, donc on adapte le HT pour qu'il soit beau à voir une fois en TTC.
- Quand on s'adresse à des pros, c'est HT, donc le TTC importe peu.
Cordialement,
Julien - http://laravel.fr/

Mammouth du PHP | 661 Messages

07 oct. 2010, 16:05

dans l'absolue, je dirais que tu devrais te concentrer sur ce que tu peux maitriser : le HT et la TVA à l'instant T !..

1. tu stockes tes produits HT
2. tu les joins à un taux de TVA lors de la vente (ou de toutes présentation)
3. lors d'une vente tu enregistre le montant HT de la vente et le montant de la TVA (ce sera plus pratique pour vérifier ta compta ensuite)

le TTC, tu t'en fou !... c'est commercial, mais ça n'a aucun intérêt pour toi, vu que le TVA c'est pas pour toi !

Ensuite, tu fais tes prix à 2 ou 3 chiffres après la virgule (comme le carburant ^^)
lorsque tu le présente tu réduit à deux chiffres (avec ou sans TVA) et si ses 2 chiffres sont 00, tu les vires ^^

Ainsi dans ton exemple, 29,0001 ... ben c'est 29€ ^^
comme ça si un jour tu veux faire une offre TVA Offerte, tu auras juste à creer une TVA à 0% et l'associer au produit
Heu .... ça c'est un argument commercial, en réalité il y a ne réduction de 19.6% ... par ce que je ne suis pas certain que les impots accepte que tu ne les payent pas même si tu ne revend pas leurs taxe, ils se foutent de ce que tu fait, ils veulent leur pognon ;)

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 oct. 2010, 16:40

Je pense que, tout le monde ici, doit prendre conscience que les règles comptable sont transposables aux SI (systèmes informatiques) et que ce n'est pas au développeur de faire ce qu'il veut avec.

Je pourrais passer des heures à lister des règles, mais voici celles qui me semblent importantes :
  • Toujours stocker les montant facturés. Un montant facturé est le résultat d'un calcul. Ce calcul peut évoluer à travers le temps, il est donc important de stocker le montant exact facturé pour que tout réédition soit toujours exacte.
  • la règle comptable est de tronquer à 2 décimales, comme dans mon exemple (12.349999999€ => 13,34€)
  • Dans tout les cas, il faut stocker le montant HT, le montant de TVA appliquée pour pouvoir justifier de ce que l'on a vendu
Ensuite, à toi de faire avec ces règles, pour voir si elles te permettent de structurer ton application ou non (si tu dois pouvoir sortir des chiffres pour la déclaration de TVA ou pas, par exemple)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
ViPHP | 3607 Messages

07 oct. 2010, 16:48

Merci pour toutes ces précisions!

Juste pour demander un peu plus, quand tu dis
Dans tout les cas, il faut stocker le montant HT, le montant de TVA appliquée pour pouvoir justifier de ce que l'on a vendu
Tu parles Du taux de TVA (ex: 19.6%) ou de la valeur en monnaie correspondante?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 oct. 2010, 18:12

La valeur en monnaie correspondante.

Si jamais tu dois pouvoir sortir des chiffres de ton application, il ne faut pas recalculer ce que tu as fait payer, mais sortir exactement ce que tu as mis sur sa facture.
La solution de stocker le montant HT et le montant de la TVA est donc plus que conseillé.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
ViPHP | 3607 Messages

11 oct. 2010, 13:07

Salut à tous,

Je poursuis les changements en fonctions des précieux conseils de zeus (merci), petit à petit, je vous tiendrais au courant lorsque ça sera finit!

En attendant j'ai un petit soucis par rapport au "tronquage" des flottants...
Soit j'ai la berlu, soit il n'existe pas de fonction native à php permettant de tronquer un nombre à virgule en précisant la précision (... hum hum...)

Il n'y a que floor mais qui ne retourne que des entiers...
donc j'ai fait la fonction suivante:
function truncate_float($f_number,$i_precision=2){

  $s_multi = '1';
  for($i=0;$i<$i_precision;$i++){
    $s_multi.='0';
  }

  $i_tmp = floor($f_number*$s_multi);

  return $i_tmp / $s_multi;
}
Donc si vous avez mieux codé au encore mieux la fonction native, je suis preneur ;)

Merci d'avance!