This commit is contained in:
2026-05-14 11:20:33 +02:00
parent 355831c76d
commit 2b3c823743
41 changed files with 2101 additions and 554 deletions

View File

@@ -0,0 +1,48 @@
# Index thematique des regles business
Statut: `migration partielle`
## Comment chercher une regle
- Contrats, dates, lieux, banques: [contracts.md](contracts.md)
- Lots virtuels, lots physiques, `lot.qt`, weighing: [FR](lots-and-quantities.md) / [EN](lots-and-quantities.en.md)
- Matching, Create Contracts, back-to-back: [matching.md](matching.md)
- Shipments, controllers, SLA, weight reports: [shipments-execution.md](shipments-execution.md)
- Pricing manuel, basis, premium, linked currency: [pricing.md](pricing.md)
- Fees, freight, lots effectifs, `% rate`: [fees.md](fees.md)
- Valuation, PnL, MTM, derivatives: [valuation-pnl-mtm.md](valuation-pnl-mtm.md)
- Factures provisoires/finales, padding: [invoicing.md](invoicing.md)
- Impacts `account.move`, validate/post: [accounting-bridge.md](accounting-bridge.md)
- Comptes bancaires, payment terms, payment orders: [payments-banking.md](payments-banking.md)
- Relatorio, `.fodt`, proprietes `report_*`: [reports-templates.md](reports-templates.md)
- Risque, credit, forex: [risk-credit-forex.md](risk-credit-forex.md)
- Rapport Lots Management: [lots-management.md](lots-management.md)
- Diagnostics SQL des invariants: [sql/README.md](sql/README.md)
## Regles migrees dans cette premiere passe
- `BR-PT-CON-001`: texte par defaut de pricing rule.
- `BR-PT-CON-002`: delivery period coherent.
- `BR-PT-CON-003`: lieux stock propages dans Create Contracts.
- `BR-PT-LOT-001`: cycle de vie des lots et des quantites.
- `BR-PT-LOT-002`: quantity contractuelle, execute physique et ligne finie.
- `BR-PT-LOT-003`: garde-fous Python et diagnostics SQL des invariants de
quantite.
- `BR-PT-MAT-001`: Create Contracts multi-lots.
- `BR-PT-SHP-001`: affectation controller.
- `BR-PT-SHP-002`: couts SLA controller.
- `BR-PT-SHP-003`: weight reports distants.
- `BR-PT-PRI-001`: premium dans priced et basis.
- `BR-PT-PRI-002`: linked currency.
- `BR-PT-PRI-003`: pricing manuel.
- `BR-PT-FEE-001`: maritime freight depuis fee shipment.
- `BR-PT-FEE-002`: lots effectifs des fees.
- `BR-PT-FEE-003`: `% rate` via delta de financement.
- `BR-PT-VAL-001`: valuation achat/vente et sale-first.
- `BR-PT-VAL-002`: references de valuation.
- `BR-PT-VAL-003`: MTM hors fees.
- `BR-PT-INV-001`: padding facture provisoire vente.
- `BR-PT-ACC-001`: Validate facture client attribue le numero.
- `BR-PT-PAY-001`: comptes bancaires tiers vs compagnie.
- `BR-PT-RPT-001`: templates trade via proprietes Python.
- `BR-PT-LOTMGT-001`: filtres Lots Management.

View File

