Listing Web

Périmètre

Cette documentation couvre la fonctionnalité nommée Listing web dans l'application.

Route UI :

  • /sku-slug-gamme

Routes API :

  • POST /api/excel/generate
  • GET /api/excel/history
  • GET /api/excel/download/:fileName

Fonctionnel

Objectif

Produire un fichier Excel de travail à partir de deux exports Akeneo :

  • un export produit
  • un export product model

L'objectif du fichier généré est de construire un pont entre :

  • les références produit
  • les slugs produit
  • les slugs de gamme

Un troisième fichier optionnel peut restreindre la génération à une liste de SKU.

Saisie utilisateur

L'utilisateur renseigne :

  • un nom de listing
  • un fichier export de taille ou export produit
  • un fichier export de model
  • un fichier optionnel liste de SKU

Une modale de confirmation affiche le récapitulatif avant lancement.

Résultat attendu

Le traitement génère un fichier Excel nommé :

  • listing_{nom_sanitized}.xlsx

L'utilisateur peut ensuite :

  • télécharger le fichier généré
  • consulter l'historique des générations précédentes

Historique

L'historique conserve jusqu'à 50 générations encore présentes sur disque.

Chaque entrée contient :

  • le nom du fichier généré
  • le nom du fichier produit source
  • le nom du fichier model source
  • le nom du fichier de filtre SKU éventuel
  • un indicateur de filtre SKU actif

Technique

Stack

  • Front : Angular
  • Back : Express
  • Traitement Excel : ExcelJS
  • Upload : Multer
  • Historique : JSON sur disque

Fichiers clés

Front :

  • linvosges_utilitaire_akeneo/src/app/features/sku-slug-gamme/sku-slug-gamme.component.ts
  • linvosges_utilitaire_akeneo/src/app/features/sku-slug-gamme/sku-slug-gamme.component.html
  • linvosges_utilitaire_akeneo/src/app/core/models/excel.model.ts

Back :

  • server/routes/excel.routes.js
  • server/utils/generateSkuSlugGamme.js
  • server/utils/skuSlugHistoryStore.js

Architecture générale

SkuSlugGammeComponent  -> POST FormData /api/excel/generate    -> excel.routes.js      -> multer upload des fichiers      -> generateSkuSlugGamme()        -> lecture des workbooks source        -> copie des feuilles source        -> construction feuille slug_sku_gamme        -> construction feuille liste_slug_avec_gamme        -> écriture du workbook de sortie        -> écriture historique JSON  -> GET /api/excel/download/:fileName

Enchaînement détaillé des appels

Utilisateur  -> SkuSlugGammeComponent.requestGeneration()  -> confirmation via modale  -> confirmGeneration()  -> generateExcel()  -> POST /api/excel/generate  -> excel.routes.js  -> multer stocke les fichiers dans server/uploads  -> generateSkuSlugGamme(productPath, modelPath, outputDir, referencePath, outputBaseName)  -> lecture workbook produit  -> lecture workbook model  -> copie des feuilles source dans le workbook de sortie  -> création feuille slug_sku_gamme  -> création feuille liste_slug_avec_gamme  -> écriture du .xlsx final  -> écriture historique JSON  -> réponse JSON front

Structure du fichier généré

Le workbook de sortie contient :

  • product
  • product_model
  • liste_references_stock si un fichier de filtre a été fourni
  • slug_sku_gamme
  • liste_slug_avec_gamme

Logique de transformation

1. Copie des données source

Les deux premières feuilles du workbook de sortie sont des copies simples :

  • feuille source produit -> product
  • feuille source model -> product_model

2. Résolution des colonnes obligatoires

Le moteur cherche ensuite les colonnes nécessaires :

Dans la feuille produit :

  • reference_interne_akeneo
  • reference_stock
  • slug-fr_FR avec fallback slug-de_DE
  • gamme-product_models

Dans la feuille model :

  • code
  • slug-fr_FR avec fallback slug-de_DE

Si une colonne obligatoire manque, la génération échoue avec une erreur explicite.

3. Construction du lookup de gamme

La feuille product_model sert à construire une map :

  • clé : code
  • valeur : slug

Cette map est ensuite utilisée pour résoudre les slugs de gamme à partir des références de model présentes sur les lignes produit.

4. Filtre optionnel par liste de SKU

Si un fichier de références est fourni :

  • la première colonne de sa première feuille est lue
  • un Set de SKU est construit
  • seules les lignes produit dont le SKU appartient à ce set sont conservées

Le moteur détecte de façon simple la présence ou non d'un header sur ce fichier.

5. Construction de la feuille slug_sku_gamme

Pour chaque ligne produit retenue :

  • référence interne Akeneo
  • référence stock
  • slug produit
  • clés product models
  • slug(s) de gamme résolus

Le slug de gamme peut contenir plusieurs valeurs séparées par des virgules si plusieurs models sont référencés.

6. Construction de la feuille liste_slug_avec_gamme

Cette feuille agrège une liste unique de valeurs :

  • d'abord les slugs de gamme
  • puis les slugs produit

Le dédoublonnage préserve l'ordre de première apparition.

Nom du fichier

Le nom saisi par l'utilisateur est sanitizé :

  • suppression des accents
  • remplacement des caractères non alphanumériques par _
  • suppression des _ parasites

Le fichier est ensuite généré sous la forme :

listing_{nom_sanitized}.xlsx

Historique et stockage

Les exports sont écrits dans :

  • server/exports/

L'historique est persisté dans :

  • server/exports/sku-slug-history.json

Le store :

  • conserve 50 entrées maximum
  • masque les entrées dont le fichier n'existe plus

Nettoyage des uploads

Les fichiers uploadés sont supprimés en finally une fois la réponse envoyée ou l'erreur gérée.

Points d'attention

  • le moteur lit uniquement la première feuille de chaque fichier source
  • les noms de colonnes doivent respecter les exports attendus
  • le fallback slug FR puis DE est codé en dur
  • la génération ne dépend pas d'Akeneo en direct, uniquement des exports Excel fournis par l'utilisateur

Limites actuelles

  • le traitement ne préserve pas les styles avancés des feuilles source, il copie avant tout les valeurs
  • aucun contrôle métier fort n'est appliqué sur la cohérence des slugs produits vs slugs de gamme
  • le filtre SKU attend une liste simple en première colonne