Files
tradon/modules/purchase_trade/AGENTS.md
2026-04-02 17:28:44 +02:00

7.2 KiB

AGENTS.md - Module purchase_trade

Ce guide complete le AGENTS.md racine. Pour ce module, les regles locales ci-dessous priment.

1) Perimetre metier

Le module purchase_trade etend les flux achat/vente Tryton avec une logique de negoce physique:

  • contrats d'achat (purchase.purchase, purchase.line)
  • contrats de vente (sale.sale, sale.line)
  • lots physiques et virtuels
  • matching achat/vente
  • shipments et execution logistique
  • frais (fee.fee)
  • templates de documents metier et facture

2) Fichiers pivots

  • Contrats achat:
    • modules/purchase_trade/purchase.py
  • Contrats vente:
    • modules/purchase_trade/sale.py
  • Lots / matching / invoicing:
    • modules/purchase_trade/lot.py
  • Shipments / lien facture-lot:
    • modules/purchase_trade/stock.py
  • Fees:
    • modules/purchase_trade/fee.py
  • Bridge facture / templates:
    • modules/purchase_trade/invoice.py
  • Vues:
    • modules/purchase_trade/view/*.xml
  • Actions module:
    • modules/purchase_trade/*.xml
  • Manifest:
    • modules/purchase_trade/tryton.cfg

3) Documentation locale a lire en priorite

  • Regles metier:
    • modules/purchase_trade/docs/business-rules.md
  • Regles templates:
    • modules/purchase_trade/docs/template-rules.md
  • Catalogue des proprietes templates:
    • modules/purchase_trade/docs/template-properties.md

4) Invariants metier a preserver

  • Un lot virtual est la reference d'ouverture de quantite pour une purchase.line.
  • Une sale.line doit aussi avoir au minimum un lot virtual; une valuation cote sale ne doit donc pas disparaitre juste parce que le lot est open.
  • Le lot physique est le pont principal entre:
    • purchase.line
    • sale.line
    • shipment
    • facture
  • Pour remonter d'une facture vers shipment / BL / controller / fret:
    • privilegier le lot physique
    • ne pas multiplier des chemins d'acces concurrents
  • Pour les champs de colis (NB BALES) dans les templates facture:
    • la source de verite est line.lot.lot_qt
    • sur une facture, sommer les lot_qt des lignes de facture
    • tenir compte du signe de la ligne de facture pour les notes finales
    • ne pas proratiser depuis le poids (net / gross)
  • Le FREIGHT VALUE d'un template facture vient du fee.fee du shipment dont le produit est Maritime freight.
  • Le wizard Create contracts en mode matched peut maintenant partir de plusieurs lot.qt, mais doit conserver un matching par lot source et laisser created_by_code = True sur les lignes creees pour ne pas declencher les creations automatiques de lots dans les validations.
  • En valuation / PnL:
    • la valeur stockee dans type est la cle technique (pur. priced, sale priced, pur. fee, etc.), pas le label affiche dans l'UI
    • les references doivent rester coherentes avec le type de lot: Purchase/Open, Purchase/Physic, Sale/Open, Sale/Physic
    • pour une sale matchee, les lignes de valuation purchase generees sur un lot physique doivent aussi renseigner sale et sale_line afin de remonter dans l'onglet PnL de la sale
    • une sale non matchee doit etre valorisable "sale-first" et alimenter valuation.valuation / valuation.valuation.line
    • si une sale.line basis n'a ni price_summary ni lot_price_sale, creer quand meme une ligne sale priced avec price = 0 et amount = 0 plutot que de ne rien generer
    • le MTM ne doit etre renseigne que pour pur. priced, sale priced et derivative; jamais pour les fees
    • mtm_price doit afficher le prix brut de valorisation (sans ratio), alors que mtm reste le montant calcule selon la logique de strategie
  • En pricing:
    • le unit_price doit rester un prix de base, hors premium
    • le premium doit impacter le prix total economique et donc le amount, aussi bien en priced qu'en basis
    • pour les documents commerciaux / facture, une ligne basis affiche le premium comme prix visible, pas le prix economique total
    • si linked currency est active, le premium est saisi dans la devise / unite liee (ex: USC/LB) puis converti vers le repere de la ligne pour le calcul du amount
    • en basis + linked currency, le linked_price doit representer le prix basis brut (hors premium) dans la devise liee; le unit_price reste ce prix brut converti, et le premium converti est ajoute seulement dans l'amount
    • si linked currency est cochee, linked_price, linked_currency et linked_unit sont requis
    • dans les forms, presenter le bloc prix dans l'ordre: price_type -> linked fields -> premium -> unit_price -> amount
    • en valuation basis, le premium s'applique a chaque composant, pas uniquement a une ligne de resume
    • pour une ligne basis sans price_summary, la valuation fallback doit utiliser unit_price + premium (et pas unit_price seul)
    • a la validation d'une sale.line, si un lot virtuel est cree et qu'aucun matching purchase n'existe, il faut lancer generate_from_sale_line() pour alimenter le PnL sale-first

5) Conventions de modification

  1. Modifier la logique metier dans le fichier pivot le plus proche.
  2. Si un template .fodt devient complexe, deplacer la logique dans une propriete Python report_*.
  3. Pour une facture trade, preferer enrichir modules/purchase_trade/invoice.py plutot que surcharger lourdement le .fodt.
  4. Si une regle metier durable change, mettre a jour docs/business-rules.md.
  5. Si une convention de template change, mettre a jour docs/template-rules.md.
  6. Pour les vues XML Tryton de ce module, utiliser editable="1" sur les <tree> editables; ne pas utiliser editable="bottom".
  7. Si une regle de texte par defaut durable est demandee sur achat/vente, preferer un singleton de configuration expose dans un menu fonctionnel existant plutot qu'un menu technique purchase_trade.

6) Pieges connus

  • Plusieurs actions de report account.invoice peuvent sembler rendre le meme document a cause du cache invoice_report_cache.
  • Les reports alternatifs (Final Invoice, Prepayment, etc.) ne doivent pas reutiliser le cache du report standard sans verification.
  • Pour les donnees achat/vente partagees, ne pas supposer qu'une facture de vente doit lire directement sur la sale.line: souvent, la verite metier passe par le lot physique et/ou la account.invoice.line.
  • Les templates invoice_ict* peuvent partager les memes proprietes Python; si une regle doit valoir pour provisional et final, la mettre dans modules/purchase_trade/invoice.py plutot que dupliquer dans les .fodt.
  • Dans les ecrans PnL, le label Sale price correspond au type stocke sale priced; idem pour Pur. price / pur. priced.
  • Une ligne basis sans resume de pricing peut sinon disparaitre de la valuation si aucun fallback explicite a 0 n'est prevu.
  • Le calcul du prix peut diverger entre unit_price, linked_price, lot_price et valuation si le premium n'est pas traite explicitement dans chaque maillon.

7) Definition of done (module purchase_trade)

  • Le flux achat/vente/lot cible reste coherent.
  • Les impacts templates/facture ont ete verifies conceptuellement.
  • Les docs locales ont ete mises a jour si une nouvelle regle durable a emerge.
  • Le patch reste minimal et local au domaine demande.