@@ -0,0 +1,117 @@
# Guide de lecture des règles business
Statut: `migration partielle`
Dernière mise à jour: `2026-05-13`
Ce dossier devient la source de lecture thématique publiée dans le wiki pour les
règles business du module `purchase_trade`.
Toutes les pages business publiées dans `modules/purchase_trade/docs/business/`
sont générées depuis une source de vérité plus sobre, rangée hors du dossier
wiki dans `modules/purchase_trade/docs_source/business/`.
Les pages publiées portent un commentaire `Generated from ...` en tête de
fichier et ne doivent pas être modifiées directement. Aucun contenu business ne
doit être ajouté ou modifié sans passer par cette source puis par le script de
génération.
Chaque page doit rester lisible par deux publics:
- les consultants, qui ont besoin d'une règle fonctionnelle stable sans détail
de code inutile;
- les développeurs, qui ont besoin des champs, modèles, fichiers et tests
concernés pour appliquer la règle sans l'interpréter.
## Convention de langues
Chaque page thématique durable doit exister en deux versions maintenues
ensemble:
- une page française, rédigée en français correct avec accents, typographie et
formulations naturelles pour le wiki consultant;
- une page anglaise miroir, portant le même contenu fonctionnel et technique.
Convention de nommage:
- page française principale: `theme.md`;
- page anglaise miroir: `theme.en.md`.
Toute modification d'une règle business, d'un statut, d'un champ technique ou
d'un point de vigilance doit être reportée dans les deux pages au même moment.
Les deux pages doivent indiquer leur page miroir en en-tête.
## Convention source / wiki
Pour toute page business:
- éditer la source de vérité dans `modules/purchase_trade/docs_source/business/`;
- régénérer la version wiki avec:
```bash
python modules/purchase_trade/docs/tools/render_business_docs.py
```
Le rendu wiki privilégie du HTML simple et portable plutôt que des extensions
MkDocs optionnelles. Cela évite d'exposer dans le wiki des marqueurs non rendus
comme `!!!` ou `:material-...:`.
Les fichiers générés dans `modules/purchase_trade/docs/business/` sont des
artefacts de publication: ils peuvent être relus, mais toute correction doit
être reportée dans `docs_source/business/` avant régénération.
Avant de livrer une modification documentaire, vérifier que les pages publiées
sont à jour avec:
```bash
python modules/purchase_trade/docs/tools/render_business_docs.py --check
```
## Convention de rédaction
Pour chaque règle durable, utiliser autant que possible ce format:
```md
### BR-PT-THEME-001 - Titre court
Statut: active
Source: business-rules.md / note de session / décision projet
#### Règle consultant
Texte fonctionnel, sans nom de champ si ce n'est pas nécessaire.
#### Notes développeur
- Modèles/champs:
- Fichiers:
- Tests:
- Points de vigilance:
```
## Convention de validation
Quand une règle business devient structurante pour l'intégrité des données, elle
doit être accompagnée autant que possible de deux garde-fous:
- un check applicatif bloquant dans le code Python, appelé à la fin des flux qui
modifient les données concernées;
- un diagnostic SQL en lecture seule pour auditer les bases existantes ou les
bases de test.
Les diagnostics SQL du module sont rangés dans `business/sql/`. Ils ne
remplacent pas les règles applicatives: ils servent à retrouver et qualifier les
écarts déjà présents dans une base.
## Sources pendant la migration
Les anciennes pages ne sont pas supprimées à cette étape. Elles restent des
sources de vérification jusqu'à ce que chaque décision soit promue dans une
page thématique:
- `modules/purchase_trade/docs/business-rules.md`
- `modules/purchase_trade/docs/fees.md`
- `modules/purchase_trade/docs/padding-invoice-accounting.md`
- `modules/purchase_trade/docs/template-rules.md`
- `modules/purchase_trade/docs/template-properties.md`
- `notes/business_rules.md`
- `notes/template_business_rules.md`

View File

@@ -0,0 +1,25 @@
# Pont comptable
Statut: `migration partielle`
## BR-PT-ACC-001 - Validate facture client attribue aussi le numero
Source: `BR-PT-017`
### Regle consultant
Une facture client doit recevoir son mouvement comptable et son numero des la
validation, comme une facture fournisseur.
### Notes developpeur
- Cible: `account.invoice` avec `type = out`.
- Workflow `Validate`: creer `account.move` et attribuer `number`.
- Workflow `Post`: ne doit pas reintroduire une session fraiche specifique au
flux client.
## Notes de migration
Les notes comptables detaillees restent dans `notes/accounting/` tant qu'elles
n'ont pas ete promues ici.

View File

