Aller au contenu

Calculs et règles métier - PT1CE

Table des matières

  1. Calcul des nouvelles bornes
  2. Application des contraintes
  3. Détection des corridors sous-optimaux
  4. Calcul du taux de remise SAP
  5. Métriques de qualité
  6. Exemples concrets

Calcul des nouvelles bornes

Principe de base

PT1CE applique les écarts historiques sur les nouveaux PAS :

Écart = Ancienne borne - Ancien PAS
Nouvelle borne = Nouveau PAS + Écart

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

  1. Calcul de base (PAS + écart)
  2. Application contrainte min
  3. Application contrainte max
  4. Résultat final

Détection des corridors sous-optimaux

Critère principal : PL6 = PAS

CASE 
    WHEN s.NEW_BORNE_PL6_PLX = s.NEW_PAS THEN 'SUBOPTIMAL'
    ELSE 'OPTIMAL'
END as STATUS

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 :

Taux de remise = (PRB - Borne) / PRB

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