158 lines
5.7 KiB
Markdown
158 lines
5.7 KiB
Markdown
# Business Rules - Purchase Trade
|
|
|
|
Statut: `draft`
|
|
Version: `v0.2`
|
|
Derniere mise a jour: `2026-03-27`
|
|
Owner metier: `a completer`
|
|
Owner technique: `a completer`
|
|
|
|
## 1) Scope
|
|
|
|
- Domaine: `purchase_trade`
|
|
- Hors scope:
|
|
- Modules impactes:
|
|
- `purchase_trade`
|
|
- `lot`
|
|
|
|
## 2) Glossaire
|
|
|
|
- `Purchase Line`: ligne d'achat.
|
|
- `quantity_theorical`: quantite theorique contractuelle de la ligne.
|
|
- `Virtual Lot`: lot unique de type `virtual` rattache a une `purchase.line`.
|
|
- `lot.qt`: table des quantites ouvertes, matchées ou shippées par lot.
|
|
- `lot.qt ouvert`: enregistrement `lot.qt` avec `lot_p = virtual lot`, `lot_s = None` et sans shipment.
|
|
|
|
## 3) Regles metier
|
|
|
|
### BR-PT-001 - Ajustement de la quantite theorique apres creation du contrat
|
|
|
|
- Intent: conserver la coherence entre la quantite theorique de la ligne d'achat, le lot virtuel associe et les quantites ouvertes stockees dans `lot.qt`.
|
|
- Description:
|
|
- Quand `purchase.line.quantity_theorical` est modifiee apres creation du contrat, le systeme doit recalculer le delta entre l'ancienne et la nouvelle valeur.
|
|
- La regle s'applique au lot unique de type `virtual` rattache a la `purchase.line`.
|
|
- Conditions d'entree:
|
|
- Une `purchase.line` existe deja.
|
|
- Son champ `quantity_theorical` est modifie via `write`.
|
|
- Un lot `virtual` est rattache a la ligne.
|
|
- Resultat attendu:
|
|
- Si `delta > 0`:
|
|
- augmenter la quantite courante du lot `virtual` via `set_current_quantity` pour conserver l'historique `lot.qt.hist`
|
|
- augmenter le `lot.qt` ouvert existant
|
|
- si aucun `lot.qt` ouvert n'existe, en creer un nouveau avec le delta
|
|
- Si `delta < 0`:
|
|
- diminuer le `lot.qt` ouvert uniquement si la quantite ouverte disponible est suffisante
|
|
- diminuer la quantite courante du lot `virtual` du meme delta
|
|
- si aucun `lot.qt` ouvert n'existe ou si sa quantite est insuffisante, bloquer avec l'erreur `Please unlink or unmatch lot`
|
|
- Definition du `lot.qt` ouvert:
|
|
- `lot_p = virtual lot`
|
|
- `lot_s = None`
|
|
- `lot_shipment_in = None`
|
|
- `lot_shipment_internal = None`
|
|
- `lot_shipment_out = None`
|
|
- Exceptions:
|
|
- si aucun lot `virtual` n'est trouve sur la ligne, la regle ne fait rien
|
|
- Priorite:
|
|
- `bloquante`
|
|
- Source:
|
|
- `Decision metier documentee dans les commentaires de purchase_trade.purchase.Line.write`
|
|
|
|
### BR-PT-002 - Le lot physique est le pont metier entre purchase, sale et shipment
|
|
|
|
- Intent: disposer d'un chemin unique et stable pour retrouver les informations logistiques et de facturation reliees a un contrat d'achat ou de vente.
|
|
- Description:
|
|
- Le lot physique (`lot_type = physic`) porte simultanement le lien vers:
|
|
- la `purchase.line` via `lot.line`
|
|
- la `sale.line` via `lot.sale_line`
|
|
- le shipment via `lot.lot_shipment_in` / `lot.lot_shipment_internal` / `lot.lot_shipment_out`
|
|
- Pour toute logique qui doit naviguer entre achat, vente, shipment et facture, il faut privilegier ce lot physique comme source de verite.
|
|
- Resultat attendu:
|
|
- depuis une facture d'achat:
|
|
- remonter a la `purchase.line`
|
|
- puis au lot physique de la ligne
|
|
- puis au shipment et aux donnees logistiques associees
|
|
- depuis une facture de vente:
|
|
- remonter a la `sale.line`
|
|
- puis au lot physique matchant qui porte aussi la `purchase.line`
|
|
- puis au shipment et aux donnees logistiques associees
|
|
- Cas d'usage typiques:
|
|
- recuperer `bl_date`, `bl_number`, `controller`, `from_location`, `to_location`
|
|
- retrouver une facture provisoire liee au lot
|
|
- retrouver des fees rattaches au shipment
|
|
- Priorite:
|
|
- `structurante`
|
|
|
|
### BR-PT-003 - Le freight amount des templates facture vient du fee de shipment
|
|
|
|
- Intent: afficher dans les documents facture la vraie valeur de fret maritime rattachee au shipment du lot physique.
|
|
- Description:
|
|
- Le `FREIGHT VALUE` d'une facture ne doit pas etre pris sur la facture elle-meme.
|
|
- Il doit etre calcule a partir du `fee.fee` rattache au shipment (`shipment_in`) du lot physique relie a la facture.
|
|
- Regle de navigation:
|
|
- retrouver le lot physique pertinent depuis la facture
|
|
- retrouver son shipment
|
|
- chercher le `fee.fee` avec:
|
|
- `shipment_in = shipment.id`
|
|
- `product.name = 'Maritime freight'`
|
|
- utiliser `fee.get_amount()` comme montant de fret
|
|
- Portee:
|
|
- s'applique aussi bien aux factures d'achat qu'aux factures de vente
|
|
- cote vente, la remontee doit passer par le lot physique qui fait le lien entre `purchase.line` et `sale.line`
|
|
- Priorite:
|
|
- `importante`
|
|
|
|
## 4) Exemples concrets
|
|
|
|
### Exemple E1 - Augmentation simple
|
|
|
|
- Donnees:
|
|
- `ancienne quantity_theorical = 100`
|
|
- `nouvelle quantity_theorical = 120`
|
|
- `lot.qt ouvert = 40`
|
|
- Attendu:
|
|
- lot `virtual` augmente de `20`
|
|
- `lot.qt ouvert` passe de `40` a `60`
|
|
|
|
### Exemple E2 - Augmentation sans lot.qt ouvert
|
|
|
|
- Donnees:
|
|
- `ancienne quantity_theorical = 100`
|
|
- `nouvelle quantity_theorical = 110`
|
|
- aucun `lot.qt` ouvert
|
|
- Attendu:
|
|
- lot `virtual` augmente de `10`
|
|
- creation d'un `lot.qt` ouvert a `10`
|
|
|
|
### Exemple E3 - Diminution possible
|
|
|
|
- Donnees:
|
|
- `ancienne quantity_theorical = 100`
|
|
- `nouvelle quantity_theorical = 90`
|
|
- `lot.qt ouvert = 25`
|
|
- Attendu:
|
|
- lot `virtual` diminue de `10`
|
|
- `lot.qt ouvert` passe de `25` a `15`
|
|
|
|
### Exemple E4 - Diminution impossible
|
|
|
|
- Donnees:
|
|
- `ancienne quantity_theorical = 100`
|
|
- `nouvelle quantity_theorical = 80`
|
|
- `lot.qt ouvert = 5`
|
|
- Attendu:
|
|
- blocage avec `Please unlink or unmatch lot`
|
|
|
|
## 5) Impact code attendu
|
|
|
|
- Fichiers Python concernes:
|
|
- `modules/purchase_trade/purchase.py`
|
|
- `modules/purchase_trade/lot.py`
|
|
|
|
## 6) Strategie de tests
|
|
|
|
Pour cette regle, couvrir au minimum:
|
|
|
|
- augmentation avec `lot.qt` ouvert existant
|
|
- augmentation sans `lot.qt` ouvert
|
|
- diminution possible
|
|
- diminution impossible avec erreur
|