<!-- Generated from docs_source/business by docs/tools/render_business_docs.py. -->

# 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

<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
<li style="margin:0.38rem 0;">Source historique: <code>BR-PT-002</code>.
</li>
<li style="margin:0.38rem 0;">Voir aussi: <a href="lots-and-quantities.md">lots-and-quantities.md</a>, <a href="matching.md">matching.md</a>, <a href="reports-templates.md">reports-templates.md</a>.
</li>
<li style="margin:0.38rem 0;">Champs frequents: <code>lot.line</code>, <code>lot.sale_line</code>, <code>lot_shipment_in</code>, <code>lot_shipment_internal</code>, <code>lot_shipment_out</code>.
</li>
</ul>

## 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

<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
<li style="margin:0.38rem 0;">Source historique: <code>BR-PT-020</code>.
</li>
<li style="margin:0.38rem 0;">Le calcul doit tenir compte de la quantite contractuelle, des lots physiques existants et des <code>lot.qt</code> deja matches ou shippes.
</li>
<li style="margin:0.38rem 0;">Regle de conservation: <code>sum(lots physiques) + lot virtuel = quantity_theorical</code>.
</li>
<li style="margin:0.38rem 0;">Regle du forecast ouvert minimal: <code>sum(lot.qt non zero) &gt;= max(lot virtuel, 0)</code>.
</li>
<li style="margin:0.38rem 0;">Un surplus de forecast ouvert est accepte apres surconsommation physique: <code>lot.qt</code> s&#x27;arrete a zero, alors que le lot virtuel absorbe toute la quantite physique.
</li>
<li style="margin:0.38rem 0;">Les lignes <code>lot.qt</code> a zero sont ignorees par les checks: elles peuvent servir de memoire d&#x27;une prevision consommee.
</li>
<li style="margin:0.38rem 0;">Le check applicatif est centralise dans <code>lot.lot.assert_lines_quantity_consistency()</code>.
</li>
<li style="margin:0.38rem 0;">Le diagnostic SQL correspondant est <a href="sql/quantity_consistency_checks.sql">sql/quantity_consistency_checks.sql</a>.
</li>
</ul>

## 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

<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
<li style="margin:0.38rem 0;">Source historique: <code>BR-PT-021</code>.
</li>
<li style="margin:0.38rem 0;">Ne pas supprimer le lien virtuel: il reste le fallback si les physiques sont retires.
</li>
<li style="margin:0.38rem 0;">Voir <a href="fees.md">fees.md</a>.
</li>
</ul>

## 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

<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
<li style="margin:0.38rem 0;">Preferer des proprietes Python <code>report_*</code> aux expressions Genshi complexes.
</li>
<li style="margin:0.38rem 0;">Ne pas supposer qu&#x27;une variable locale comme <code>shipment</code> existe partout dans un <code>.fodt</code>.
</li>
<li style="margin:0.38rem 0;">Voir <a href="reports-templates.md">reports-templates.md</a>.
</li>
</ul>
