394 lines
16 KiB
Markdown
394 lines
16 KiB
Markdown
<!-- Generated from docs_source/business by docs/tools/render_business_docs.py. -->
|
|
|
|
# Fees
|
|
|
|
Langue : `fr`
|
|
Page miroir : [fees.en.md](fees.en.md)
|
|
Statut : `migration partielle`
|
|
|
|
Voir aussi la page technique historique : `../fees.md`.
|
|
|
|
<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>Un fee porte un montant, mais sa quantité doit rester alignée avec les lots qui le composent. Le mode <code>Per packing</code> est la seule exception : il suit une quantité de colisage, pas le poids du lot.</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;">Repère</th>
|
|
<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é</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.quantity</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Somme des lots liés dans <code>fee.lots</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">État</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.qt_state</code> vide</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Utilise le <code>weight basis</code> du contrat.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">État</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.qt_state</code> renseigné</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Utilise cet état, plafonné au <code>weight basis</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Fallback</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">état absent sur le lot</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Prend l'état antérieur le plus proche par <code>sequence</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Net / brut</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.weight_type</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>net</code> lit <code>quantity</code>, <code>brut</code> lit <code>gross_quantity</code>.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Packing</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>ppack</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Quantité de packing, décorrélée du poids.</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Contrôle</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Python + SQL</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Check applicatif et diagnostic SQL.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
## Règles consultant
|
|
|
|
### BR-PT-FEE-001 - Freight value depuis fee shipment
|
|
|
|
Source : `BR-PT-003`
|
|
|
|
#### Règle consultant
|
|
|
|
La valeur de fret affichée sur les documents facture vient du fee maritime du
|
|
shipment, pas d'un champ direct de la facture.
|
|
|
|
#### Notes développeur
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Retrouver le lot physique depuis la facture.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Retrouver son <code>shipment_in</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Chercher le <code>fee.fee</code> avec <code>product.name = 'Maritime freight'</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Utiliser <code>fee.get_amount()</code>.
|
|
</li>
|
|
</ul>
|
|
|
|
### BR-PT-FEE-002 - Lots effectifs des fees
|
|
|
|
Source : `BR-PT-021`
|
|
|
|
#### Règle consultant
|
|
|
|
Un fee suit le lot virtuel tant qu'aucun lot physique n'est lié. Dès qu'un lot
|
|
physique est lié, les lots physiques deviennent la base de calcul du fee.
|
|
|
|
#### Notes développeur
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Ne pas supprimer le lien virtuel : il reste le fallback.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Les lots effectifs sont :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">les physiques si au moins un physique est lié ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">sinon les virtuels.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">La même sélection s'applique au PnL fee.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Points de synchronisation :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">création fee ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">lien <code>fee.lots</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">changement de <code>quantity_theorical</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">weighing ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">suppression de physique.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
### BR-PT-FEE-003 - Quantité du fee
|
|
|
|
#### Règle consultant
|
|
|
|
La quantité d'un fee suit la vie de la quantité des lots qui lui sont liés. Elle
|
|
doit représenter la somme des quantités de ces lots dans l'état contractuel
|
|
autorisé.
|
|
|
|
#### Règle courte
|
|
|
|
<pre style="background:#263238; color:#eef7ff; padding:1rem; border-radius:0.35rem; overflow:auto;"><code>fee.quantity = somme(quantité applicable des lots effectifs fee.lots)</code></pre>
|
|
|
|
#### Sélection de l'état 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;">Cas</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;">État cible</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.qt_state</code> vide</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>weight basis</code> du contrat porteur du fee</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.qt_state</code> renseigné</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.qt_state</code>, sauf s'il est postérieur au <code>weight basis</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.qt_state</code> postérieur au <code>weight basis</code></td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>weight basis</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">état cible absent du lot</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">état antérieur le plus proche par <code>lot.qt.type.sequence</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">aucun état cible disponible</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">poids courant du lot, seulement si aucun <code>weight basis</code> ne s'applique</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
#### Source du `weight basis`
|
|
|
|
<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;">Fee</th>
|
|
<th style="text-align:left; padding:0.55rem 0.7rem; border-bottom:2px solid #4051b5;"><code>weight basis</code></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Fee achat</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.line.purchase.wb.qt_type</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Fee vente</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;"><code>fee.sale_line.sale.wb.qt_type</code></td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Fee shipment</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">weight basis achat du lot si présent</td>
|
|
</tr>
|
|
<tr style="border-bottom:1px solid #e0e0e0;">
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">Fee shipment sans achat</td>
|
|
<td style="vertical-align:top; padding:0.5rem 0.7rem;">weight basis vente du lot si présent</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
#### Net / brut
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Si <code>fee.weight_type = net</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">lire <code>lot.qt.hist.quantity</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Si <code>fee.weight_type = brut</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">lire <code>lot.qt.hist.gross_quantity</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
#### Per packing
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;"><code>mode = ppack</code> est exclu de la règle poids.
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>fee.quantity</code> représente une quantité de packing.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Cette quantité peut être décorrélée du poids net ou brut.
|
|
</li>
|
|
</ul>
|
|
|
|
#### Lump sum
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;"><code>mode = lumpsum</code> suit aussi la règle de quantité.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Le montant reste forfaitaire.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">La quantité permet de calculer un prix par tonne plus précis.
|
|
</li>
|
|
</ul>
|
|
|
|
### BR-PT-FEE-004 - Fees `% rate` via delta de financement
|
|
|
|
Source : `BR-PT-016` historique et notes `2026-04-30`
|
|
|
|
#### Règle 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 développeur
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Formule : <code>amount = unit_price * quantity * (price / 100) * fin_int_delta / 360</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Source du delta : ligne <code>Estimated date</code> avec <code>trigger = bldate</code>.
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Si aucune ligne <code>bldate</code> n'existe, ne pas calculer de montant <code>% rate</code>.
|
|
</li>
|
|
</ul>
|
|
|
|
## 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;">Fee : <code>fee.fee</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Lots du fee : <code>fee.lots</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Quantité du fee : <code>fee.fee.quantity</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Mode : <code>fee.fee.mode</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">État de quantité optionnel : <code>fee.fee.qt_state</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Net / brut : <code>fee.fee.weight_type</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">État de quantité lot : <code>lot.qt.hist.quantity_type</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Quantité nette : <code>lot.qt.hist.quantity</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Quantité brute : <code>lot.qt.hist.gross_quantity</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Ordre des états : <code>lot.qt.type.sequence</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Weight basis achat / vente : <code>purchase.weight.basis.qt_type</code>
|
|
</li>
|
|
</ul>
|
|
|
|
### Fonctions de calcul
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;"><code>Fee._get_effective_fee_lots()</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">sélectionne physiques puis virtuels.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>Fee._target_qt_type_for_lot()</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">choisit <code>fee.qt_state</code> ou le <code>weight basis</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">plafonne l'état au <code>weight basis</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>Fee._select_lot_qt_type()</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">prend l'état exact s'il existe ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">sinon prend l'état antérieur le plus proche par <code>sequence</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>Fee._get_lot_fee_quantity()</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">lit net ou brut selon <code>weight_type</code>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>Fee.sync_quantity_from_lots()</code> :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">resynchronise <code>fee.quantity</code>.
|
|
</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>fee.fee.assert_quantity_consistency()</code>
|
|
</li>
|
|
<li style="margin:0.38rem 0;"><code>fee.fee.assert_quantities_consistency()</code>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Points 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;">création de fee ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">modification de fee ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">création / modification / suppression de <code>fee.lots</code> ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">weighing via resynchronisation des fees liés.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li style="margin:0.38rem 0;">Exception :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;"><code>mode = ppack</code> n'est pas contrôlé comme un poids.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
### Gap connu
|
|
|
|
<ul style="margin:0.65rem 0 1rem 1.1rem; padding-left:1rem; list-style-type:disc;">
|
|
<li style="margin:0.38rem 0;">Split / merge de lots :
|
|
<ul style="margin:0.65rem 0 1rem 1.35rem; padding-left:1rem; list-style-type:circle;">
|
|
<li style="margin:0.38rem 0;">le flux peut cloner ou créer des lots physiques ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">le recâblage de <code>fee.lots</code> vers les nouveaux lots n'est pas encore garanti ;
|
|
</li>
|
|
<li style="margin:0.38rem 0;">les fees concernés doivent donc être contrôlés par le diagnostic SQL après utilisation de ce flux.
|
|
</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/fee_quantity_consistency_checks.sql">sql/fee_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 remonte les fees non <code>ppack</code> dont <code>fee.quantity</code> ne correspond pas à la somme des lots effectifs selon l'état de quantité applicable.
|
|
</li>
|
|
</ul>
|