@@ -0,0 +1,50 @@
# Contrats achat / vente
Statut: `migration partielle`
## BR-PT-CON-001 - Texte par defaut de pricing rule
Source: `BR-PT-013`
### Regle consultant
Le texte de regle de pricing recurrent doit etre configure une seule fois et
repris automatiquement sur les nouvelles lignes achat et vente.
### Notes developpeur
- Configuration: `purchase_trade.configuration.pricing_rule`.
- Cibles: `purchase.line.pricing_rule`, `sale.line.pricing_rule`.
- Les lignes existantes ne sont pas modifiees retroactivement.
## BR-PT-CON-002 - Delivery period coherent
Source: `BR-PT-014` historique, doublon de numerotation a corriger
### Regle consultant
Une periode de livraison ne peut pas commencer apres sa date de fin. Une seule
borne renseignee reste acceptee.
### Notes developpeur
- Champs: `purchase.line.from_del`, `purchase.line.to_del`,
`sale.line.from_del`, `sale.line.to_del`.
- Validation attendue: bloquer si `from_del > to_del`.
## BR-PT-CON-003 - Propagation des lieux stock dans Create Contracts
Source: `BR-PT-024`
### Regle consultant
Quand un contrat miroir est cree depuis une quantite ouverte, les lieux
logistiques doivent etre proposes selon le flux source pour eviter la ressaisie.
### Notes developpeur
- Champs: `from_location`, `to_location`.
- Flux fournisseur vers client: recopier le couple source.
- Achat vers stock puis vente: `sale.from_location = purchase.to_location`.
- Vente depuis stock puis achat: `purchase.to_location = sale.from_location`.

View File

@@ -0,0 +1,55 @@
# Fees
Statut: `migration partielle`
Voir aussi la page technique historique: `../fees.md`.
## BR-PT-FEE-001 - Freight value depuis fee shipment
Source: `BR-PT-003`
### Regle consultant
La valeur de fret affichee sur les documents facture vient du fee maritime du
shipment, pas d'un champ direct de la facture.
### Notes developpeur
- Retrouver le lot physique depuis la facture.
- Retrouver son `shipment_in`.
- Chercher le `fee.fee` avec `product.name = 'Maritime freight'`.
- Utiliser `fee.get_amount()`.
## BR-PT-FEE-002 - Les fees lies aux lots privilegient les physiques
Source: `BR-PT-021`
### Regle consultant
Un fee suit le lot virtuel tant qu'aucun lot physique n'est lie. Des qu'un lot
physique est lie, les lots physiques deviennent la base de calcul du fee.
### Notes developpeur
- Ne pas supprimer le lien virtuel: il reste le fallback.
- Quantite `ppack`: somme de `lot.lot_qt` des physiques.
- Modes quantitatifs: quantites courantes converties des physiques.
- La meme selection s'applique au PnL fee.
- Points de synchronisation: creation fee, lien `fee.lots`, changement de
`quantity_theorical`, weighing, suppression de physique.
## BR-PT-FEE-003 - Fees `% rate` via delta de financement
Source: `BR-PT-016` historique et notes `2026-04-30`
### Regle consultant
Les frais financiers en pourcentage se calculent avec le delta de financement
de la ligne d'estimation `BL date`, pas avec la date du jour.
### Notes developpeur
- Formule: `amount = unit_price * quantity * (price / 100) * fin_int_delta / 360`.
- Source du delta: ligne `Estimated date` avec `trigger = bldate`.
- Si aucune ligne `bldate` n'existe, ne pas calculer de montant `% rate`.

View File

@@ -0,0 +1,22 @@
# Glossaire purchase_trade
Statut: `migration partielle`
- `Purchase Line`: ligne d'achat.
- `Sale Line`: ligne de vente.
- `quantity_theorical`: quantite contractuelle theorique d'une ligne.
- `Virtual Lot`: lot de type `virtual`, representant un reliquat ouvert.
- `Physical Lot`: lot de type `physic`, representant une quantite executee.
- `lot.qt`: ligne de quantite ouverte, matchee ou rattachee a un shipment.
- `lot.qt ouvert`: `lot.qt` libre, sans lot oppose et sans shipment.
- `Shipment In`: shipment entrant utilise aussi pour les flux dropship dans ce module.
- `Dropship`: flux fournisseur vers client, sans passage par stock interne.
- `Inbound`: flux entrant classique qui ne correspond pas au dropship.
- `Basis`: mode de prix construit a partir d'un prix de marche et d'un premium.
- `Premium`: prime ou discount commercial ajoute au prix economique.
- `Linked currency`: saisie d'un prix dans une devise/unite liee, par exemple `USC/LB`.
- `Valuation`: lignes de PnL generees pour prix, fees, derivatives et MTM.
- `MTM`: mark-to-market applique aux lignes valorisables au marche.
- `Fee`: frais commercial ou logistique rattache a une ligne, un lot ou un shipment.
- `Report property`: propriete Python exposee pour simplifier un template Relatorio.

