Formats d'export et analyses - PT2QE¶
Organisation des fichiers générés¶
Structure des dossiers de sortie¶
outputs/
├── run_YYYYMMDD_HHMMSS/ # Exécution initiale (Option 1)
│ ├── recommendations_detail.csv
│ ├── statistics_by_dimension.csv
│ ├── impact_analysis.csv
│ ├── price_increase_distribution.csv
│ ├── decision_path_analysis.csv
│ ├── capping_distribution.csv
│ ├── capping_cubes_generated.csv
│ └── summary.txt
│
├── corrections_YYYYMMDD_HHMMSS/ # Après ajustement cappings (Option 2)
│ ├── [mêmes fichiers que run_*]
│ └── [versions recalculées]
│
└── final_YYYYMMDD_HHMMSS/ # Export final (Option 3)
├── final_price_offers.csv
├── validation_report.csv
└── export_summary.txt
Scope temporel : Les dossiers sont horodatés au moment de l'exécution. Les données extraites couvrent les 4 derniers trimestres fiscaux complets par rapport à la date d'exécution.
Fichier 1 : recommendations_detail.csv¶
Description¶
Export ligne à ligne de TOUTES les recommandations calculées. C'est le fichier le plus complet contenant la cascade complète de calcul.
Scope : ZOOM1 uniquement, offres de prix valides au moment de l'extraction.
Scope temporel : - Offres actuelles : valides au moment de l'exécution (DT_FIN > date du jour) - Historique transactionnel : 4 derniers trimestres fiscaux complets - Exemple : si exécution le 15/01/2025, historique couvre 4 quarters avant Q4 2024
Structure détaillée¶
Bloc 1 : Identifiants et infos condition (colonnes 1-7)¶
ID_CLN : Identifiant client Sysco
LC_CLN : Libellé client
ID_ART : Identifiant article Sysco
LC_ART : Libellé article
ID_CND : Identifiant condition de prix
DT_DEB_CONDITION : Date début validité condition
DT_FIN_CONDITION : Date fin validité condition
Bloc 2 : Catégories produit (colonnes 8-15)¶
CATEGORIE_N1 à N6 : Hiérarchie article complète (du plus agrégé au plus fin)
MARQUE : Marque produit
LC_ATTRIBUT : Attribut produit (ex: "Basiques", "Premium")
LC_ATTRIBUT = "Basiques" déclenche le capping à +50% en cascade.
Bloc 3 : Dimensions tarifaires (colonnes 16-20)¶
TYPE_CLIENT : Segment client (ex: "RCI PI GI", "RSI HM")
TYPE_RESTAURANT : Type établissement (ex: "TRADITIONNEL", "RESTAURATION_RAPIDE")
GEO : Zone géographique (ex: "NORD", "SUD")
UNIVERS : ZOOM1 (exclusif dans PT2QE)
MATCH_TYPE : Type de matching corridor
- "MASTER" : corridor spécifique trouvé
- "NATIONAL" : fallback corridor national
Bloc 4 : Métriques transactionnelles 4Q (colonnes 21-29)¶
Scope temporel : 4 derniers trimestres fiscaux complets
MT_CAB_4Q : CA total sur période (hors prix promo)
QT_UF_4Q : Volume en UF (Unité de Facturation) sur période
QT_KG_4Q : Volume en KG sur période
MT_CAB_4Q_FERMES : CA sur prix fermes uniquement
QT_UF_4Q_FERMES : Volume UF sur prix fermes
QT_KG_4Q_FERMES : Volume KG sur prix fermes
MT_CAB_4Q_INDEXES : CA sur prix indexés uniquement
QT_UF_4Q_INDEXES : Volume UF sur prix indexés
QT_KG_4Q_INDEXES : Volume KG sur prix indexés
Filtres appliqués : - Hors prix promo (TRIM(LC_PRP_N1) <> 'Prix promo') - Factures ZF2 uniquement - FG_PRESTA = '0' (hors prestations) - FG_MARCHANDISE IN ('X', '1')
Bloc 5 : Prix actuels et positions (colonnes 30-33)¶
PRIX_TARIF_ACTUEL : Prix condition actuelle
PRIX_UNITAIRE_ACTUEL : Prix unitaire (identique à PRIX_TARIF_ACTUEL)
POSITION_TARIF_ACTUEL_DANS_ANCIENNES_BORNES : Position dans corridor PT0CE
Valeurs: ABOVE_PRB, PL1, PL2, PL3,
PL4, PL5, PL6, PLX, BELOW_PAS
PALIER_TARIF_ACTUEL_VS_NOUVELLES_BORNES : Position dans corridor PT1CE
(après recalibrage PT1CE)
Valeurs: idem ci-dessus
POSITION_NOUVEAU_PRIX_DANS_NOUVELLES_BORNES : Position après application reco PT2QE
Valeurs: idem ci-dessus
Les 3 positions permettent de voir : 1. D'où on part (anciennes bornes) 2. Où on est après recalibrage PT1CE 3. Où on arrive après optimisation PT2QE
Bloc 6 : Cascade de calcul recommandations (colonnes 34-37)¶
RECO1_BASE : Repositionnement paliers BRUT (sans capping)
RECO1_APRES_CAPPING_SENSIBILITE : Après étape 1 de capping (HIGH/MEDIUM/LOW)
RECO1_AVEC_CAPPING : Après cascade complète (sensibilité + basiques 50%)
RECO2 : Hausse proportionnelle au PAS
Cascade visible :
RECO1_BASE
↓ capping sensibilité (2.5%, 5%, 7.5% selon HIGH/MEDIUM/LOW)
RECO1_APRES_CAPPING_SENSIBILITE
↓ capping basiques (+50% max si LC_ATTRIBUT = "Basiques")
RECO1_AVEC_CAPPING
Bloc 7 : Décision finale et traçabilité (colonnes 38-42)¶
DECISION_PATH : Chemin emprunté dans l'arbre de décision
- "PAS_BAISSE_GEL_PRIX" : Gel total (NEW_PAS < PAS_ACTIF)
- "PL1_CONSERVATION_PREMIUM" : Maintien clients premium
- "OPTIMISATION_STANDARD" : Optimisation classique
RECO_TYPE : Type recommandation gagnante (description courte)
- "GEL_PRIX"
- "CONSERVATION_PREMIUM"
- "REPOSITIONNEMENT_PALIERS"
- "HAUSSE_PROPORTIONNELLE_PAS"
RECO_SELECTIONNEE : Nom explicite de la recommandation retenue
- "GEL_PRIX"
- "CONSERVATION_PREMIUM"
- "RECO1_REPOSITIONNEMENT_PALIERS"
- "RECO2_HAUSSE_PROPORTIONNELLE_PAS"
CAPPING_APPLIED : Capping le plus contraignant appliqué (ordre priorité)
1. "GEL_PAS" : Gel total
2. "PRB_FINAL" : Plafond PRB absolu
3. "PLANCHER_PL2_PL3" : Plancher sécurité (CHEMIN 2)
4. "BASIQUES_50PCT" : Capping produits basiques
5. "SENSIBILITE" : Capping sensibilité prix
6. "NONE" : Aucun capping
Bloc 8 : Résultat final (colonnes 43-44)¶
PRIX_RECOMMANDE : Prix final après arbre décision + capping PRB
PCT_HAUSSE_FINALE : % hausse appliqué (format décimal : 0.0345 = 3.45%)
Format fichier¶
- Séparateur : point-virgule (;)
- Décimale : virgule (,)
- Encoding : CP1252 (compatible Excel Windows)
- Tri : PCT_HAUSSE_FINALE DESC (hausses les plus fortes en premier)
Exemple de lignes¶
ID_CLN;LC_CLN;ID_ART;LC_ART;TYPE_CLIENT;PRIX_TARIF_ACTUEL;RECO1_BASE;RECO1_AVEC_CAPPING;RECO2;PRIX_RECOMMANDE;PCT_HAUSSE_FINALE;DECISION_PATH;CAPPING_APPLIED
12345;RESTAURANT CHEZ PAUL;075130;FILET BOEUF 1KG;RCI PI GI;45,750;48,200;47,900;47,500;47,900;4,70;OPTIMISATION_STANDARD;SENSIBILITE
12346;BRASSERIE DU CENTRE;075131;SAUMON FUME 500G;RSI HM;28,500;28,500;28,500;29,350;28,500;0,00;PAS_BAISSE_GEL_PRIX;GEL_PAS
Comment modifier le tri¶
Localisation : analyze_recommendations.py ligne ~55
Modifier la clause ORDER BY :
Exemples de tris alternatifs :
ORDER BY TYPE_CLIENT, TYPE_RESTAURANT, ID_CLN, ID_ART -- Tri logique
ORDER BY MT_CAB_4Q DESC -- Plus gros CA d'abord
ORDER BY ID_CLN, ID_ART -- Tri client/article
Comment ajouter une colonne¶
Localisation : analyze_recommendations.py méthode _export_recommendations_detail
-
Ajouter la colonne dans le SELECT :
-
Aucune modification du code Python nécessaire (lecture automatique)
Fichier 2 : statistics_by_dimension.csv¶
Description¶
Agrégations par dimension clé (TYPE_CLIENT, TYPE_RESTAURANT, UNIVERS).
Scope : ZOOM1 uniquement
Structure¶
DIMENSION : Nom de la dimension ("TYPE_CLIENT", "TYPE_RESTAURANT", "UNIVERS")
VALEUR : Valeur spécifique de la dimension (ex: "RCI PI GI")
NB_OFFRES : Nombre d'offres dans ce segment
NB_CLIENTS : Clients uniques
NB_ARTICLES : Articles uniques
PRIX_MOY_ACTUEL : Prix moyen actuel
PRIX_MOY_RECOMMANDE: Prix moyen recommandé
PCT_HAUSSE_MOY : Hausse moyenne en % (format décimal)
PCT_HAUSSE_MIN : Hausse minimale
PCT_HAUSSE_MAX : Hausse maximale
PCT_HAUSSE_STDDEV : Écart-type des hausses
Format¶
- Séparateur : ;
- Décimale : ,
- Encoding : CP1252
Exemple¶
DIMENSION;VALEUR;NB_OFFRES;NB_CLIENTS;NB_ARTICLES;PRIX_MOY_ACTUEL;PRIX_MOY_RECOMMANDE;PCT_HAUSSE_MOY
TYPE_CLIENT;RCI PI GI;234567;12345;8765;34,56;35,78;3,53
TYPE_CLIENT;RSI HM;123456;6789;5432;28,90;29,75;2,94
TYPE_RESTAURANT;TRADITIONNEL;189012;8901;7654;31,23;32,18;3,04
Comment ajouter une dimension¶
Localisation : analyze_recommendations.py méthode _export_statistics_by_dimension
Dupliquer un des blocs de requête :
query_geo = f"""
SELECT
'GEO' as DIMENSION,
GEO as VALEUR,
COUNT(*) as NB_OFFRES,
-- ... autres métriques
FROM {table}
GROUP BY GEO
"""
Ajouter à la liste :
Fichier 3 : impact_analysis.csv¶
Description¶
Analyse d'impact CA et distribution des hausses par segment TYPE_CLIENT × UNIVERS.
Scope : ZOOM1 uniquement
Structure¶
Métriques volumétriques¶
Métriques CA¶
CA_ACTUEL : Somme des prix tarif actuels (€, 2 décimales)
CA_FUTUR : Somme des prix recommandés (€, 2 décimales)
IMPACT_EUROS : Gain CA en euros (CA_FUTUR - CA_ACTUEL)
IMPACT_PCT : Gain CA en % ((CA_FUTUR/CA_ACTUEL - 1) × 100)
HAUSSE_MOY_PCT : Hausse moyenne pondérée (%)
Formule IMPACT_PCT :
Distribution des hausses (nombres absolus)¶
NB_SANS_HAUSSE : Offres avec 0% de hausse
NB_0_2PCT : Offres ]0%, 2%]
NB_2_5PCT : Offres ]2%, 5%]
NB_5_10PCT : Offres ]5%, 10%]
NB_10_15PCT : Offres ]10%, 15%]
NB_15_20PCT : Offres ]15%, 20%]
NB_PLUS_20PCT : Offres > 20%
Distribution des hausses (pourcentages)¶
PCT_SANS_HAUSSE : % d'offres sans hausse
PCT_0_2 : % d'offres 0-2%
PCT_2_5 : % d'offres 2-5%
PCT_5_10 : % d'offres 5-10%
PCT_10_15 : % d'offres 10-15%
PCT_15_20 : % d'offres 15-20%
PCT_PLUS_20 : % d'offres > 20%
Format¶
- Séparateur : ;
- Décimale : ,
- Encoding : CP1252
- Tri : TYPE_CLIENT, UNIVERS
Exemple¶
TYPE_CLIENT;UNIVERS;NB_OFFRES;CA_ACTUEL;CA_FUTUR;IMPACT_EUROS;IMPACT_PCT;HAUSSE_MOY_PCT;NB_SANS_HAUSSE;NB_0_2PCT;PCT_SANS_HAUSSE;PCT_0_2
RCI PI GI;ZOOM1;234567;12345678,50;12789456,30;443777,80;3,59;3,78;23456;89012;10,0;37,9
Comment modifier les tranches de distribution¶
Localisation : analyze_recommendations.py ligne ~195
Modifier les seuils dans les CASE :
-- Exemple : ajouter une tranche 0-1%
SUM(CASE WHEN PCT_HAUSSE_FINALE > 0 AND PCT_HAUSSE_FINALE <= 0.01 THEN 1 ELSE 0 END) as NB_0_1PCT,
SUM(CASE WHEN PCT_HAUSSE_FINALE > 0.01 AND PCT_HAUSSE_FINALE <= 0.02 THEN 1 ELSE 0 END) as NB_1_2PCT,
Ajouter aussi le calcul du pourcentage :
Fichier 4 : price_increase_distribution.csv¶
Description¶
Histogramme global des hausses de prix par tranche détaillée (10 buckets).
Scope : ZOOM1, toutes offres confondues
Structure¶
TRANCHE_HAUSSE : Libellé de la tranche
Format: "01. 0-2%", "02. 2-5%", etc.
Préfixe numérique pour tri correct
NB_OFFRES : Nombre d'offres dans cette tranche
NB_CLIENTS_UNIQUES : Clients distincts touchés
NB_ARTICLES_UNIQUES : Articles distincts touchés
PRIX_MOY_ACTUEL : Prix moyen actuel dans la tranche (€, 2 déc)
PRIX_MOY_RECOMMANDE : Prix moyen recommandé dans la tranche (€, 2 déc)
HAUSSE_MIN_PCT : Hausse minimale dans la tranche (%, 2 déc)
HAUSSE_MAX_PCT : Hausse maximale dans la tranche (%, 2 déc)
HAUSSE_MOY_PCT : Hausse moyenne dans la tranche (%, 2 déc)
PCT_OFFRES : % du total des offres (1 déc)
PCT_CUMULE : % cumulé (1 déc)
Tranches utilisées¶
00. Pas de hausse : 0%
01. 0-2% : ]0%, 2%]
02. 2-5% : ]2%, 5%]
03. 5-7% : ]5%, 7%]
04. 7-10% : ]7%, 10%]
05. 10-12% : ]10%, 12%]
06. 12-15% : ]12%, 15%]
07. 15-17% : ]15%, 17%]
08. 17-20% : ]17%, 20%]
09. Plus de 20% : > 20%
Format¶
- Séparateur : ;
- Décimale : ,
- Encoding : CP1252
- Tri : TRANCHE_HAUSSE (ordre numérique du préfixe)
Exemple¶
TRANCHE_HAUSSE;NB_OFFRES;NB_CLIENTS_UNIQUES;NB_ARTICLES_UNIQUES;PRIX_MOY_ACTUEL;PRIX_MOY_RECOMMANDE;HAUSSE_MIN_PCT;HAUSSE_MAX_PCT;HAUSSE_MOY_PCT;PCT_OFFRES;PCT_CUMULE
00. Pas de hausse;45678;3456;2345;32,45;32,45;0,00;0,00;0,00;15,2;15,2
01. 0-2%;78901;5678;4321;28,90;29,35;0,05;2,00;1,23;26,3;41,5
02. 2-5%;98765;6789;5432;31,23;32,45;2,01;5,00;3,45;32,9;74,4
Interprétation¶
Profil conservateur : - 80%+ des offres entre 0-10% - PCT_CUMULE atteint 90% à la tranche 7-10%
Profil agressif : - 50%+ des offres entre 10-20% - PCT_CUMULE atteint 90% à la tranche 15-17%
Profil problématique : - 20%+ des offres > 20% - Investigation nécessaire
Comment modifier les tranches¶
Localisation : analyze_recommendations.py ligne ~247
Modifier les CASE dans la requête :
CASE
WHEN PCT_HAUSSE_FINALE = 0 THEN '00. Pas de hausse'
WHEN PCT_HAUSSE_FINALE <= 0.02 THEN '01. 0-2%%'
-- Ajouter/modifier tranches ici
WHEN PCT_HAUSSE_FINALE <= 0.03 THEN '02. 2-3%%' -- Nouvelle tranche
WHEN PCT_HAUSSE_FINALE <= 0.05 THEN '03. 3-5%%'
-- etc.
END as TRANCHE_HAUSSE
Attention : Dupliquer le CASE dans GROUP BY et ORDER BY.
Fichier 5 : decision_path_analysis.csv ⭐ NOUVEAU¶
Description¶
Statistiques par chemin de décision de l'arbre PT2QE. Permet de comprendre la répartition des offres entre les 3 chemins et l'impact de chaque type de capping.
Scope : ZOOM1 uniquement
Structure¶
DECISION_PATH : Chemin emprunté (3 valeurs possibles)
- "PAS_BAISSE_GEL_PRIX"
- "PL1_CONSERVATION_PREMIUM"
- "OPTIMISATION_STANDARD"
RECO_SELECTIONNEE : Recommandation retenue (nom explicite)
- "GEL_PRIX"
- "CONSERVATION_PREMIUM"
- "RECO1_REPOSITIONNEMENT_PALIERS"
- "RECO2_HAUSSE_PROPORTIONNELLE_PAS"
NB_OFFRES : Volume d'offres par combinaison
NB_CLIENTS : Clients distincts
NB_ARTICLES : Articles distincts
HAUSSE_MOY_PCT : Hausse moyenne (%, 2 déc)
HAUSSE_MEDIANE_PCT : Hausse médiane (%, 2 déc)
-- Comptage par type de capping appliqué
NB_CAP_GEL : Nombre avec capping GEL_PAS
NB_CAP_PRB : Nombre avec capping PRB_FINAL
NB_CAP_PLANCHER : Nombre avec capping PLANCHER_PL2_PL3
NB_CAP_BASIQUES : Nombre avec capping BASIQUES_50PCT
NB_CAP_SENSIBILITE : Nombre avec capping SENSIBILITE
NB_SANS_CAPPING : Nombre sans capping (NONE)
Format¶
- Séparateur : ;
- Décimale : ,
- Encoding : CP1252
- Tri : DECISION_PATH, RECO_SELECTIONNEE
Exemple¶
DECISION_PATH;RECO_SELECTIONNEE;NB_OFFRES;NB_CLIENTS;NB_ARTICLES;HAUSSE_MOY_PCT;HAUSSE_MEDIANE_PCT;NB_CAP_GEL;NB_CAP_PRB;NB_CAP_PLANCHER;NB_CAP_BASIQUES;NB_CAP_SENSIBILITE;NB_SANS_CAPPING
PAS_BAISSE_GEL_PRIX;GEL_PRIX;12345;1234;987;0,00;0,00;12345;0;0;0;0;0
PL1_CONSERVATION_PREMIUM;CONSERVATION_PREMIUM;8901;890;654;1,23;0,85;0;234;4567;0;0;4100
OPTIMISATION_STANDARD;RECO1_REPOSITIONNEMENT_PALIERS;189012;12345;8765;4,56;4,23;0;5678;0;12345;98765;72224
OPTIMISATION_STANDARD;RECO2_HAUSSE_PROPORTIONNELLE_PAS;45678;4567;3456;2,89;2,67;0;1234;0;0;0;44444
Interprétation¶
Insight 1 - Répartition entre chemins : Si 80% des offres sont en OPTIMISATION_STANDARD, cela indique que : - Peu de baisses de PAS (CHEMIN 1) - Peu de clients premium PL1 (CHEMIN 2) - Majorité en optimisation classique (CHEMIN 3)
Insight 2 - RECO1 vs RECO2 (CHEMIN 3 uniquement) : Si RECO1 gagne dans 90% des cas du CHEMIN 3 : - Les paliers sont bien calibrés - Le repositionnement est plus agressif que la hausse proportionnelle - Les cappings ne sont pas trop contraignants
Insight 3 - Impact des cappings : - NB_CAP_SENSIBILITE élevé → Cappings sensibilité actifs - NB_CAP_BASIQUES élevé → Beaucoup de produits basiques dépassent +50% - NB_CAP_PRB élevé → Compression du corridor (écart PAS-PRB réduit) - NB_SANS_CAPPING élevé → Cappings peu contraignants OU prix déjà bas
Comment utiliser ce fichier¶
Cas 1 : Ajuster l'agressivité globale - Si trop de RECO2 gagne → Hausser les paliers dans PT1CE - Si trop de RECO1 gagne → Baisser les paliers OU augmenter les cappings
Cas 2 : Calibrer les cappings
- Si NB_CAP_SENSIBILITE > 50% des offres → Cappings trop restrictifs
- Modifier inputs/capping_type_client.csv
Cas 3 : Analyser les gels - Si NB_CAP_GEL élevé → Beaucoup de baisses de PAS - Vérifier PT1CE : les nouveaux PAS sont-ils cohérents ?
Fichier 6 : capping_distribution.csv ⭐ NOUVEAU¶
Description¶
Distribution détaillée des cappings appliqués, croisée avec chemins de décision et recommandations. Vision granulaire de l'impact de chaque type de capping.
Scope : ZOOM1 uniquement
Structure¶
CAPPING_APPLIED : Type de capping le plus contraignant
Ordre priorité (du plus au moins prioritaire):
1. "GEL_PAS"
2. "PRB_FINAL"
3. "PLANCHER_PL2_PL3"
4. "BASIQUES_50PCT"
5. "SENSIBILITE"
6. "NONE"
DECISION_PATH : Chemin de décision
RECO_SELECTIONNEE : Recommandation retenue
NB_OFFRES : Volume d'offres
HAUSSE_MOY_PCT : Hausse moyenne (%, 2 déc)
Format¶
- Séparateur : ;
- Décimale : ,
- Encoding : CP1252
- Tri : CAPPING_APPLIED, DECISION_PATH, RECO_SELECTIONNEE
Exemple¶
CAPPING_APPLIED;DECISION_PATH;RECO_SELECTIONNEE;NB_OFFRES;HAUSSE_MOY_PCT
GEL_PAS;PAS_BAISSE_GEL_PRIX;GEL_PRIX;12345;0,00
PRB_FINAL;OPTIMISATION_STANDARD;RECO1_REPOSITIONNEMENT_PALIERS;5678;7,89
PLANCHER_PL2_PL3;PL1_CONSERVATION_PREMIUM;CONSERVATION_PREMIUM;4567;1,23
BASIQUES_50PCT;OPTIMISATION_STANDARD;RECO1_REPOSITIONNEMENT_PALIERS;12345;35,67
SENSIBILITE;OPTIMISATION_STANDARD;RECO1_REPOSITIONNEMENT_PALIERS;98765;4,56
NONE;OPTIMISATION_STANDARD;RECO2_HAUSSE_PROPORTIONNELLE_PAS;44444;2,89
Interprétation¶
Analyse capping BASIQUES_50PCT :
- 12345 offres de produits basiques - HAUSSE_MOY = 35,67% → Sans capping, hausse aurait été > 50% - Preuve que le capping basiques est actif et utile - Si HAUSSE_MOY proche de 50% → Beaucoup d'offres plafonnéesAnalyse capping SENSIBILITE :
- 98765 offres plafonnées par capping sensibilité - HAUSSE_MOY = 4,56% → Probablement LOW sensitivity (7,5%) - Si volume très élevé → Cappings peut-être trop restrictifsAnalyse NONE :
- 44444 offres sans capping appliqué - RECO2 gagne souvent dans ce cas - HAUSSE_MOY faible (2,89%) → Prix déjà bien positionnésComment utiliser ce fichier¶
Cas 1 : Évaluer l'efficacité des cappings basiques - Filtrer CAPPING_APPLIED = 'BASIQUES_50PCT' - Si HAUSSE_MOY proche de 50% → Capping très actif - Si HAUSSE_MOY << 50% → Capping peu utile (considérer suppression)
Cas 2 : Mesurer l'impact du capping PRB - Filtrer CAPPING_APPLIED = 'PRB_FINAL' - Volume élevé → Compression du corridor (écart PAS-PRB réduit) - Solution : Réajuster PRB dans PT1CE
Cas 3 : Calibrer les cappings sensibilité
- Comparer NB_OFFRES entre SENSIBILITE et NONE
- Si SENSIBILITE >> NONE → Cappings trop contraignants
- Augmenter les valeurs dans inputs/capping_type_client.csv
Comment modifier l'ordre de priorité des cappings¶
Localisation : calculate_recommandations.py ligne ~550
L'ordre de priorité est défini dans le CASE de la requête SQL :
CASE
-- Priorité 1 : Gel total
WHEN fp.DECISION_PATH = 'PAS_BAISSE_GEL_PRIX'
THEN 'GEL_PAS'
-- Priorité 2 : Capping PRB final
WHEN fp.CAPPING_PRB_APPLIED = 1
THEN 'PRB_FINAL'
-- Priorité 3 : Plancher PL2_PL3
WHEN fp.PLANCHER_PL2_APPLIED = 1
THEN 'PLANCHER_PL2_PL3'
-- Priorité 4 : Capping basiques (NOUVEAU)
WHEN fp.CAPPING_BASIQUES_APPLIED = 1
THEN 'BASIQUES_50PCT'
-- Priorité 5 : Capping sensibilité
WHEN fp.CAPPING_SENSIBILITE_APPLIED = 1
THEN 'SENSIBILITE'
-- Aucun capping
ELSE 'NONE'
END as CAPPING_APPLIED
Pour modifier l'ordre : Réorganiser les WHEN par priorité descendante.
Fichier 7 : capping_cubes_generated.csv¶
Description¶
Cappings générés pour chaque cube (UNIVERS × TYPE_CLIENT × TYPE_RESTAURANT × GEO). Ce fichier sert de base pour les ajustements manuels.
Scope : ZOOM1 uniquement, cubes MASTER + NATIONAL
Structure¶
UNIVERS : ZOOM1
TYPE_CLIENT : Segment client ou "NATIONAL"
TYPE_RESTAURANT : Type restaurant ou "NATIONAL"
GEO : Zone géographique ou "NATIONAL"
CUBE_TYPE : "MASTER" (cube spécifique) ou "NATIONAL" (fallback)
CAPPING_HIGH : Capping pour produits HIGH sensitivity (format décimal)
CAPPING_MEDIUM : Capping pour produits MEDIUM sensitivity
CAPPING_LOW : Capping pour produits LOW sensitivity
Format¶
- Séparateur : ;
- Décimale : ,
- Encoding : CP1252
- Tri : UNIVERS, TYPE_CLIENT, TYPE_RESTAURANT, GEO
Exemple¶
UNIVERS;TYPE_CLIENT;TYPE_RESTAURANT;GEO;CUBE_TYPE;CAPPING_HIGH;CAPPING_MEDIUM;CAPPING_LOW
ZOOM1;RCI PI GI;TRADITIONNEL;NORD;MASTER;0,025;0,05;0,075
ZOOM1;RCI PI GI;TRADITIONNEL;SUD;MASTER;0,025;0,05;0,075
ZOOM1;RSI HM;RESTAURATION_RAPIDE;EST;MASTER;0,025;0,05;0,075
ZOOM1;NATIONAL;NATIONAL;NATIONAL;NATIONAL;0,03;0,10;0,15
Cubes NATIONAL¶
Les cubes NATIONAL servent de fallback pour les offres qui n'ont pas de corridor MASTER.
Cappings par défaut : - CAPPING_HIGH : 0,03 (3% - plus restrictif) - CAPPING_MEDIUM : 0,10 (10%) - CAPPING_LOW : 0,15 (15%)
Rationale : Les corridors nationaux sont moins précis, donc cappings plus conservateurs.
Comment utiliser ce fichier pour ajuster les cappings¶
Procédure complète :
- Analyser les résultats initiaux (après Option 1)
- Ouvrir
recommendations_detail.csv - Filtrer sur TYPE_CLIENT / TYPE_RESTAURANT / GEO spécifique
-
Examiner PCT_HAUSSE_FINALE et CAPPING_APPLIED
-
Identifier les cubes à ajuster
- Hausses trop fortes → Baisser les cappings
- Hausses trop faibles → Augmenter les cappings
-
Beaucoup de CAPPING_APPLIED = 'SENSIBILITE' → Cappings trop restrictifs
-
Copier le fichier vers corrections/
-
Modifier les valeurs dans Excel
- Ouvrir
corrections/capping_cubes_corrections.csv - Modifier CAPPING_HIGH / MEDIUM / LOW pour les cubes souhaités
- Ne pas modifier : UNIVERS, TYPE_CLIENT, TYPE_RESTAURANT, GEO, CUBE_TYPE
-
Sauvegarder avec séparateur ; et décimale ,
-
Relancer avec Option 2 (Ajuster cappings)
- Exécuter
2_ajuster_cappings.batOU Menu Option 2 - Les nouveaux cappings seront appliqués
-
Nouveau dossier
corrections_YYYYMMDD_HHMMSS/généré -
Comparer les résultats
- Comparer
run_*/recommendations_detail.csvvscorrections_*/recommendations_detail.csv - Vérifier l'évolution de PCT_HAUSSE_FINALE
- Itérer si nécessaire
Exemple de modification¶
Avant (capping_cubes_generated.csv) :
UNIVERS;TYPE_CLIENT;TYPE_RESTAURANT;GEO;CUBE_TYPE;CAPPING_HIGH;CAPPING_MEDIUM;CAPPING_LOW
ZOOM1;RCI PI GI;TRADITIONNEL;NORD;MASTER;0,025;0,05;0,075
Après correction (capping_cubes_corrections.csv) :
UNIVERS;TYPE_CLIENT;TYPE_RESTAURANT;GEO;CUBE_TYPE;CAPPING_HIGH;CAPPING_MEDIUM;CAPPING_LOW
ZOOM1;RCI PI GI;TRADITIONNEL;NORD;MASTER;0,03;0,06;0,09
Impact : Produits HIGH sensitivity passent de +2,5% max à +3% max pour ce cube.
Fichier 8 : summary.txt¶
Description¶
Fichier texte récapitulatif de l'exécution. Généré à chaque run.
Scope : ZOOM1 uniquement
Contenu¶
PT2QE - RÉSUMÉ D'EXÉCUTION
======================================================================
Date : 15/01/2025 14:32:45
Période analysée : 2024-01-01 -> 2024-12-31
Trimestres fiscaux : 2024_Q01, 2024_Q02, 2024_Q03, 2024_Q04
Table recommandations : PT2QE_RECOMMENDATIONS
Dossier résultats : outputs/run_20250115_143245
Champs : - Date : Horodatage de l'exécution - Période analysée : Dates de début et fin de l'extraction historique (4Q) - Trimestres fiscaux : Liste des quarters inclus dans l'historique - Table recommandations : Nom de la table Oracle créée - Dossier résultats : Chemin du dossier de sortie
Comment modifier le contenu¶
Localisation : pt2qe_main.py fonction create_summary_file
Ajouter des lignes au fichier :
f.write(f"Date : {datetime.now().strftime('%d/%m/%Y %H:%M:%S')}\n")
f.write(f"Période analysée : {app.start_date} -> {app.end_date}\n")
f.write(f"Trimestres fiscaux : {', '.join(app.fiscal_quarters)}\n")
f.write(f"Table recommandations : {table}\n")
f.write(f"Dossier résultats : {app.output_folder}\n")
# Ajouter nouvelles infos
f.write(f"Base de données : {app.args.database}\n")
f.write(f"Fichier capping : {app.args.capping_file}\n")
Exports finaux (Option 3)¶
Fichier 9 : final_price_offers.csv¶
Description¶
Export final simplifié au format client × article, prêt pour intégration. Contient uniquement les champs nécessaires pour l'utilisation opérationnelle.
Scope : ZOOM1 uniquement, offres avec recommandations calculées
Structure¶
Colonnes principales (format export)¶
ID_CLN : Identifiant client
LC_CLN : Libellé client
ID_ART : Identifiant article
LC_ART : Libellé article
TYPE_CLIENT : Segment client
TYPE_RESTAURANT : Type établissement
GEO : Zone géographique
UNIVERS : ZOOM1
ID_CND : Identifiant condition
DT_DEB_CONDITION : Date début validité
DT_FIN_CONDITION : Date fin validité
PRIX_TARIF_ACTUEL : Prix actuel (€, 3 décimales)
NOUVEAU_PRIX : Prix recommandé (€, 3 décimales)
PCT_HAUSSE : % hausse (format 12,34 = 12,34%)
HAUSSE_EUROS : Hausse en € (3 décimales)
Attention : PCT_HAUSSE est en format pourcentage (12,34 = 12,34%), contrairement aux autres exports où c'est en format décimal (0,1234).
Colonnes traçabilité¶
POSITION_TARIF_ACTUEL_DANS_ANCIENNES_BORNES : Position départ
PALIER_TARIF_ACTUEL_VS_NOUVELLES_BORNES : Position après PT1CE
POSITION_NOUVEAU_PRIX_DANS_NOUVELLES_BORNES : Position après PT2QE
PRICE_SENSITIVITY : HIGH / MEDIUM / LOW
TYPE_HAUSSE : Type recommandation retenue
- "REPOSITIONNEMENT" (RECO1)
- "HAUSSE_PROPORTIONNELLE" (RECO2)
VALIDATION_STATUS : Statut validation automatique
- "VALIDE" : OK
- "A_VERIFIER" : Hausse > 20%
- "ANOMALIE" : Baisse détectée
DATE_CALCUL : Horodatage calcul (format DD/MM/YYYY HH24:MI:SS)
Règles de validation automatique¶
VALIDE (par défaut) : - PCT_HAUSSE entre 0% et 20% - Aucune anomalie détectée
A_VERIFIER : - PCT_HAUSSE > 20% - Ou (PRICE_SENSITIVITY = 'HIGH' ET PCT_HAUSSE > 10%)
ANOMALIE : - PCT_HAUSSE < 0 (baisse de prix) - Ne devrait jamais arriver avec PT2QE
Format¶
- Séparateur : ;
- Décimale : ,
- Encoding : CP1252
- Tri : ID_CLN, ID_ART
Exemple¶
ID_CLN;LC_CLN;ID_ART;LC_ART;TYPE_CLIENT;PRIX_TARIF_ACTUEL;NOUVEAU_PRIX;PCT_HAUSSE;VALIDATION_STATUS;TYPE_HAUSSE
12345;RESTAURANT CHEZ PAUL;075130;FILET BOEUF 1KG;RCI PI GI;45,750;47,900;4,70;VALIDE;REPOSITIONNEMENT
12346;BRASSERIE DU CENTRE;075131;SAUMON FUME 500G;RSI HM;28,500;29,350;2,98;VALIDE;HAUSSE_PROPORTIONNELLE
12347;HOTEL RESTAURANT;075132;CHAMPIGNONS 1KG;RCI PI GI;12,450;15,950;28,11;A_VERIFIER;REPOSITIONNEMENT
Comment modifier les seuils de validation¶
Localisation : generate_final_quotes.py méthode _format_final_data
def _format_final_data(self, df: pd.DataFrame):
# Statut par défaut
df['VALIDATION_STATUS'] = 'VALIDE'
# Modifier seuils ici
df.loc[df['PCT_HAUSSE'] > 20, 'VALIDATION_STATUS'] = 'A_VERIFIER' # Changer 20
# Anomalies
df.loc[df['PCT_HAUSSE'] < 0, 'VALIDATION_STATUS'] = 'ANOMALIE'
# Cas spéciaux - modifier conditions
df.loc[
(df['PRICE_SENSITIVITY'] == 'HIGH') &
(df['PCT_HAUSSE'] > 10), # Changer 10
'VALIDATION_STATUS'
] = 'A_VERIFIER'
Comment ajouter des colonnes¶
Localisation : generate_final_quotes.py ligne ~30
Ajouter les colonnes dans le SELECT :
SELECT
-- Colonnes existantes
ID_CLN,
LC_CLN,
-- ...
-- Nouvelles colonnes
RECO1_BASE,
RECO2,
DECISION_PATH,
CAPPING_APPLIED,
FROM {recommendations_table}
Aucune modification Python nécessaire (lecture auto).
Fichier 10 : validation_report.csv¶
Description¶
Rapport de validation structuré avec métriques clés.
Scope : ZOOM1 uniquement
Structure¶
CATEGORIE : Type de métrique
- "GLOBAL" : Métriques volumétriques globales
- "HAUSSES" : Statistiques de hausses
- "TYPE_HAUSSE" : Répartition RECO1/RECO2
- "VALIDATION" : Distribution statuts validation
METRIQUE : Nom de la métrique
VALEUR : Valeur (nombre ou pourcentage)
Format¶
- Séparateur : ;
- Décimale : ,
- Encoding : CP1252
- Tri : CATEGORIE, METRIQUE
Exemple¶
CATEGORIE;METRIQUE;VALEUR
GLOBAL;Nombre total d'offres;234567
GLOBAL;Nombre de clients;12345
GLOBAL;Nombre d'articles;8765
HAUSSES;Hausse moyenne (%);3,78
HAUSSES;Hausse médiane (%);2,89
HAUSSES;Hausse max (%);28,45
TYPE_HAUSSE;REPOSITIONNEMENT;145678
TYPE_HAUSSE;HAUSSE_PROPORTIONNELLE;88889
VALIDATION;VALIDE;220123
VALIDATION;A_VERIFIER;14234
VALIDATION;ANOMALIE;210
Métriques disponibles¶
GLOBAL : - Nombre total d'offres - Nombre de clients - Nombre d'articles
HAUSSES : - Hausse moyenne (%) - Hausse médiane (%) - Hausse min (%) - Hausse max (%)
TYPE_HAUSSE : - REPOSITIONNEMENT (RECO1 gagne) - HAUSSE_PROPORTIONNELLE (RECO2 gagne)
VALIDATION : - VALIDE - A_VERIFIER - ANOMALIE
Comment ajouter des métriques¶
Localisation : generate_final_quotes.py méthode _generate_validation_report
Ajouter au tableau validation_stats :
# Nouvelle métrique
validation_stats.append({
'CATEGORIE': 'PERFORMANCE',
'METRIQUE': 'CA total impacté (€)',
'VALEUR': (df['NOUVEAU_PRIX'] * df['QT_UF_4Q']).sum()
})
Fichier 11 : export_summary.txt¶
Description¶
Résumé textuel lisible de l'export final.
Scope : ZOOM1 uniquement
Contenu type¶
RÉSUMÉ EXPORT FINAL PT2QE
==================================================
Date : 15/01/2025 14:32:45
VOLUMÉTRIE
--------------------
Offres exportées : 234,567
Clients uniques : 12,345
Articles uniques : 8,765
HAUSSES DE PRIX
--------------------
Hausse moyenne : 3.7%
Hausse médiane : 2.9%
Hausse min : 0.0%
Hausse max : 28.5%
VALIDATION
--------------------
VALIDE : 220,123 (93.8%)
A_VERIFIER : 14,234 (6.1%)
ANOMALIE : 210 (0.1%)
RÉPARTITION TYPE RECOMMANDATION
--------------------
REPOSITIONNEMENT : 145,678 (62.1%)
HAUSSE_PROPORTIONNELLE : 88,889 (37.9%)
MATCHING CORRIDORS
--------------------
MASTER : 210,345 (89.7%)
NATIONAL : 24,222 (10.3%)
Sections¶
- Date : Horodatage génération
- Volumétrie : Offres, clients, articles
- Hausses de prix : Statistiques descriptives
- Validation : Distribution statuts
- Répartition type recommandation : RECO1 vs RECO2
- Matching corridors : MASTER vs NATIONAL
Comment modifier le contenu¶
Localisation : generate_final_quotes.py méthode _generate_validation_report
Ajouter des sections au fichier :
with open(summary_file, 'w', encoding='cp1252') as f:
f.write("RÉSUMÉ EXPORT FINAL PT2QE\n")
f.write("=" * 50 + "\n\n")
# ... sections existantes ...
# Nouvelle section
f.write("DÉTAIL PAR TYPE CLIENT\n")
f.write("-" * 20 + "\n")
type_client_stats = df.groupby('TYPE_CLIENT').agg({
'ID_CLN': 'count',
'PCT_HAUSSE': 'mean'
})
for tc, stats in type_client_stats.iterrows():
f.write(f"{tc} : {stats['ID_CLN']:,} offres, {stats['PCT_HAUSSE']:.1f}% hausse moy\n")
Paramètres d'export globaux¶
Configuration dans pt2qe_config.json¶
Localisation : config/pt2qe_config.json
{
"output": {
"csv_separator": ";",
"csv_encoding": "cp1252",
"decimal_places": 3,
"percentage_format": 2
}
}
Paramètres disponibles¶
csv_separator : Séparateur CSV (défaut: ;)
csv_encoding : Encodage (défaut: cp1252 pour Excel Windows)
decimal_places : Décimales pour les montants (défaut: 3)
percentage_format : Décimales pour les pourcentages (défaut: 2)
Comment modifier l'encodage pour Linux/Mac¶
Modifier dans pt2qe_config.json :
{
"output": {
"csv_separator": ",",
"csv_encoding": "utf-8",
"decimal_places": 3,
"percentage_format": 2
}
}
Attention : Changer aussi le séparateur décimal dans le code si nécessaire.
Comment modifier le séparateur décimal¶
Localisation : Chaque méthode d'export dans analyze_recommendations.py et generate_final_quotes.py
Remplacer decimal=',' par decimal='.' :
Volumétrie et performance¶
Compression automatique¶
Les exports ne sont pas compressés automatiquement par défaut.
Compression manuelle :
Sous Windows :
Sous Linux :
Comment activer la compression automatique¶
Créer un fichier compress_exports.py dans utils/ :
import zipfile
from pathlib import Path
def compress_exports(output_folder: Path):
csv_files = list(output_folder.glob('*.csv'))
txt_files = list(output_folder.glob('*.txt'))
if csv_files or txt_files:
zip_path = output_folder / 'exports.zip'
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
for f in csv_files + txt_files:
zf.write(f, f.name)
f.unlink() # Supprimer après compression
Appeler dans pt2qe_main.py après génération :
from utils.compress_exports import compress_exports
# Après génération des exports
compress_exports(app.output_folder)
Découpage des exports volumineux¶
Exports sans découpage¶
Par défaut, aucun découpage n'est appliqué. Tous les exports sont en un seul fichier.
Comment activer le découpage¶
Localisation : analyze_recommendations.py méthode _export_recommendations_detail
Ajouter avant df.to_csv() :
def split_dataframe(df, chunk_size=500000):
"""Découpe un DataFrame en chunks."""
for i in range(0, len(df), chunk_size):
yield df.iloc[i:i+chunk_size]
# Dans _export_recommendations_detail
if len(df) > 500000:
# Découpage nécessaire
for i, chunk in enumerate(split_dataframe(df, chunk_size=500000)):
chunk_file = output_folder / f'recommendations_detail_part{i+1:02d}.csv'
chunk.to_csv(chunk_file, index=False, sep=';', decimal=',', encoding='cp1252')
self.app.log.info(f" → Part {i+1} : {len(chunk):,} lignes")
else:
# Export normal
df.to_csv(output_file, index=False, sep=';', decimal=',', encoding='cp1252')
Utilisation des exports¶
Workflow standard¶
1. Exécuter Option 1 (Calcul recommandations)
└─> Analyser : recommendations_detail.csv
decision_path_analysis.csv
capping_distribution.csv
2. Si ajustements nécessaires
└─> Modifier : corrections/capping_cubes_corrections.csv
└─> Exécuter Option 2 (Ajuster cappings)
└─> Comparer : run_*/recommendations_detail.csv
vs corrections_*/recommendations_detail.csv
3. Si résultats validés
└─> Exécuter Option 3 (Générer offres finales)
└─> Utiliser : final_price_offers.csv
Analyses Excel recommandées¶
Sur recommendations_detail.csv : 1. Tableau croisé dynamique : TYPE_CLIENT × UNIVERS - Valeurs : Moyenne PCT_HAUSSE_FINALE - Filtres : DECISION_PATH, CAPPING_APPLIED
- Graphique distribution PCT_HAUSSE_FINALE
- Histogramme par tranches
- Courbe cumulée
Sur decision_path_analysis.csv : 1. Graphique empilé : Volume par DECISION_PATH - Couleurs par RECO_SELECTIONNEE
- Tableau : Impact des cappings par chemin
- Lignes : DECISION_PATH
- Colonnes : NB_CAP_* (comptages)
Sur impact_analysis.csv : 1. Tableau : TYPE_CLIENT × IMPACT_PCT - Mise en forme conditionnelle selon impact
- Graphique : Distribution des hausses
- Barres : NB_0_2PCT, NB_2_5PCT, etc.
- Courbe : PCT cumulés
Troubleshooting¶
Problème : Fichiers CSV illisibles dans Excel¶
Cause : Encodage CP1252 corrompu ou séparateurs mal détectés
Solution 1 : Réimporter dans Excel - Données → Obtenir des données → À partir d'un fichier texte - Choisir "Délimité" → Séparateur ";" → Décimale "," - Encodage : Windows-1252
Solution 2 : Modifier l'encodage
Problème : Colonnes manquantes dans l'export¶
Cause : Colonne ajoutée dans la requête SQL mais pas dans le DataFrame
Solution : Vérifier que le SELECT inclut toutes les colonnes
Dans analyze_recommendations.py :
# Vérifier la requête
query = f"""
SELECT
ID_CLN,
LC_CLN,
ID_ART,
-- ... TOUTES les colonnes nécessaires
FROM {table}
"""
Problème : Pourcentages mal formatés¶
Cause : Format décimal au lieu de format pourcentage
Solution : Convertir dans le code
Pour les exports détaillés (format décimal 0.0345) :
Pour l'export final (format pourcentage 3.45) :
Problème : Exports très volumineux¶
Cause : Volume ZOOM1 important
Solution 1 : Filtrer dans la requête SQL
-- Ajouter des WHERE dans la requête d'export
WHERE TYPE_CLIENT = 'RCI PI GI' -- Filtrer sur un segment
Solution 2 : Activer le découpage (voir section précédente)
Solution 3 : Exporter par batch
# Dans _export_recommendations_detail
for type_client in ['RCI PI GI', 'RSI HM', 'RSC HM']:
query_filtered = f"{query} WHERE TYPE_CLIENT = '{type_client}'"
# ... export
Problème : Dossiers outputs/ non créés¶
Cause : Permissions ou erreur création dossier
Solution : Vérifier les permissions
Si erreur persiste, créer manuellement :
Problème : Fichiers exports vides¶
Cause : Aucune donnée dans la table source
Solution : Vérifier le contenu de la table
Si 0 ligne → Problème lors du calcul des recommandations.
Personnalisation avancée¶
Ajouter un export custom¶
Localisation : analyze_recommendations.py
Créer une nouvelle méthode :
def _export_custom_analysis(self, table: str, output_folder: Path):
"""Mon export personnalisé."""
output_file = output_folder / 'custom_export.csv'
query = f"""
SELECT
TYPE_CLIENT,
COUNT(*) as NB_OFFRES,
AVG(PCT_HAUSSE_FINALE) as HAUSSE_MOY
-- Ajouter colonnes souhaitées
FROM {table}
GROUP BY TYPE_CLIENT
ORDER BY TYPE_CLIENT
"""
q = self.db.create_query(query)
df = q.read()
q.close()
if not df.empty:
df.to_csv(output_file, index=False, sep=';', decimal=',', encoding='cp1252')
self.app.log.info(f" → Export custom généré")
Appeler dans analyze_and_export :
def analyze_and_export(self, recommendations_table: str, output_folder: Path):
# ... exports existants ...
# Nouvel export
self._export_custom_analysis(recommendations_table, output_folder)
Modifier le format de date¶
Localisation : generate_final_quotes.py ligne ~30
Dans la requête SQL :
-- Changer format date
TO_CHAR(CALCULATION_DATE, 'DD/MM/YYYY HH24:MI:SS') as DATE_CALCUL -- Actuel
TO_CHAR(CALCULATION_DATE, 'YYYY-MM-DD') as DATE_CALCUL -- ISO 8601
TO_CHAR(CALCULATION_DATE, 'MM/DD/YYYY') as DATE_CALCUL -- US
Ajouter un export JSON¶
Localisation : generate_final_quotes.py
Après l'export CSV :
import json
# Export JSON en plus du CSV
json_file = output_file.parent / 'final_price_offers.json'
# Convertir DataFrame en JSON
df_json = df.to_dict(orient='records')
with open(json_file, 'w', encoding='utf-8') as f:
json.dump(df_json, f, indent=2, ensure_ascii=False)
self.app.log.info(f" → Export JSON généré")
Résumé des fichiers générés¶
Par étape d'exécution¶
Option 1 - Calcul initial (run_YYYYMMDD_HHMMSS/) : - ✅ recommendations_detail.csv - ✅ statistics_by_dimension.csv - ✅ impact_analysis.csv - ✅ price_increase_distribution.csv - ✅ decision_path_analysis.csv ⭐ NOUVEAU - ✅ capping_distribution.csv ⭐ NOUVEAU - ✅ capping_cubes_generated.csv - ✅ summary.txt
Option 2 - Après corrections (corrections_YYYYMMDD_HHMMSS/) : - Même liste que Option 1 (versions recalculées)
Option 3 - Export final (final_YYYYMMDD_HHMMSS/) : - ✅ final_price_offers.csv - ✅ validation_report.csv - ✅ export_summary.txt
Taille typique des fichiers¶
Impossible à estimer : Dépend du volume ZOOM1 et de la volumétrie client × article.
Fichiers obligatoires vs optionnels¶
Obligatoires (toujours générés) : - recommendations_detail.csv - capping_cubes_generated.csv - summary.txt - final_price_offers.csv (Option 3)
Optionnels (peuvent être désactivés) : - statistics_by_dimension.csv - impact_analysis.csv - price_increase_distribution.csv - decision_path_analysis.csv - capping_distribution.csv - validation_report.csv
Pour désactiver un export optionnel, commenter l'appel dans analyze_and_export :
Points d'attention¶
Scopes temporels à retenir¶
- Offres extraites : Valides au moment de l'exécution (DT_FIN > date du jour)
- Historique 4Q : 4 derniers trimestres fiscaux complets avant la date d'exécution
- Corridors PT1CE : Utilisés tels que présents dans PT1CE_OPTIMAL_* au moment de l'exécution
- Cappings : Fichier
inputs/capping_type_client.csvutilisé lors du calcul
Cohérence entre exports¶
Tous les exports d'un même run (même dossier) sont cohérents : - Même extraction source - Même période 4Q - Mêmes cappings appliqués - Même horodatage
Conservation des runs¶
Les dossiers de run ne sont jamais écrasés. Chaque exécution crée un nouveau dossier horodaté.
Recommandation : Archiver les anciens runs après validation pour libérer de l'espace.
Encodage et compatibilité¶
CP1252 (défaut) : - ✅ Compatible Excel Windows (France) - ✅ Caractères accentués français - ❌ Peut poser problème sur Linux/Mac
UTF-8 (alternatif) : - ✅ Compatible tous systèmes - ✅ Standard moderne - ⚠️ Nécessite import manuel dans Excel Windows
Arrondis et précision¶
Montants : 3 décimales (45,750) Pourcentages : 2 décimales (3,45%) Écarts : Possible sur les agrégations (somme des arrondis ≠ arrondi de la somme)