Oui bien sûr… comme je passe une partie de mon temps libre à adapter Dolibarr pour une coopérative, je n’ai pas toujours le temps de publier.
Sur la V16, la TVA d’une année me prenait 15 minutes et en général cela plantait.
Avec cette requête cela se fait en une fraction de seconde. Une seule requête (les multi-requêtes ne sont pas implémentés par $db, question de sécurité), mais un peu longue. Je l’ai testé depuis un an : pas de remarques de la comptable.
La logique :
- Reprendre la TVA à jour dans le produit s’il existe : cela permet de corriger après coup des erreurs. Cela arrive souvent, surtout dans notre contexte avec des bénévoles. Sinon, utiliser la TVA telle que renseignée dans la table facture détail.
- Faire les arrondis nécessaires
- Rq : j’ai remplacé le « . » séparateur décimal par « , ». Il faut enlever le replace si on veut conserver le « . » comme séparateur pour une compatibilité générale.
- On fait les sommes TVA 5,5%; 20%, 10%, autre TVA (cela arrive), TTC, HT, TVA tot.
- Condition : sur un mois d’une année, ou sur une année : modifier clause WHERE
- La clause WHERE se fait sur datep : la date effective du paiement. Si le paiement est en plusieurs étapes, on ne prend que ce qui a été payé.
Ici avec préfixe en dur : testable sur phpMyAdmin.
A adapter avec le préfixe bdd pour une page Dolibarr (remplacer llx_ par ‹ .MAIN_DB_PREFIX. ›
A adapter pour la période choisie (clause WHERE)
A supprimer replace (xxxxxx,‹ . ›,‹ , ›) pour intégrer dans une version générale en conservant le séparateur « . »
A part le replace « . »,« , », cela fonctionne dans les cas génériques pour la France. A adapter pour prendre en considération différents taux de TVA, mais la logique de la requête SQL unique reste la même.
$sql='
select
replace(round(sum(detail.total_ttc),2),".",",") as total_ttc,
replace(round(sum(detail.total_ht),2),".",",") as total_ht,
replace(round(sum(detail.tva),2),".",",") tva_tot,
replace(round(sum(case when detail.tva_tx=5.5 then detail.total_ht else 0 END),2),".",",") as ht_55,
replace(round(sum(case when detail.tva_tx=20 then detail.total_ht else 0 END),2),".",",") as ht_20,
replace(round(sum(case when detail.tva_tx=0 then detail.total_ht else 0 END),2),".",",") as ht_0,
replace(round(sum(case when detail.tva_tx<>0 AND detail.tva_tx<>5.5 AND detail.tva_tx<>20 then detail.total_ht else 0 END),2),".",",") as ht_autre,
replace(round(sum(case when detail.tva_tx=5.5 then detail.tva else 0 END),2),".",",") as tva_55,
replace(round(sum(case when detail.tva_tx=20 then detail.tva else 0 END),2),".",",") as tva_20,
replace(round(sum(case when detail.tva_tx=0 then detail.tva else 0 END),2),".",",") as tva_0,
replace(round(sum(case when detail.tva_tx<>0 AND detail.tva_tx<>5.5 AND detail.tva_tx<>20 then detail.tva else 0 END),2),".",",") as tva_autre,
replace(round(sum(case when detail.tva_tx=5.5 then detail.total_ttc else 0 END),2),".",",") as ttc_55,
replace(round(sum(case when detail.tva_tx=20 then detail.total_ttc else 0 END),2),".",",") as ttc_20,
replace(round(sum(case when detail.tva_tx=0 then detail.total_ttc else 0 END),2),".",",") as ttc_0,
replace(round(sum(case when detail.tva_tx<>0 AND detail.tva_tx<>5.5 AND detail.tva_tx<>20 then detail.total_ttc else 0 END),2),".",",") as ttc_autre
from (
SELECT distinct f.ref as ref_fact,
fd.total_ttc as total_ttc,
fd.total_ht as total_ht,
CASE WHEN NOT ISNULL(pr.ref) THEN pr.tva_tx ELSE fd.tva_tx END as tva_tx,
CASE WHEN NOT ISNULL(pr.ref) THEN fd.total_ttc - (fd.total_ttc / (1 + (pr.tva_tx / 100)))
WHEN ISNULL(pr.ref) THEN fd.total_tva
END as tva,
fd.rowid as id_fd
from llx_paiement as p inner join llx_paiement_facture as pf on pf.fk_paiement=p.rowid
inner join llx_facture as f on f.rowid=pf.fk_facture
inner join llx_facturedet as fd on fd.fk_facture=f.rowid
left join llx_product as pr on pr.rowid=fd.fk_product
WHERE year(p.datep)='.$annee.' AND month(p.datep)='.$i.' AND f.paye=1
) as detail;
';
(Rq : je ne comprend pas pourquoi dans Dolibarr les requêtes sont écrites avec des « $sql .= … » pour chaque ligne. C’est plus difficile à lire et plus difficile à tester dans phpMyAdmin si on n’a pas xdebug en version locale)