View File

@@ -0,0 +1,75 @@
# Invariants structurants
Statut: `migration partielle`
Ces invariants doivent etre relus avant de modifier des flux `purchase_trade`
touchant lots, quantites, fees, PnL, factures ou templates.
## INV-PT-001 - Le lot physique est le pont metier stable
### Regle consultant
Quand une information doit relier achat, vente, shipment et facture, le chemin
fonctionnel de reference passe par le lot physique. Il porte le lien entre les
contrats et l'execution logistique.
### Notes developpeur
- Source historique: `BR-PT-002`.
- Voir aussi: [lots-and-quantities.md](lots-and-quantities.md),
[matching.md](matching.md), [reports-templates.md](reports-templates.md).
- Champs frequents: `lot.line`, `lot.sale_line`, `lot_shipment_in`,
`lot_shipment_internal`, `lot_shipment_out`.
## INV-PT-002 - Le reliquat ouvert ne doit pas doubler les lots physiques
### Regle consultant
Une quantite deja executee physiquement ne doit pas rester disponible comme
quantite ouverte. Le reliquat ouvert represente seulement ce qui reste a
executer.
### Notes developpeur
- Source historique: `BR-PT-020`.
- Le calcul doit tenir compte de la quantite contractuelle, des lots physiques
existants et des `lot.qt` deja matches ou shippes.
- Regle de conservation:
`sum(lots physiques) + lot virtuel = quantity_theorical`.
- Regle du forecast ouvert:
`sum(lot.qt non zero) = max(lot virtuel, 0)`.
- Les lignes `lot.qt` a zero sont ignorees par les checks: elles peuvent servir
de memoire d'une prevision consommee.
- Le check applicatif est centralise dans
`lot.lot.assert_lines_quantity_consistency()`.
- Le diagnostic SQL correspondant est
[sql/quantity_consistency_checks.sql](sql/quantity_consistency_checks.sql).
## INV-PT-003 - Les fees utilisent leurs lots effectifs
### Regle consultant
Un fee ouvert suit le lot virtuel tant qu'il n'y a pas de lot physique. Des
qu'un ou plusieurs lots physiques sont lies au fee, ils deviennent la base
effective de calcul.
### Notes developpeur
- Source historique: `BR-PT-021`.
- Ne pas supprimer le lien virtuel: il reste le fallback si les physiques sont
retires.
- Voir [fees.md](fees.md).
## INV-PT-004 - Les templates doivent rester simples
### Regle consultant
Les documents doivent afficher des informations metier stables, meme si le
chemin technique pour les retrouver est complexe.
### Notes developpeur
- Preferer des proprietes Python `report_*` aux expressions Genshi complexes.
- Ne pas supposer qu'une variable locale comme `shipment` existe partout dans
un `.fodt`.
- Voir [reports-templates.md](reports-templates.md).

View File

@@ -0,0 +1,24 @@
# Facturation trade
Statut: `migration partielle`
## BR-PT-INV-001 - Padding facture provisoire vente
Source: `BR-PT-019` et `../padding-invoice-accounting.md`
### Regle consultant
Le padding d'une facture provisoire vente augmente la quantite facturee pour
constituer une provision, sans modifier la quantite physique du lot.
### Notes developpeur
- Le padding global du wizard `lot.invoice` est reparti entre les lots
selectionnes.
- La ligne facture expose `Inc. padding`.
- Le lot conserve sa part dans `sale_invoice_padding`.
- La facture finale retire le padding de la quantite provisoire avant de
calculer le delta.
- Les ecritures d'extourne doivent relire la provisoire depuis
`lot.sale_invoice_line_prov`.

View File

