762 lines
36 KiB
Markdown
762 lines
36 KiB
Markdown
<!-- Generated from docs_source/business by docs/tools/render_business_docs.py. -->
|
|
|
|
# Lots et quantités
|
|
|
|
Langue : `fr`
|
|
Page miroir : [lots-and-quantities.en.md](lots-and-quantities.en.md)
|
|
Statut : `migration partielle`
|
|
Dernière vérification code : `2026-05-13`
|
|
|
|
Cette page consolide `BR-PT-LOT-001`, `BR-PT-LOT-002` et `BR-PT-LOT-003`.
|
|
Objectif : piloter les règles de quantité depuis une définition métier lisible,
|
|
puis les sécuriser par des checks Python et des diagnostics SQL.
|
|
|
|
## À retenir
|
|
|
|
<div style="border-left:0.28rem solid #4051b5; background:#f5f7ff; padding:0.85rem 1rem; margin:1rem 0 1.4rem 0; border-radius:0.35rem;"><strong style="display:block; margin-bottom:0.35rem;">Résumé opérationnel</strong><span>Une ligne trade possède un seul lot virtuel. Le lot virtuel porte le solde ouvert global, <code>lot.qt</code> porte le forecast opérationnel, et les lots physiques consomment ce forecast.</span></div>
|
|
|
|
<table style="width:100%; border-collapse:collapse; margin:1rem 0 1.5rem 0; font-size:0.95rem;">
|
|
<thead>
|
|
<tr style="background:#eef3ff;">
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Sujet</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Règle courte</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Quantité saisie</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>quantity_theorical</code> est la quantité métier.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Quantité standard</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>quantity</code> est un compteur technique non éditable.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Avant physique</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>quantity</code> suit <code>quantity_theorical</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Après physique</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>quantity</code> reflète l'exécuté physique.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Ligne non finie</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Le montant de ligne utilise <code>quantity_theorical</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Ligne finie</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Le montant peut revenir à l'exécuté physique.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Weight basis</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Achat et vente peuvent lire deux états différents du même lot.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Facturation</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Elle choisit ses états dans <code>lot.qt.hist</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Contrôles</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Invariants bloqués en Python et auditables en SQL.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<pre style="background:#263238; color:#eef7ff; padding:1rem; border-radius:0.35rem; overflow:auto;"><code>quantity_theorical
|
|
|
|
|
v
|
|
lot virtuel P1 ---> lot.qt forecast ---> lot physique
|
|
^ |
|
|
| v
|
|
+------ recalcul après consommation</code></pre>
|
|
|
|
## Règles consultant
|
|
|
|
### BR-PT-LOT-001 - Cycle de vie lot virtuel / forecast / physique
|
|
|
|
<table style="width:100%; border-collapse:collapse; margin:1rem 0 1.5rem 0; font-size:0.95rem;">
|
|
<thead>
|
|
<tr style="background:#eef3ff;">
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Moment</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Effet métier</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Création de ligne</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Création d'un lot virtuel unique.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Initialisation</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Le lot virtuel reprend <code>quantity_theorical</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Forecast</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Une ligne ouverte est créée dans <code>lot.qt</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Planification</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>lot.qt</code> peut être subdivisé par vente, matching, transport ou shipment.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Ajout physique</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Le lot physique consomme une ligne <code>lot.qt</code> précise.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Après ajout</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>lot.qt</code> diminue et le lot virtuel est recalculé.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div style="border-left:0.28rem solid #4051b5; background:#f5f7ff; padding:0.85rem 1rem; margin:1rem 0 1.4rem 0; border-radius:0.35rem;"><strong style="display:block; margin-bottom:0.35rem;">Découpage d'un solde P1</strong><span><code>P1S1T1</code>, <code>P1S1T2</code>, <code>P1S2T3</code>, <code>P1S2T4</code></span></div>
|
|
|
|
<div style="border-left:0.28rem solid #4051b5; background:#f5f7ff; padding:0.85rem 1rem; margin:1rem 0 1.4rem 0; border-radius:0.35rem;"><strong style="display:block; margin-bottom:0.35rem;">Point clé</strong><span>Ces découpages ne créent pas plusieurs lots virtuels. Ils décrivent seulement la répartition prévisionnelle du solde ouvert.</span></div>
|
|
|
|
### BR-PT-LOT-002 - Quantité contractuelle, compteur, ligne finie
|
|
|
|
<table style="width:100%; border-collapse:collapse; margin:1rem 0 1.5rem 0; font-size:0.95rem;">
|
|
<thead>
|
|
<tr style="background:#eef3ff;">
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Situation</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Quantité de référence</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Saisie utilisateur</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>quantity_theorical</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Aucun lot physique</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>quantity = quantity_theorical</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Lots physiques présents</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>quantity = somme des lots physiques</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>finished = False</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Montant basé sur <code>quantity_theorical</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>finished = True</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Montant basé sur l'exécuté physique</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Weight basis disponible</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Montant basé sur l'état <code>wb.qt_type</code> du contrat</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div style="border-left:0.28rem solid #4051b5; background:#f5f7ff; padding:0.85rem 1rem; margin:1rem 0 1.4rem 0; border-radius:0.35rem;"><strong style="display:block; margin-bottom:0.35rem;">Ce que <code>finished</code> ne fait pas</strong><span><code>finished</code> n'efface pas la quantité contractuelle, ne supprime pas les lots physiques et ne masque pas leur PnL. Il signifie seulement que le reliquat ouvert peut être ignoré pour les calculs d'exécution.</span></div>
|
|
|
|
<table style="width:100%; border-collapse:collapse; margin:1rem 0 1.5rem 0; font-size:0.95rem;">
|
|
<thead>
|
|
<tr style="background:#eef3ff;">
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Lecture du même lot physique</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">État possible</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Achat</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">BL via <code>purchase.purchase.wb.qt_type</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Vente</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">LR ou Weight Report via <code>sale.sale.wb.qt_type</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Facturation</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Choix indépendant dans <code>lot.qt.hist</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
### BR-PT-LOT-003 - Invariants de quantité
|
|
|
|
<table style="width:100%; border-collapse:collapse; margin:1rem 0 1.5rem 0; font-size:0.95rem;">
|
|
<thead>
|
|
<tr style="background:#eef3ff;">
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Invariant</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Formule</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Conservation</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>somme(lots physiques) + lot virtuel = quantity_theorical</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Forecast ouvert minimal</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>somme(lot.qt non zéro) >= max(lot virtuel, 0)</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<table style="width:100%; border-collapse:collapse; margin:1rem 0 1.5rem 0; font-size:0.95rem;">
|
|
<thead>
|
|
<tr style="background:#eef3ff;">
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Cas</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Règle</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Lot virtuel achat</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Sommer tous les <code>lot.qt</code> où <code>lot_p = lot virtuel</code>, avec ou sans <code>lot_s</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Lot virtuel vente</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Sommer tous les <code>lot.qt</code> où <code>lot_s = lot virtuel</code>, avec ou sans <code>lot_p</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>lot.qt = 0</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Ignoré par les checks ; mémoire possible d'une prévision vidée.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Surconsommation forecast</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Autorisée après confirmation de tolérance : <code>lot.qt</code> s'arrête à zéro, mais le lot virtuel absorbe tout le physique.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>lot.qt</code> supérieur au virtuel</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Accepté si le forecast ouvert restant dépasse le virtuel positif à cause d'une surconsommation physique.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Lot virtuel négatif</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Autorisé pour compenser l'écart théorique / exécuté ; forecast attendu = zéro.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>lot.qt</code> non zéro orphelin</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Interdit si ni <code>lot_p</code> ni <code>lot_s</code> n'est renseigné.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
### BR-PT-LOT-004 - Historique de quantité et weighing
|
|
|
|
<table style="width:100%; border-collapse:collapse; margin:1rem 0 1.5rem 0; font-size:0.95rem;">
|
|
<thead>
|
|
<tr style="background:#eef3ff;">
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Élément</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Règle</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>lot.qt.hist</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Porte les états de quantité d'un lot.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Fiche <code>lot.lot</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Pas de saisie directe des états.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Modification</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Uniquement via <code>Do weighing</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Lot virtuel</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Pas de packing manuel.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Champs packing virtuel</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>lot_qt</code> et <code>lot_unit</code> non éditables.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
### Tolérances
|
|
|
|
<table style="width:100%; border-collapse:collapse; margin:1rem 0 1.5rem 0; font-size:0.95rem;">
|
|
<thead>
|
|
<tr style="background:#eef3ff;">
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Point</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">Règle</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Niveau</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">La tolérance est définie au header <code>purchase</code> / <code>sale</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Héritage</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Les lignes héritent de la tolérance header par défaut.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Transport</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Pas de tolérance indépendante par transport.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Ajout physique</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Le contrôle se fait au moment de <code>Add physical lots</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Forecast matché</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Si <code>lot_qt</code> porte <code>lot_p</code> et <code>lot_s</code>, le contrôle porte sur les deux côtés achat et vente.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Dépassement ligne</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Warning confirmable en anglais si la quantité physique projetée dépasse la tolérance courante de la ligne. Le message indique le côté bloquant : <code>purchase</code>, <code>sale</code>, ou les deux si les deux checks déclenchent successivement.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Enveloppe globale</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Le dépassement ponctuel d'une ligne est accepté après confirmation et consomme l'enveloppe globale du contrat.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Tolérance restante</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Les lignes du contrat sont recalculées avec <code>inherit_tol = False</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Surconsommation</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Une ligne qui dépasse la tolérance header garde une tolérance <code>+</code> au moins égale à son dépassement réel.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Autres lignes</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Leur tolérance <code>+</code> est réduite selon l'enveloppe restante.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Sous-consommation</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Restitue mécaniquement de la tolérance disponible aux autres lignes lors du recalcul suivant.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Matching ouvert</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>Go to matching</code> peut matcher au-delà du solde ouvert strict si la quantité projetée reste dans <code>Qt max</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Jauge ligne</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Sur une ligne avec lots physiques, la jauge utilise la somme des physiques ; sans physique, elle utilise la somme des <code>lot.qt</code> liés.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Jauge header</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">La jauge purchase/sale est la moyenne pondérée des jauges de lignes au prorata de <code>quantity_theorical</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Jauge matching</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Dans <code>Go to matching</code>, la jauge projette <code>déjà matché + Qt to match</code> contre <code>quantity_theorical</code>, avec bornes <code>-tol_min</code> / <code>tol_max</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Layout jauge ligne</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">En formulaire <code>purchase.line</code> / <code>sale.line</code>, placer la jauge et <code>targeted_qt</code> directement dans la grille principale, sans sous-groupe <code>colspan="4"</code>, et utiliser <code>xalign="0"</code> pour éviter un double décalage vers la droite.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
## Section développeur
|
|
|
|
### Champs clés
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Ligne achat : <code>purchase.line</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Ligne vente : <code>sale.line</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Lot : <code>lot.lot</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Forecast : <code>lot.qt</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Historique : <code>lot.qt.hist</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Quantité métier achat : <code>purchase.line.quantity_theorical</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Quantité métier vente : <code>sale.line.quantity_theorical</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Compteur technique : <code>quantity</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Ligne finie : <code>purchase.line.finished</code>, <code>sale.line.finished</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Lot virtuel / physique : <code>lot.lot.lot_type = virtual / physic</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Lien achat : <code>lot.lot.line</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Lien vente : <code>lot.lot.sale_line</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Forecast achat : <code>lot.qt.lot_p</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Forecast vente : <code>lot.qt.lot_s</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Quantité forecast : <code>lot.qt.lot_quantity</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Weight basis : <code>purchase.purchase.wb</code>, <code>sale.sale.wb</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">État Weight basis : <code>purchase.weight.basis.qt_type</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Packing : <code>lot.lot.lot_qt</code>, <code>lot.lot.lot_unit</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Tolerances : <code>tol_min</code>, <code>tol_max</code>, <code>tol_min_qt</code>, <code>tol_max_qt</code>, <code>tol_min_v</code>, <code>tol_max_v</code>, <code>tolerance_used</code>, <code>tolerance_min</code>, <code>tolerance_max</code>
|
|
</li>
|
|
</ul>
|
|
|
|
### Création ligne / lot virtuel
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Achat : <code>purchase.py</code>, <code>Line.validate</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Vente : <code>sale.py</code>, <code>SaleLine.validate</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Si <code>quantity_theorical</code> est saisi et que <code>quantity</code> est vide ou zéro :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>quantity</code> est initialisée depuis <code>quantity_theorical</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">seulement si aucun lot physique n'existe.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Si la ligne est éligible :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">pas <code>created_by_code</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">pas encore de lot ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">produit non service ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>quantity_theorical != 0</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">création d'un lot <code>virtual</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Le lot virtuel reçoit une première entrée <code>lot.qt.hist</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>Lot.validate</code> crée le <code>lot.qt</code> ouvert via <code>createVirtualPart</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Si la ligne est <code>created_by_code</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">elle provient d'un workflow métier (<code>Create contracts</code>, matching, etc.) ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>Lot.validate</code> ne crée pas de <code>lot.qt</code> ouvert automatique ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">le workflow rattache ou subdivise son <code>lot.qt</code> source ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">le check bloquant s'applique seulement après stabilisation du workflow.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
### Modification de `quantity_theorical`
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Achat : <code>purchase.py</code>, <code>Line.write</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Vente : <code>sale.py</code>, <code>SaleLine.write</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Cible lot virtuel :
|
|
</li>
|
|
</ul>
|
|
|
|
<pre style="background:#263238; color:#eef7ff; padding:1rem; border-radius:0.35rem; overflow:auto;"><code>target_quantity = quantity_theorical - somme(lots physiques convertis)</code></pre>
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Si <code>target_quantity < 0</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">blocage : <code>Please unlink or unmatch lot</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Cible <code>lot.qt</code> libre :
|
|
</li>
|
|
</ul>
|
|
|
|
<pre style="background:#263238; color:#eef7ff; padding:1rem; border-radius:0.35rem; overflow:auto;"><code>free_quantity = target_quantity - somme(lot.qt déjà matchés ou shippés)</code></pre>
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Si <code>free_quantity < 0</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">blocage : <code>Please unlink or unmatch lot</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Si un <code>lot.qt</code> libre existe :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">sa quantité est remplacée.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Si aucun <code>lot.qt</code> libre n'existe et <code>free_quantity > 0</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">création d'un nouveau <code>lot.qt</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Les fees de ligne sont resynchronisés.
|
|
</li>
|
|
</ul>
|
|
|
|
### Ajout de lots physiques
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Wizard : <code>lot.add</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Méthodes :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>LotQt.add_physical_lots</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>LotQt.add_physical_lot</code>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Source obligatoire : une ligne <code>lot.qt</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Ajout direct depuis un lot physique refusé.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Ajout physique côté vente par ce wizard refusé : utiliser <code>Apply matching</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Le lot physique reprend :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">ligne achat ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">vente matchée si présente ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">shipment ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">produit ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">unité ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">quantités ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">premium ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">chunk key.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Après création :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">réduction de la ligne <code>lot.qt</code> source ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">pas de quantité <code>lot.qt</code> négative ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">recalcul du lot virtuel ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">recalcul de <code>quantity</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">mise à jour moves et fees si nécessaire.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
### Retrait de lots physiques
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Wizard : <code>lot.remove</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Lot ouvert : retrait interdit.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Lot avec <code>stock.move</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">move obligatoire en <code>draft</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Lot matché ou shippé :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">warning confirmable.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Effets :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">suppression du move draft ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">restauration de la quantité dans <code>lot.qt</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">contexte restauré via shipment, <code>getVlot_p()</code>, <code>getVlot_s()</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">recalcul lot virtuel, <code>quantity</code>, fees.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
### Weighing / états de quantité
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Wizard : <code>lot.weighing</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Action UI : <code>Do weighing</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Écrit ou met à jour <code>lot.qt.hist</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Peut mettre à jour <code>lot_state</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Synchronise :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">lot ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">quantités ouvertes ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">fees.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Les vues <code>lot.qt.hist</code> sont consultatives.
|
|
</li>
|
|
</ul>
|
|
|
|
### Quantité compteur `quantity`
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Méthode : <code>Lot._recalc_line_quantity</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Sans physique :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>quantity</code> suit le lot virtuel.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Avec physiques :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>quantity</code> somme uniquement les lots physiques.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>quantity</code> est readonly côté ligne trade.
|
|
</li>
|
|
</ul>
|
|
|
|
### Montant de ligne
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Achat : <code>purchase.line.on_change_with_amount()</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Vente : <code>sale.line.on_change_with_amount()</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Helper :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>_get_amount_quantity()</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>_get_weight_basis_quantity()</code>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Priorités :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>finished = False</code> : <code>quantity_theorical</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>finished = True</code> + Weight basis disponible : somme physique dans cet état
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>finished = True</code> sans Weight basis exploitable : <code>quantity</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">fallback legacy : <code>quantity</code> si <code>quantity_theorical</code> vide
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
### Garde-fous Python
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Check central :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>lot.lot.assert_lines_quantity_consistency()</code>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Règle de déclenchement :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">bloquer les états finaux incohérents ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">ne pas bloquer les états transitoires internes d'un workflow ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">utiliser <code>Lot.skip_quantity_consistency()</code> uniquement autour d'une séquence qui rétablit ensuite les invariants ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">appeler un check final explicite après la séquence.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Blocage <code>lot.qt</code> orphelin non zéro :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>lot.qt.validate</code>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Appels après :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">modification <code>quantity_theorical</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">création / suppression de lots physiques ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">matching / unmatching ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">shipping / unshipping ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>Create contracts</code> en mode matched ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">weighing.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Le cas <code>created_by_code</code> est volontairement exclu du check immédiat <code>Lot.validate</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">le lot virtuel est sauvegardé avant que le <code>lot.qt</code> matched soit rattaché ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">l'invariant est contrôlé par le check final du workflow.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
### Diagnostic SQL
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Script :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><a href="sql/quantity_consistency_checks.sql">sql/quantity_consistency_checks.sql</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Usage :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">audit des bases de test ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">audit des données historiques ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">qualification avant correction.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Le script ignore totalement les <code>lot.qt = 0</code>.
|
|
</li>
|
|
</ul>
|
|
|
|
## Tests proches
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;"><code>modules/purchase_trade/tests/test_module.py</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Couverture existante :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>quantity</code> readonly ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">initialisation depuis <code>quantity_theorical</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">protection si lots physiques ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">amount sur théorique / physique / Weight basis ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">resynchronisation des lots virtuels ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">blocages quand l'open ne suffit plus.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Tests à ajouter :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>lot_hist</code> readonly ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>Do weighing</code> crée ou met à jour un état ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">lot virtuel sans saisie directe <code>lot_qt</code> / <code>lot_unit</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">contrôles SQL rejoués sur jeux de données incohérents.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|