Diagrammes Step 06 - Valuation of Volume Effects
Vue d'ensemble du processus
graph TB
Start([main]) --> M1[main_margin_computation]
M1 --> M2[main_valuation_computation]
M2 --> M3[main_cannibalization_computation]
subgraph "Phase 1: Calcul des marges"
M1A[Lecture sell_in_base]
M1B[Calcul marges ajustées]
M1C[Agrégation par produit/année]
M1D[Merge avec effects_baseline]
M1A --> M1B --> M1C --> M1D
end
subgraph "Phase 2: Valorisation"
M2A[Lecture model_with_margin_kpi]
M2B[Baseline_GM = Volume × Marge]
M2C[Sauvegarde model_margins]
M2A --> M2B --> M2C
end
subgraph "Phase 3: Cannibalisation"
M3A[Agrégation famille]
M3B[Calcul ratio cannibalisation]
M3C[Répartition volumes/marges]
M3D[Sauvegarde effects finale]
M3A --> M3B --> M3C --> M3D
end
M1 --> M1A
M1D --> M2
M2 --> M2A
M2C --> M3
M3 --> M3A
M3D --> End([Fin])
Flux de données détaillé
flowchart LR
subgraph "Tables entrée"
T1[(step_2_03_sell_in_base)]
T2[(step_4_01_model_with_effects_baseline)]
end
subgraph "Tables intermédiaires"
I1[(step_5_01_model_with_margin_kpi)]
I2[(step_5_02_model_margins)]
end
subgraph "Table sortie"
O1[(step_5_03_model_cannibalization_effects)]
end
T1 --> PC1[Phase 1:<br/>Calcul marges]
T2 --> PC1
PC1 --> I1
I1 --> PC2[Phase 2:<br/>Valorisation]
PC2 --> I2
I2 --> PC3[Phase 3:<br/>Cannibalisation]
PC3 --> O1
style I1 fill:#e3f2fd
style I2 fill:#fff3e0
style O1 fill:#90EE90
Phase 1 : Calcul des marges - Comparaison Galbani/Parmalat
graph TD
subgraph "Galbani"
G1[Lecture sell_in_base]
G2[Extract Year from Period]
G3[Calcul Adjusted_gross_margin]
G4[Agrégation EAN×EAN_desc×Year]
G5[Moyenne pondérée volumes]
G6[Merge avec baseline effects]
G1 --> G2 --> G3
G3 --> G4 --> G5 --> G6
note1[Adjusted_GM = Gross_margin<br/>+ Supply_chain_gap × Volumes]
G3 -.-> note1
end
subgraph "Parmalat"
P1[Lecture sell_in_base]
P2[Vérif marges pré-calculées]
P3{Marges<br/>existantes?}
P4[Utiliser Promo_margin_per_unit]
P5[Fallback: calcul manuel]
P6[Agrégation EAN×Year<br/>Sans EAN_desc!]
P7[Merge avec baseline effects]
P1 --> P2 --> P3
P3 -->|Oui| P4
P3 -->|Non| P5
P4 --> P6
P5 --> P6
P6 --> P7
note2[Marges calculées en Step 3:<br/>Product_margin + Supply_chain_gap<br/>+ Fixed_industrial_costs]
P2 -.-> note2
end
style G3 fill:#e3f2fd
style P5 fill:#ffebee
Phase 2 : Valorisation baseline
stateDiagram-v2
[*] --> LoadData: compute_valuation_baseline_effects_{country}
LoadData --> CalcGM: Chargement step_5_01
CalcGM --> SaveResults: Calcul simple
state CalcGM {
[*] --> Formula
Formula: Baseline_GM_excl_promo_adjustment =
Formula: Baseline_Volume × Promo_margin
}
SaveResults --> [*]: step_5_02_model_margins
note right of CalcGM
Identique pour tous les
business units
Simple multiplication
end note
Phase 3 : Cannibalisation - Flux général
flowchart TD
Start("compute_cannibalization_{country}") --> Load(Charger step_5_02_model_margins)
Load --> CalcOriginal(Cannib_GM = Cannib_Volume × Promo_margin)
CalcOriginal --> Aggregate(Agrégation par famille)
subgraph "Agrégation famille"
A1("GROUP BY Category/New_category,<br/>Retailer, Year, Week")
A2("SUM Uplift_Volume → Family_Uplift")
A3("SUM Cannib_Volume → Family_Cannib")
A4("SUM Cannib_GM → Total_Family_GM")
A1 --> A2
A1 --> A3
A1 --> A4
end
Aggregate --> A1
A4 --> PondGM("Ponderated_Family_Cannib_GM =<br/>Total_Family_GM / Family_Cannib_Volume")
PondGM --> CalcRatio("Ratio_Cannibalizing = Uplift_i / Family_Uplift")
CalcRatio --> Distribute(Distribution volumes et marges)
subgraph "Distribution"
D1("Cannibalizing_Volume =<br/>Ratio × Family_Cannib_Volume")
D2("Cannibalizing_GM =<br/>Ratio × Family_Cannib × Ponderated_GM")
end
Distribute --> D1
Distribute --> D2
D2 --> Save(Sauvegarder step_5_03)
Cannibalisation Parmalat - Restriction UHT
graph LR
subgraph "Filtrage initial"
F1[Toutes catégories]
F2{New_category in<br/>UHT milk?}
F3[UHT normal milk<br/>UHT lactose free milk]
F4[Autres catégories]
F1 --> F2
F2 -->|Oui| F3
F2 -->|Non| F4
end
subgraph "Traitement UHT"
U1[Calcul cannibalisation normal]
U2[Agrégation famille]
U3[Répartition proportionnelle]
F3 --> U1 --> U2 --> U3
end
subgraph "Traitement autres"
O1[Tous metrics = 0]
O2[Cannibalizing_Volume = 0]
O3[Cannibalizing_GM = 0]
F4 --> O1 --> O2 --> O3
end
U3 --> Merge[Concat DataFrames]
O3 --> Merge
Merge --> Output[step_5_03 finale]
style F3 fill:#e8f5e9
style F4 fill:#ffebee
graph TD
subgraph "Moyenne pondérée marge (Galbani)"
MW1("Pour chaque groupe EAN×EAN_desc×Year")
MW2("weighted_margin_sum = Σ(Adjusted_gross_margin)")
MW3("total_volumes = Σ(Volumes)")
MW4("Promo_margin = weighted_margin_sum / total_volumes")
MW1 --> MW2
MW1 --> MW3
MW2 --> MW4
MW3 --> MW4
end
subgraph "Ratio cannibalisation"
RC1("Galbani: Uplift only")
RC2("Ratio = Uplift_i / Σ(Uplift_famille)")
RC3("Default: Uplift + Halo")
RC4("Ratio = (Uplift_i + Halo_i) /<br/>Σ(Uplift_famille + Halo_famille)")
RC1 --> RC2
RC3 --> RC4
end
subgraph "Protection division"
SD1("safe_divide(numerator, denominator)")
SD2("denominator = 0 → NaN")
SD3("numerator = ±inf → NaN")
SD4("result.fillna(default_value)")
SD1 --> SD2
SD1 --> SD3
SD2 --> SD4
SD3 --> SD4
end
Gestion des erreurs et cas limites
flowchart TD
subgraph "Types d'erreurs"
E1(Division par zéro)
E2(Colonnes manquantes)
E3(Volumes nuls)
E4(Marges extrêmes)
end
subgraph "Stratégies de gestion"
S1("safe_divide() systématique")
S2(Vérification existence colonnes)
S3(Protection moyenne pondérée)
S4(Logs WARNING)
end
E1 --> S1
E2 --> S2
E3 --> S3
E4 --> S4
subgraph "Résultats"
R1(Continuation pipeline)
R2(Valeurs NaN neutres)
R3(Fallback calculations)
S1 --> R2
S2 --> R3
S3 --> R2
S4 --> R1
end
Dispatcher principal - apply_*_computation()
flowchart LR
Start("apply_{operation}_computation")
Build("Construire nom fonction:<br/>{operation}_{business_unit}")
Check{Fonction<br/>existe?}
Start --> Build --> Check
Check -->|Oui| Specific(Appeler fonction spécifique)
Check -->|Non| Default("Appeler {operation}_default")
Specific --> Log1("Log: using BU-specific logic")
Default --> Log2("Log: using default logic")
subgraph "Exemples"
Ex1(compute_margin_italy_galbani)
Ex2(compute_margin_italy_parmalat)
Ex3(compute_margin_default)
end
style Specific fill:#e8f5e9
style Default fill:#fff3e0
Points clés de l'implémentation
mindmap
root((Step 06<br/>Valuation))
Marges
Galbani
Adjusted gross margin
Supply chain gap
Moyenne pondérée
Parmalat
Marges pré-calculées
Step 3 réutilisation
Fallback si absent
Valorisation
Simple multiplication
Baseline × Marge
Identique tous BU
Cannibalisation
Famille = catégorie
Ratio proportionnel
Galbani: uplift seul
Parmalat: UHT only
Default: uplift + halo
Techniques
safe_divide partout
Agrégations vectorisées
Gestion mémoire
Logs détaillés