@@ -0,0 +1,27 @@
# Lots Management
Statut: `migration partielle`
## BR-PT-LOTMGT-001 - Separations matching, side et shipping status
Source: `BR-PT-023` et notes `2026-05-09`
### Regle consultant
Le rapport Lots Management doit permettre de lire separement le matching
commercial, le sens achat/vente et l'avancement logistique.
### Notes developpeur
- Filtres: `Matching status`, `Side`, `Shipping status`, `Dimension`,
`Strategy`.
- Dates `As of` / `To`: `purchase.purchase_date` et `sale.sale_date`.
- `Unshipped`: aucun `shipment_in`.
- `Scheduled`: shipment `draft`.
- `Shipped`: shipment `started`.
- `Received`: shipment `received` ou `done`.
- `Shipment Type = Dropship` si `from_location.type = supplier` et
`to_location.type = customer`, sinon `Inbound`.
- `Mark as finished` masque seulement les reliquats ouverts / virtuels, pas
les lots physiques.

View File

@@ -0,0 +1,27 @@
# Matching achat / vente
Statut: `migration partielle`
## BR-PT-MAT-001 - Create Contracts multi-lots conserve le matching source
Source: `BR-PT-012` et doublon historique `BR-PT-013`
### Regle consultant
Le wizard `Create contracts` peut creer un seul contrat miroir depuis plusieurs
quantites ouvertes selectionnees. Chaque ligne creee doit rester reliee a son
lot source.
### Notes developpeur
- La quantite du wizard doit correspondre a la somme des quantites ouvertes
selectionnees.
- Creer une ligne par `lot.qt` source.
- Conserver `created_by_code = True` pour eviter les creations automatiques
parasites lors des validations.
## Notes de migration
Les regles sur `Apply matching` presentes dans les notes de session du
`2026-05-09` doivent encore etre promues ici.

View File

@@ -0,0 +1,21 @@
# Paiements et banques
Statut: `migration partielle`
## BR-PT-PAY-001 - Distinguer banque tiers et banque compagnie
Source: `BR-PT-018`
### Regle consultant
Un contrat distingue le compte bancaire du client ou fournisseur du compte
bancaire utilise par la compagnie courante pour encaisser ou payer.
### Notes developpeur
- Contrats: `sale.sale`, `purchase.purchase`.
- `bank_account`: compte de la party du contrat.
- `our_bank_account`: compte de la compagnie courante, selectionnable parmi
les comptes disponibles.
- La devise du contrat est prioritaire pour proposer un compte par defaut.

View File

@@ -0,0 +1,53 @@
# Pricing, basis, premium
Statut: `migration partielle`
## BR-PT-PRI-001 - Le premium fait partie du prix economique
Source: `BR-PT-008`
### Regle consultant
Le premium ou discount saisi sur une ligne fait partie du prix economique, que
la ligne soit en prix fixe ou en basis.
### Notes developpeur
- `unit_price` reste le prix de base hors premium.
- Montant economique: `unit_price + premium converti si necessaire`.
- En basis, le premium s'applique aussi aux blocs valorises.
## BR-PT-PRI-002 - Linked currency
Source: `BR-PT-009` et `BR-PT-010`
### Regle consultant
Quand le prix est saisi dans une devise ou unite liee, le premium est exprime
dans ce meme repere puis converti pour les calculs internes.
### Notes developpeur
- Champs obligatoires si active: `linked_price`, `linked_currency`,
`linked_unit`.
- En `basis + linked currency`, `linked_price` represente le basis brut hors
premium.
- `amount` ajoute le premium converti.
## BR-PT-PRI-003 - Pricing manuel
Source: `BR-PT-016` et doublon historique `BR-PT-015`
### Regle consultant
En pricing manuel, l'utilisateur saisit uniquement la quantite fixee du jour et
le prix de marche. Les cumuls et prix moyens sont calcules automatiquement.
### Notes developpeur
- Champs saisis: `quantity`, `settl_price`.
- Champs derives: `fixed_qt`, `fixed_qt_price`, `unfixed_qt`,
`unfixed_qt_price`, `eod_price`, `last`.
- Groupe metier: `line + component` ou `sale_line + component`.
- Le composant choisi doit appartenir a la ligne courante.

View File

