sopheos / pebble_cart
Shopping cart totals (HT/TTC) with French VAT rules
Requires
- php: >=8.1.0
- sopheos/pebble_models: ^1.0
Requires (Dev)
- phpunit/phpunit: ^9.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Calcul des totaux d'un panier (HT, TTC, TVA par taux) avec les règles de TVA françaises : métropole, DOM, Union européenne (intracommunautaire ou non) et export.
La lib ne gère ni la persistance, ni les remises, ni les frais de port. Elle n'arrondit pas les montants au centime : c'est à l'appelant de le faire (voir TODO.md).
Installation
composer require sopheos/pebble_cart
Claude Code
Ce package fournit un skill Claude Code dans skills/pebble-cart/. Il documente les patterns d'usage et les pièges de la librairie : prix HT ou TTC selon is_ttc, ttc à 0 quand aucune TVA ne s'applique, montants non arrondis, total fourni jamais recalculé, codes pays sensibles à la casse, etc.
Dans un projet qui dépend de sopheos/pebble_cart, copie-le une fois dans .claude/skills/ après composer install pour que Claude Code le charge automatiquement. Le nom du dossier doit correspondre au name déclaré dans SKILL.md :
cp -r vendor/sopheos/pebble_cart/skills/pebble-cart .claude/skills/pebble-cart
Pour la maintenance de la lib elle-même, voir CLAUDE.md. Les bugs connus sont listés dans TODO.md.
CartData
\Pebble\Cart\CartData étend \Pebble\Models\ModelAbstract. Le total est calculé à la construction, sauf si une clé total est fournie.
Propriétés :
is_btbClient professionnel (défautfalse).is_ttcLes prix des lignes sont TTC (défauttrue) ou HT.is_intracoClient professionnel UE avec numéro de TVA intracommunautaire (défautfalse).countryCode pays ISO en majuscules (défaut'FR').itemsLignesCartItemData(les tableaux sont convertis à l'import).totalRésultatCartTotalData.mentionsMentions d'exonération à imprimer sur la facture, sans doublon.
Méthodes :
__construct(array $data = [])Importe les données puis calcule le total.import(array $data = []) : staticConvertititemsettotal, puis recalcule le total sitotaln'est pas fourni.total() : staticRecalculetotaletmentions. À appeler après avoir modifié une propriété directement.getTaxValue(CartItemData $item) : arrayRenvoie[taux, mention|null]pour une ligne selon le client et le pays.getAmount() : floatMontant à encaisser :ttc, ouhtsittcvaut 0.export() : arrayExport tableau (hérité), réimportable tel quel.
Constantes : codes de taux NO_RATE, NORMAL_RATE, INTERMEDIATE_RATE, REDUCED_RATE, SPECIAL_RATE (libellés dans RATE_LANG), unités DAYS_UNIT/HOURS_UNIT (libellés dans UNITS), tables TVA_METRO, TVA_DOM, TVA_EXO, listes de pays EU et DOM.
use Pebble\Cart\CartData; $cart = new CartData([ 'is_ttc' => false, 'items' => [ ['label' => 'Formation', 'quantity' => 2, 'price' => 450, 'unit' => CartData::UNITS[CartData::DAYS_UNIT], 'taxe' => CartData::NORMAL_RATE], ], ]); $cart->total->ht; // 900 $cart->total->ttc; // 1080 $cart->total->tva; // ['0.2' => 180] $cart->getAmount(); // 1080
Règles de TVA
| Client | Pays | Services | Biens |
|---|---|---|---|
| Professionnel | FR, MC |
métropole | métropole |
| Professionnel | GP, MQ, RE |
DOM | exonéré (art. 294) |
| Professionnel | GF, YT |
exonéré (art. 294) | exonéré (art. 294) |
| Professionnel | UE, is_intraco |
exonéré (art. 283-2) | exonéré (art. 262-2) |
| Professionnel | UE sans is_intraco |
métropole | métropole |
| Professionnel | autre | exonéré (art. 283-2) | exonéré (art. 262-1) |
| Particulier | FR, MC |
métropole | métropole |
| Particulier | DOM | métropole | exonéré (art. 294) |
| Particulier | UE | métropole | métropole |
| Particulier | autre | métropole | exonéré (art. 262-1) |
La TVA est calculée sur le total de chaque taux, pas ligne par ligne. Quand aucune TVA ne s'applique, total->ttc vaut 0 : utiliser getAmount().
CartItemData
\Pebble\Cart\CartItemData décrit une ligne.
labelDésignation.quantityQuantité. Une ligne à 0 est ignorée.pricePrix unitaire, HT ou TTC selonCartData::$is_ttc.unitUnité libre (par exempleCartData::UNITS[CartData::HOURS_UNIT]).taxeCode de taux (CartData::NORMAL_RATE…). Un code inconnu vaut un taux de 0.is_serviceService (défauttrue) ou bien.
CartTotalData
\Pebble\Cart\CartTotalData porte le résultat.
ttcTotal TTC (0 si aucune TVA).htTotal HT.tvaMontant de TVA par taux, la clé est le taux en chaîne ('0.2','0.055').total_tvaSomme des TVA.
Tests
composer install vendor/bin/phpunit
Les bugs connus sont figés par des tests annotés // BUG: qui vérifient le comportement actuel.