Une phrase. Power BI calcule une proposition (Hero / Strat / rang / DV). L’humain confirme ou force. Dataverse mémorise. Après refresh, les colonnes « actuel » du rapport suivent la décision, pas la proposition.
Chaîne à implémenter, dans cet ordre :
PowerBIIntegration.Data, Patch sur clé alternative.cr568_prio_decision et cr568_prio_objectif.| Saisie des accords | Prio Réfs (à construire) | |
|---|---|---|
| App canvas | e890ef64-b48f-43ad-9a7e-e2454e283e82 | Nouvelle app. Interdit de l’embarquer dans le slot Prio. |
| Visuel PBI | PowerApps_PBI_CV_C29F1DCC_81F5_4973_94AD_0517D44CC06A | Même type de visuel, autre appId. |
| Table Dataverse | cr568_negotiation_current (ledger négo) | Deux tables neuves. Pas une colonne de plus sur le ledger. |
| Grain d’écriture | EAN × enseigne × PeriodKey (ScaKey) | Décision : EAN × circuit × année. Objectif : EAN × enseigne × PeriodKey. |
| Contexte reçu | Colonnes de negotiation_current (ean, Année, DV, dates…) | Mesures et colonnes Prio (section Embed). |
| Après Patch | Flux PPC / refresh dataset | Même hop refresh. Pointer ensuite PRIO actuel / PL actuel / DV Objectif Prio sur Dataverse. |
| Sécurité CDC | Équipe négo | Restricted Perfect Store + DXI uniquement. |
cr568_prio_ref n’est pas la cible. Ce champ (et cr568_priority_list, entier) existe déjà sur cr568_negotiation_current : étiquette recopiée sur le ledger d’accords. Une écriture Prio dedans casserait la négo et ne nourrirait pas PRIO actuel, qui lit Spec_Produit_Wide via TREATAS. Créer des tables dédiées.
Le rapport ne persiste rien. Il affiche une proposition DAX et un « actuel » Excel. L’app est le seul endroit où un humain verrouille.
Publisher DataLift, préfixe cr568_, table non managée, audit on. Une ligne = une décision d’assortiment pour un circuit et une année typo. CDC : unitaires, pas de refs HD. Alternate key obligatoire : cr568_ak_prio_decision sur cr568_ean + cr568_circuit + cr568_annee.
| Attribut logique | Type | Oblig. | Règle |
|---|---|---|---|
| cr568_prio_decisionid | uniqueidentifier | PK | GUID système |
| cr568_name | nvarchar 200 | auto | Formule : ean & "|" & circuit & "|" & annee |
| cr568_ean | nvarchar 20 | oui | Texte, pas Int64. Pad interdit. |
| cr568_circuit | choice | oui | HM / SM / PROXI seulement. Pas HD, pas ECOM. |
| cr568_annee | nvarchar 4 | oui | Année typo spec 2023…2026 = slicer Spec_Produit_Wide[annee]. |
| cr568_conditionnement | choice | oui | Défaut UNITAIRE. DP / BOX hors scope Prio (Supply). |
| cr568_refs_hd | choice | oui | Défaut HORS HD. Les jumeaux HD de Spec_Produit_Wide cassent SELECTEDVALUE. |
| cr568_prio | choice | oui | HERO / STRAT / INNO / OTHER — valeur lue ensuite par PRIO actuel. |
| cr568_prio_propose | nvarchar 20 | non | Copie de Hero proposé / Strat proposé au Patch (audit). |
| cr568_ranking_pl | int | non | Rang liste prio (1…n), unique par (circuit, annee). |
| cr568_ranking_pl_propose | int | non | Copie de PL proposé au Patch. |
| cr568_source | choice | oui | PROPOSE (accepté tel quel) / FORCE (surcharge humaine). |
| cr568_host_screen | choice | oui | HERO / STRAT / LISTE_PRIO. |
| cr568_commentaire | nvarchar 500 | non | Motif si FORCE. |
| ownerid / createdon / modifiedon | std | oui | Audit PS + DXI. |
Patch idempotent. LookUp sur la clé alternative, puis Patch du record. Ne pas Create en doublon si l’EAN est déjà tranché pour ce circuit-année.
Grain plus fin que la décision prio : EAN × enseigne nvx2 × PeriodKey (2025Q1, 2025Q3…), identique à Objectifs.xlsx (14 267 lignes, ScaKey = ProductKey|enseigne|PeriodKey, ProductKey = ean & "0"). Périmètre CDC : HMSM + CRF City/Contact + Franprix. Pas HD, pas e-com.
| Attribut logique | Type | Oblig. | Règle |
|---|---|---|---|
| cr568_prio_objectifid | GUID | PK | |
| cr568_scakey | nvarchar 120 | oui unique | ean & "0|" & label_enseigne_nvx2 & "|" & periodkey |
| cr568_ean | nvarchar 20 | oui | |
| cr568_label_enseigne_nvx2 | nvarchar 100 | oui | Libellé enseigne référentiel, pas le circuit. |
| cr568_periodkey | nvarchar 8 | oui | YYYYQ1 ou YYYYQ3 uniquement (CDC négo). |
| cr568_annee | int | oui | Dérivé de PeriodKey. |
| cr568_nego | choice Q1/Q3 | oui | |
| cr568_dv_objectif | decimal (2) | oui | Saisie humaine. DV brute enseigne, pas un %. |
| cr568_dn_objectif | decimal (2) | non | Si le métier le saisit ; sinon vide. |
| cr568_source | choice | oui | EXCEL_IMPORT / SAISIE_APP. |
| Rôle | Tables Prio | negotiation_current |
|---|---|---|
| Perfect Store | CRUD prio_decision + prio_objectif | lecture seule recommandée |
| DXI | CRUD + publier solution | inchangé |
| Autres (négo, field) | aucun | inchangé |
cr568_prio : HERO, STRAT, INNO, OTHER (même texte que Bridge_PE_Annee[PRIO], sinon le DAX de comparaison casse).cr568_circuit : HM, SM, PROXI (majuscules = Dim_Enseignes[circuit]). Ne pas créer HD / ECOM : un Hero HD n’est pas dans le CDC Prio.Une app, quatre écrans. StartScreen selon host_screen (section Embed). Pas de menu interne qui duplique les onglets PBI.
OnVisible commun : Set(varRow; First(PowerBIIntegration.Data)). Si ean blank → « Sélectionnez une ligne dans le tableau ». Tous les Patch lisent varRow, jamais une galerie interne non filtrée.
| Contrôle | Source | Comportement |
|---|---|---|
| LblRef | varRow.reference & " · " & varRow.ean | lecture |
| LblCircuitAnnee | varRow.circuit & " · " & varRow.annee | circuit vient du slicer PBI |
| LblActuel | varRow.PRIO_actuel | spec Excel / Dataverse après bascule |
| LblPropose | varRow.Hero_propose | HERO ou OTHER |
| LblCumul | varRow.Poids_NR_Cumule | warning 50 % |
| CmbPrio | HERO / OTHER (pas INNO/STRAT ici) | défaut = Hero_propose |
| TglForce | bool | si choix ≠ proposé → source = FORCE, commentaire obligatoire |
| BtnEnregistrer | Patch prio_decision | host_screen = HERO |
Avertissement (pas un blocage) si CmbPrio = HERO et Poids_NR_Cumule déjà ≥ 50 % hors de cette SKU : le métier a le droit de forcer.
Patch(
cr568_prio_decisions;
LookUp(cr568_prio_decisions;
cr568_ean = varRow.ean And cr568_circuit = varRow.circuit And cr568_annee = Text(varRow.annee)
);
{
cr568_ean: varRow.ean;
cr568_circuit: varRow.circuit;
cr568_annee: Text(varRow.annee);
cr568_conditionnement: "UNITAIRE";
cr568_refs_hd: "HORS HD";
cr568_prio: CmbPrio.Selected.Value;
cr568_prio_propose: varRow.Hero_propose;
cr568_source: If(CmbPrio.Selected.Value = varRow.Hero_propose; "PROPOSE"; "FORCE");
cr568_host_screen: "HERO";
cr568_commentaire: TxtMotif.Text
}
)
CmbPrio : STRAT / OTHER. HERO désactivé — renvoyer vers l’onglet Hero. Si Hero_propose = HERO : « déjà Hero, ne pas retrancher ici ». Le scoring Perfect Store (croissance, marge, DN) vit ici : formule CDC absente du PBIX. Tant que le score n’existe pas, préremplir avec Strat_propose (bande 50–80 %).
| Quand le score arrivera | Où le coder | Impact PBI |
|---|---|---|
| Règle chiffrée PS (score ≥ seuil) | App : cr568_score + calcul OnVisible | Remplacer la mesure Strat proposé DAX, ou la laisser en suggestion |
| EAN déjà STRAT dans spec | Précocher CmbPrio = PRIO_actuel si STRAT | Comparer actuel vs proposé dans le tableau |
TxtRang entier ≥ 1. Unicité de cr568_ranking_pl par (circuit, annee). Collision : décaler les rangs suivants (ForAll Update) ou refuser. Préremplir avec PL_propose. Afficher PL_actuel (spec) en lecture.
Une ligne PBI (EAN) peut cacher N enseignes. Soit le tableEx de la page Objectifs expose label_enseigne_nvx2 + PeriodKey (recommandé), soit l’app charge une galerie Filter(cr568_prio_objectifs; cr568_ean = varRow.ean).
| Champ galerie | Patch |
|---|---|
| Enseigne (lecture) | cr568_label_enseigne_nvx2 |
| PeriodKey (slicer Q1/Q3 ou combo) | cr568_periodkey — 2025Q1 / 2025Q3 |
| DV objectif (saisie) | cr568_dv_objectif — nombre, pas % |
| DN objectif (optionnel) | cr568_dn_objectif |
Périmètre Objectifs. Patch seulement si l’enseigne est HMSM, Carrefour City, Carrefour Contact ou Franprix. Refuser HD / Drive / e-com / enseigne saisie à la main. Alignement Dim_Enseignes[Enseigne_MAG] et circuit HM/SM/PROXI.
| Cas | UI |
|---|---|
| PowerBIIntegration.Data vide | Pas de Patch. Texte d’aide. |
| Circuit ou année = Tout | Bloquer. SELECTEDVALUE prio / annee est blank. |
| Patch OK | Notify succès + déclencher le flux refresh. |
| Patch KO (clé / sécurité) | Notify erreur Dataverse brute, ne pas avaler. |
Remplacer la card « Console Prio — à brancher » (acedc191357f4eac992b) par le visuel Power Apps, même emplacement que Saisie : x ≈ 987, y ≈ 223, width ≈ 279, height ≈ 477, dans le rectangle arrondi console.
| Propriété visuel | Valeur |
|---|---|
| visualType | PowerApps_PBI_CV_C29F1DCC_81F5_4973_94AD_0517D44CC06A |
| objects.general.appId | /providers/Microsoft.PowerApps/apps/<GUID-NOUVELLE-APP> |
| query.queryState.table.projections | Rôle table (pas Values) — liste ci-dessous |
| Table Prio drillFilterOtherVisuals | Repasser à true (false aujourd’hui à cause du crash isMeasure sans app). |
Noms sans slash ni accent : l’app les lit en identifiants. Le tableau PBI peut garder les libellés FR.
| nativeQueryRef | Champ PBI | Pages |
|---|---|---|
| ean | Dim_Produit_EAN[ean] | toutes |
| reference | Dim_Produit_EAN[reference] | toutes |
| circuit | Dim_Enseignes[circuit] — slicer, pas une mesure | toutes |
| annee | Spec_Produit_Wide[annee] | toutes |
| conditionnement | Dim_Produit_EAN[conditionnement] | toutes |
| NR_Finance | Mesures[NR_Finance] | toutes |
| Poids_NR | Mesures[Poids NR/Circuit] | Hero, Strat, PL |
| Poids_NR_Cumule | Mesures[Poids NR Cumulé] | Hero, Strat |
| PRIO_actuel | Mesures[PRIO actuel] | toutes |
| Hero_propose | Mesures[Hero proposé] | Hero, Strat, PL |
| Strat_propose | Mesures[Strat proposé] | Strat, PL |
| PL_actuel | Mesures[PL actuel] | Liste prio |
| PL_propose | Mesures[PL proposé] | Liste prio |
| DV_Objectif | Mesures[DV Objectif Prio] | Objectifs |
| label_enseigne_nvx2 | à ajouter sur la page Objectifs | Objectifs |
| PeriodKey | Objectifs[PeriodKey] | Objectifs |
| host_screen | mesure constante HERO / STRAT / LISTE_PRIO / OBJECTIFS | toutes |
Mesure host_screen par page pour StartScreen = Switch(First(PowerBIIntegration.Data).host_screen; …). Évite un Param() fragile dans l’embed Desktop.
Table → console : remettre DataFilter (aujourd’hui NoFilter), sinon le clic EAN n’envoie pas la ligne. Table → cartes KPI : garder NoFilter (un Hero unique ferait chuter % NR à ~2 %).
| Slicer | Pourquoi l’app l’exige |
|---|---|
| Circuit = HM ou SM ou PROXI | PRIO actuel / PL actuel sont circuit-spécifiques. Tout = SELECTEDVALUE blank. |
| Année typo = une année | Spec_Produit_Wide a 4 années ; sans filtre SELECTEDVALUE prio_ref_* est blank (doublons). |
| Contour / Conditionnement | Filtrent la proposition NR ; UNITAIRE recommandé (CDC). |
Set(varRow; First(PowerBIIntegration.Data));;
Set(varCircuit; Coalesce(varRow.circuit; Blank()));;
If(
IsBlank(varRow.ean) Or IsBlank(varCircuit) Or IsBlank(varRow.annee);
Notify("Sélectionnez un circuit, une année, puis une ligne EAN"; NotificationType.Warning);
Navigate(EcrHero; ScreenTransition.None)
)
Sans ce hop, le Patch est invisible dans Power BI. Aujourd’hui PRIO actuel lit Spec_Produit_Wide (Excel SharePoint Specifications_produits.xlsx). Objectifs lit Objectifs.xlsx. Dataverse n’est importé que pour cr568_negotiation_current.
| Option | Mécanique | Quand |
|---|---|---|
| A — recommandée (proche Saisie) | Flux cloud « Power Range Prio writeback » : On Create/Update de cr568_prio_decision et cr568_prio_objectif, import des deux tables (Import, pas DirectQuery), relation ean → Dim_Produit_EAN, refresh dataset 612ef347-…. COALESCE(Dataverse ; spec Excel). | Même contrat que Saisie. |
| B — Excel | Le flux upsert prio_ref_* et ranking_PL_* dans Specifications_produits.xlsx, et DV Objectif dans Objectifs.xlsx. Aucun changement DAX. | Uniquement si l’import Dataverse est refusé. Fragile (lock fichier, HD vs HORS HD). |
| Mesure PBI à rebrancher | Lecture actuelle | Après option A |
|---|---|---|
| PRIO actuel | TREATAS EAN → Spec_Produit_Wide[prio_ref_HM/SM/Proxi] | SELECTEDVALUE(cr568_prio_decision[cr568_prio]) filtré circuit+année ; fallback spec si pas de ligne |
| PL actuel | ranking_PL_* spec | cr568_ranking_pl ; fallback spec |
| DV Objectif Prio | SUM(Objectifs[DV Objectif]) | SUM Dataverse si source = SAISIE_APP, sinon Excel (union Power Query) |
Fallback spec. COALESCE(décision Dataverse ; spec Excel) : une SKU jamais touchée dans l’app continue d’afficher l’Excel. C’est le comportement attendu au go-live.
Refresh à la demande. Bouton app « Publier vers le rapport » = déclenchement du flux Power Automate, pas un refresh Desktop. Ne rafraîchir que si le Patch a réussi. Pas toutes les 5 min (le PPC négo garde son cadencement).
| # | Donné | Attendu |
|---|---|---|
| 1 | Slicer Tout / clic EAN / Enregistrer Hero | App refuse. Message circuit + année. |
| 2 | HM + 2025 + FOOD + UNITAIRE, ligne Hero proposé = HERO, accepter | Ligne Dataverse source=PROPOSE, prio=HERO. Après refresh, PRIO actuel = HERO sur cet EAN × HM. |
| 3 | Même filtre, forcer OTHER sur un Hero DAX | source=FORCE, commentaire obligatoire. PRIO actuel devient OTHER. Hero proposé reste HERO (DAX). |
| 4 | Même EAN, passer slicer SM | Autre ligne Dataverse (clé ean|SM|année). HM inchangé. CDC : un EAN peut être Hero HM et Other Proxi. |
| 5 | Onglet Strat, SKU déjà Hero proposé | Pas de Patch STRAT. Message renvoyer vers Hero. |
| 6 | Liste prio : deux EAN rang 1 | Refus ou décalage. Jamais deux rangs identiques actifs. |
| 7 | Objectifs : enseigne Drive | Patch refusé. |
| 8 | Utilisateur hors PS/DXI | App en lecture ou accès Dataverse refusé. |
| 9 | Embarquer l’app Saisie e890ef64 dans le slot Prio | Hors recette — interdit. Champs dates/DV négo, mauvais grain. |
| 10 | Doublon spec HD vs HORS HD même EAN 2025 | App n’écrit que HORS HD. PRIO actuel PBI ne doit plus rester blank après bascule Dataverse. |
| Livrable | Owner |
|---|---|
| Tables + choices + alternate keys + security roles dans PowerRange | Dataverse / DXI |
| Canvas app 4 écrans + Patch + Notify + bouton refresh | Power App |
| Visuel Power Apps × 4 pages Prio, bindings, drillFilter true, host_screen | Power BI |
| Mesures fallback Dataverse / spec pour PRIO actuel, PL actuel, DV Objectif Prio | Power BI |
| Flux On Create/Update → refresh dataset 612ef347-… | Power Automate |
| Remplacer Strat proposé DAX quand le score PS est codé dans l’app | Power App + PBI |