@@ -0,0 +1,39 @@
# Reports et templates
Statut: `migration partielle`
Voir aussi:
- `../template-rules.md`
- `../template-properties.md`
- `../../../../notes/template_business_rules.md`
## BR-PT-RPT-001 - Templates trade via proprietes Python
Source: `template-rules.md`, `template-properties.md`, notes AGENTS
### Regle consultant
Un document trade doit afficher des informations metier fiables, sans dependre
d'expressions fragiles dans le fichier bureautique.
### Notes developpeur
- Preferer des proprietes Python simples, souvent prefixees `report_*`.
- Dans les placeholders XML, utiliser `"` et `'` plutot que des
antislashs.
- Pour les factures liees a vente/achat/shipment, privilegier le lot physique
comme pont.
- Verifier le cache `invoice_report_cache` avant de conclure qu'une action
report pointe vers le mauvais `.fodt`.
- Pour les templates shipment, preferer `records[0]...` ou des proprietes sur
`stock.shipment.in` plutot qu'une variable locale supposee.
## Decisions deja documentees a migrer ensuite
- `insurance.fodt`: compagnie courante, amount insured a 110%, surveyor.
- `packing_list.fodt`: date du jour, unites depuis `purchase.line`.
- `bill.fodt`: maturity date reelle et montant en lettres depuis le total.
- `invoice_ict.fodt` / `invoice_ict_final.fodt`: poids, shipments et lots.
- `sale_ict.fodt`: priorite lots et unite reelle.

View File

@@ -0,0 +1,15 @@
# Risque, credit, forex
Statut: `placeholder`
Cette page est reservee aux regles business sur le risque, le credit et les
ecarts de change.
Aucune regle canonique `purchase_trade` n'a ete promue ici dans cette premiere
passe. Les notes comptables et forex existantes doivent etre relues avant toute
migration:
- `notes/accounting/README.md`
- `notes/accounting/business_rules.md`
- `notes/accounting/reporting.md`

View File

@@ -0,0 +1,31 @@
# Journal de migration et sessions
Statut: `non canonique`
Cette page sert de routeur vers les notes historiques. Une note devient
canonique seulement quand elle est reprise dans une page thematique.
## Sources historiques
- `modules/purchase_trade/docs/business-rules.md`
- `modules/purchase_trade/docs/business-rules-architecture-proposal.md`
- `notes/business_rules.md`
- `notes/template_business_rules.md`
## Notes deja partiellement promues
- Session `2026-04-30`: PnL fees ouverts et `% rate`, promue dans
[fees.md](fees.md) et [valuation-pnl-mtm.md](valuation-pnl-mtm.md).
- Session `2026-05-01`: solde ouvert apres lots physiques et lots effectifs
des fees, promue dans [lots-and-quantities.md](lots-and-quantities.md) et
[fees.md](fees.md).
- Session `2026-05-06`: Remove physical lot, promue dans
[lots-and-quantities.md](lots-and-quantities.md).
- Session `2026-05-09`: Lots Management, promue partiellement dans
[lots-management.md](lots-management.md).
- Session `2026-05-13`: cadrage `quantity_theorical` / `quantity`, amount de
ligne, Weight basis, invariants de quantite, checks Python bloquants et
diagnostic SQL. Promue dans
[lots-and-quantities.md](lots-and-quantities.md),
[lots-and-quantities.en.md](lots-and-quantities.en.md),
[invariants.md](invariants.md) et [sql/README.md](sql/README.md).

View File

