Calculs et règles métier - PT1CE¶
Table des matières¶
- Calcul des nouvelles bornes
- Application des contraintes
- Détection des corridors sous-optimaux
- Calcul du taux de remise SAP
- Métriques de qualité
- Exemples concrets
Calcul des nouvelles bornes¶
Principe de base¶
PT1CE applique les écarts historiques sur les nouveaux PAS :
Implémentation SQL¶
-- Pour chaque borne
CASE
WHEN np.ID_ART IS NOT NULL AND c.ECART_PL1_PL2_PAS IS NOT NULL THEN
np.NEW_PAS + c.ECART_PL1_PL2_PAS
ELSE c.BORNE_PL1_PL2
END as NEW_BORNE_PL1_PL2
Gestion des NULL¶
- Si pas de nouveau PAS → garde l'ancienne borne
- Si écart NULL → garde l'ancienne borne
- Si article non présent dans CSV → pas de modification
Calcul vectorisé¶
Pour optimiser les performances :
# Numpy pour calcul en masse
valid_mask = (pas_actif > 0) & (ecarts.notna())
nouvelles_bornes = np.where(
valid_mask,
pas_actif + ecarts,
anciennes_bornes
)
Application des contraintes¶
Contrainte minimale¶
Règle : Une borne ne peut jamais être inférieure au PAS
CASE
WHEN np.NEW_PAS + c.ECART_PL1_PL2_PAS < np.NEW_PAS
THEN np.NEW_PAS
ELSE np.NEW_PAS + c.ECART_PL1_PL2_PAS
END
Cas d'application :
- Écarts négatifs (rare mais possible)
- Ajustements manuels incohérents
Contrainte maximale¶
Règle : Une borne ne peut pas dépasser le PRB approprié
CASE
-- Si PRB_TO_USE = 1, utiliser PRB_RC
WHEN c.PRB_TO_USE = 1 AND np.NEW_PAS + c.ECART > np.NEW_PRB_RC
THEN np.NEW_PRB_RC
-- Si PRB_TO_USE = 2, utiliser PRB_COLL
WHEN c.PRB_TO_USE = 2 AND np.NEW_PAS + c.ECART > np.NEW_PRB_COLL
THEN np.NEW_PRB_COLL
-- Sinon, garder le calcul
ELSE np.NEW_PAS + c.ECART
END
Ordre d'application¶
- Calcul de base (PAS + écart)
- Application contrainte min
- Application contrainte max
- Résultat final
Détection des corridors sous-optimaux¶
Critère principal : PL6 = PAS¶
Signification :
- La borne maximale a atteint le prix d'achat
- Plus de marge de manœuvre tarifaire
- Nécessite intervention manuelle
Classification détaillée¶
CASE
-- Problème double
WHEN s.NEW_BORNE_PL6_PLX = s.NEW_PAS
AND s.ECART_TYPE > 0.10
THEN 'PL6_ET_ECART_TYPE'
-- Problème simple PL6
WHEN s.NEW_BORNE_PL6_PLX = s.NEW_PAS
THEN 'PL6_EGAL_PAS'
-- Écart-type seul (reste optimal)
WHEN s.ECART_TYPE > 0.10
THEN 'ECART_TYPE_ELEVE'
-- Pas de problème
ELSE 'AUCUN'
END as PROBLEM_TYPE
Flags complémentaires¶
-- Flag écart-type élevé
CASE
WHEN s.ECART_TYPE > 0.10 THEN 1
ELSE 0
END as HAS_HIGH_STD
-- Flag PL6 = PAS
CASE
WHEN s.NEW_BORNE_PL6_PLX = s.NEW_PAS THEN 1
ELSE 0
END as HAS_PL6_EQUALS_PAS
Cohérence des bornes¶
-- Vérification ordre croissant
CASE
WHEN s.NEW_BORNE_PL1_PL2 <= s.NEW_BORNE_PL2_PL3
AND s.NEW_BORNE_PL2_PL3 <= s.NEW_BORNE_PL3_PL4
AND s.NEW_BORNE_PL3_PL4 <= s.NEW_BORNE_PL4_PL5
AND s.NEW_BORNE_PL4_PL5 <= s.NEW_BORNE_PL5_PL6
AND s.NEW_BORNE_PL5_PL6 <= s.NEW_BORNE_PL6_PLX
THEN 'COHERENT'
ELSE 'INCOHERENT'
END as BORNES_COHERENCE
Calcul du taux de remise SAP¶
Formule¶
Pour chaque palier :
Correspondance paliers SAP¶
Code SAP | Borne PT1CE | Description |
---|---|---|
ZRPL | NEW_BORNE_PL6_PLX | Remise palier libre |
ZP05 | NEW_BORNE_PL5_PL6 | Remise palier 5 |
ZP04 | NEW_BORNE_PL4_PL5 | Remise palier 4 |
ZP03 | NEW_BORNE_PL3_PL4 | Remise palier 3 |
ZP02 | NEW_BORNE_PL2_PL3 | Remise palier 2 |
ZPP1 | NEW_BORNE_PL1_PL2 | Remise palier 1 |
Implémentation¶
# Déterminer le PRB à utiliser
if corridor['PRB_TO_USE'] == 1:
prb_used = corridor['NEW_PRB_RC']
else: # PRB_TO_USE == 2
prb_used = corridor['NEW_PRB_COLL']
# Pour chaque palier
for code_tarif_sap, borne_col in tarif_mapping.items():
borne_value = corridor[borne_col]
# Calculer le taux (arrondi 2 décimales)
taux_remise = round((prb_used - borne_value) / prb_used, 2)
Gestion des cas particuliers¶
# PRB nul ou non défini
if pd.isna(prb_used) or prb_used == 0:
continue # Skip ce corridor
# Borne non définie
if pd.isna(borne_value):
continue # Skip ce palier
# Protection division par zéro (théoriquement impossible)
if prb_used == 0:
taux_remise = 0
Métriques de qualité¶
Évolution des prix moyens¶
-- Comparaison ancien/nouveau par TYPE_CLIENT
SELECT
TYPE_CLIENT,
-- PAS
AVG(PAS_ACTIF) as PAS_MOY_ANCIEN,
AVG(NEW_PAS) as PAS_MOY_NOUVEAU,
ROUND((AVG(NEW_PAS) - AVG(PAS_ACTIF)) / AVG(PAS_ACTIF) * 100, 2)
as EVOL_PAS_PCT,
-- Bornes (exemple PL1)
AVG(BORNE_PL1_PL2) as PL1_MOY_ANCIEN,
AVG(NEW_BORNE_PL1_PL2) as PL1_MOY_NOUVEAU,
ROUND((AVG(NEW_BORNE_PL1_PL2) - AVG(BORNE_PL1_PL2))
/ AVG(BORNE_PL1_PL2) * 100, 2) as EVOL_PL1_PCT
FROM comparison_table
WHERE STATUS = 'OPTIMAL'
GROUP BY TYPE_CLIENT
Distribution des écarts-types¶
SELECT
CASE
WHEN ECART_TYPE < 0.02 THEN '< 2%'
WHEN ECART_TYPE < 0.05 THEN '2% - 5%'
WHEN ECART_TYPE < 0.07 THEN '5% - 7%'
WHEN ECART_TYPE < 0.10 THEN '7% - 10%'
WHEN ECART_TYPE < 0.15 THEN '10% - 15%'
WHEN ECART_TYPE < 0.20 THEN '15% - 20%'
ELSE '> 20%'
END as TRANCHE_ECART_TYPE,
COUNT(*) as NB_CORRIDORS,
SUM(CA_TOTAL) as CA_TOTAL
FROM table
GROUP BY CASE...
ORDER BY MIN(ECART_TYPE)
Indicateurs de qualité globaux¶
- Taux d'optimisation : % corridors optimaux
- CA couvert : CA des corridors optimaux / CA total
- Dispersion moyenne : Écart-type moyen
- Cohérence : % corridors avec bornes cohérentes
Exemples concrets¶
Exemple 1 : Calcul standard¶
Données initiales :
- Ancien PAS : 10,00€
- Ancienne borne PL1 : 13,00€
- Écart : 13,00 - 10,00 = 3,00€
Nouveaux prix :
- Nouveau PAS : 11,00€
- Nouveau PRB_RC : 15,00€
Calcul :
1. Base : 11,00 + 3,00 = 14,00€
2. Min check : 14,00 > 11,00 ✓
3. Max check : 14,00 < 15,00 ✓
4. Résultat : NEW_BORNE_PL1_PL2 = 14,00€
Exemple 2 : Application contrainte max¶
Données :
- Ancien PAS : 20,00€
- Ancienne borne PL6 : 28,00€
- Écart : 28,00 - 20,00 = 8,00€
Nouveaux prix :
- Nouveau PAS : 22,00€
- Nouveau PRB_RC : 29,00€
Calcul :
1. Base : 22,00 + 8,00 = 30,00€
2. Min check : 30,00 > 22,00 ✓
3. Max check : 30,00 > 29,00 ✗
4. Résultat : NEW_BORNE_PL6_PLX = 29,00€ (plafonné)
Exemple 3 : Corridor sous-optimal¶
Après application :
- NEW_PAS : 15,00€
- NEW_BORNE_PL1_PL2 : 16,50€
- NEW_BORNE_PL2_PL3 : 16,00€
- NEW_BORNE_PL3_PL4 : 15,80€
- NEW_BORNE_PL4_PL5 : 15,50€
- NEW_BORNE_PL5_PL6 : 15,20€
- NEW_BORNE_PL6_PLX : 15,00€ ⚠️
Détection :
- PL6 = PAS → STATUS = 'SUBOPTIMAL'
- PROBLEM_TYPE = 'PL6_EGAL_PAS'
- Nécessite correction manuelle
Exemple 4 : Calcul taux SAP¶
Corridor :
- ID_ART : '075130'
- PRB_TO_USE : 1
- NEW_PRB_RC : 20,00€
- NEW_BORNE_PL1_PL2 : 18,00€
Export SAP :
- Type tarif : '01'
- Palier : 'ZPP1'
- Montant : (20,00 - 18,00) / 20,00 = 0,10
- → Taux de remise : 10%
Exemple 5 : Évolution avec hausse PAS¶
Article 075150 :
- Ancien PAS : 3,456€
- Nouveau PAS : 3,865€ (+11.8%)
Impact sur les bornes :
- PL1 : 3,665€ → 4,098€ (+11.8%)
- PL2 : 3,855€ → 4,310€ (+11.8%)
- PL3 : 4,275€ → 4,780€ (+11.8%)
- PL4 : 4,660€ → 5,211€ (+11.8%)
- PL5 : 5,115€ → 5,721€ (+11.8%)
- PL6 : 5,820€ → 6,508€ (+11.8%)
→ Les écarts absolus sont conservés
→ Les % de hausse suivent le PAS