@@ -0,0 +1,49 @@
# Shipments et execution
Statut: `migration partielle`
## BR-PT-SHP-001 - Affectation controller par ecart a l'objectif
Source: `BR-PT-014`
### Regle consultant
Le controller propose automatiquement est celui dont la zone a le plus grand
retard par rapport a son objectif.
### Notes developpeur
- Configuration: onglet `Execution` de `party.party`.
- La zone du shipment vient de `shipment.to_location.country`.
- Une region parente couvre ses sous-regions.
- `% achieved` compte seulement les shipments deja affectes a un controller.
## BR-PT-SHP-002 - Couts SLA controller par pays et/ou lieu
Source: `BR-PT-014-bis`
### Regle consultant
Un cout controller peut etre defini pour un pays, un lieu, ou le couple pays +
lieu. Le couple est le cas le plus specifique.
### Notes developpeur
- Matching: `country + location`, puis `location`, puis `country`.
- Le pays vient de `shipment.to_location.country`.
## BR-PT-SHP-003 - Weight reports distants par lot
Source: `BR-PT-015`
### Regle consultant
L'export distant par lot part du weight report global choisi par l'utilisateur
sur le shipment.
### Notes developpeur
- Exporter seulement les lots physiques des `incoming_moves`.
- Exiger au minimum `controller` et `returned_id` sur le shipment.
- Conserver les cles distantes et la date d'envoi sur le `weight.report`.

View File

@@ -0,0 +1,47 @@
# SQL diagnostics for purchase_trade business rules
These scripts are read-only diagnostics for a PostgreSQL test database.
They exist to support the same business rules enforced by Python guards. The
expected workflow is:
1. write the consultant/developer rule in the thematic documentation;
2. enforce the invariant in the application code when feasible;
3. provide a read-only SQL diagnostic to audit existing data.
## quantity_consistency_checks.sql
Checks the two core lot quantity invariants documented in
`lots-and-quantities.md` and `lots-and-quantities.en.md`.
Zero `lot_qt` rows are ignored completely. They are treated as legitimate
memory of an open quantity consumed by a physical lot. This is required because
`lot_qt` represents usable open forecast and stops at zero, while the virtual
lot may become negative to compensate the difference between theoretical and
executed quantity. A non-zero `lot_qt` row without both `lot_p` and `lot_s` is
reported as anomalous.
Run it on a restored test database:
```sql
\i modules/purchase_trade/docs/business/sql/quantity_consistency_checks.sql
```
The script returns rows only when it finds a potential issue.
Main columns:
- `check_name`: invariant or diagnostic that failed.
- `contract_model`: `purchase.purchase` or `sale.sale`.
- `contract_id`: database id of the contract.
- `contract_number`: purchase or sale contract number.
- `line_id`: `purchase.line` or `sale.line` id depending on the check.
- `virtual_lot_id`: virtual lot involved in the inconsistency.
- `observed_value`: value found in the database.
- `expected_value`: value required by the business rule.
- `diff`: observed minus expected.
- `detail`: human-readable explanation.
Cross-category UoM rows are reported as manual-review diagnostics because the
Python code may pass explicit conversion factors that cannot be inferred safely
from SQL alone.

View File

@@ -0,0 +1,51 @@
# Valuation, PnL, MTM
Statut: `migration partielle`
## BR-PT-VAL-001 - La valuation couvre achat, vente et sale-first
Source: `BR-PT-004`, `BR-PT-006`, `BR-PT-011`
### Regle consultant
Le PnL doit exister pour les achats et pour les ventes, meme quand une vente
n'est pas encore matchee a un achat.
### Notes developpeur
- Une `sale.line` non matchee doit generer au minimum `sale priced`, `sale fee`
et `derivative` si applicable.
- Une sale basis sans detail de prix doit quand meme produire une ligne a zero
ou au prix economique fallback selon la regle applicable.
- Ne pas attacher arbitrairement une sale unique si plusieurs sales sont
matchees au meme ouvert.
## BR-PT-VAL-002 - References de valuation
Source: `BR-PT-005`
### Regle consultant
La reference de PnL doit decrire la nature de la ligne valorisee: achat ou
vente, ouverte ou physique.
### Notes developpeur
- References autorisees: `Purchase/Open`, `Purchase/Physic`, `Sale/Open`,
`Sale/Physic`.
- Un lot virtuel ne doit pas sortir avec une reference physique.
## BR-PT-VAL-003 - MTM hors fees
Source: `BR-PT-007`
### Regle consultant
Le mark-to-market s'applique aux prix et aux derives, pas aux frais.
### Notes developpeur
- MTM autorise pour `pur. priced`, `sale priced`, `derivative`.
- Fees hors MTM: `pur. fee`, `sale fee`, `shipment fee`, `line fee`.
- Pour les fees: `mtm_price`, `mtm`, `strategy` doivent rester vides.