# Spécifications Technique 2.16.0 Corrigées
### ==TMA-155 Ajout des frais de distribution en fiche produit et actualisation composition pack (si existant).==
Travail a faire :
- Lors de l'intégration d'un CGN, valoriser et stocker la valeur contenue dans les champs **tauxDistri** et **fraiDistri** associés à un article si une valeur est différente de "vide".
Ajouter deux nouveaux champs en fiche article :
**Taux frais de distribution** : XX,XX %
**Montant frais de distribution** : YY,YY €
#### **Scénario 1 : Visualiser la fiche article depuis le catalogue général**
Conditions **Taux frais de distribution** :
```
Si tauxDistri > 0
Taux frais de distribution = **tauxDistri** %
Sinon si tauxDistri == 0
Taux frais de distribution = 0.00 %
Sinon
Ne pas afficher la ligne
```
Conditions **Montant frais de distribution** :
```
Si fraisDistri > 0
Montant frais de distribution = **fraisDistri** %
Sinon si tauxDistri == 0
Montant frais de distribution = 0.00 €
Sinon
Ne pas afficher la ligne
```
#### **Scénario 2 : Visualiser la fiche article depuis une commande**
La valorisation des deux valeurs se base selon les taux des remises MLO ET ALO.
Ce scénario est valable à **n'importe quel statut de la commande**.
:::info
### Mise à jour
Après analyse plus approfondie, il n'est plus nécessaire de passer par un service dédié. Le bon de commande possède bel et bien le taux associé à une remise MLO ALO.
Les deux valeurs peuvent donc être calculées coté front sans passer par un nouveau service.
:::
Algorithme a exécuter (uniquement si on vient du bon de commande) :
```
taux = 0;
remises = liste des remises du bon de commande :
Si remises contient la remise de type MLO ET ALO
taux = 0;
Sinon Si remises contient la remise de type MLO
taux = tauxRemiseMLO
Sinon Si remises contient la remise de type ALO
taux = tauxRemiseALO
Si taux est > 0
frais distrib = prix de l'article * taux / 100;
taux distrib = +taux %
Renseigner les deux lignes Taux frais de distribution et Montant frais de distribution
Sinon
Ne pas afficher les lignes
```
Respecter ce fonctionnement avec les boutons précédant suivant.
#### **En addition**
:::info
### Mise à jour
Un nouvel onglet 'Contenu' est ajouté pour y afficher le tableau "Composition du pack".
:::
Le tableau "Composition du pack" est à retirer de l'onglet composition et infos techniques.
**Condition pour afficher le nouvel onglet 'Contenu'**
```
Si proprietes.attr.type == 'BOX' ET qu'il existe au moins 1 composition d'articles :
Afficher un nouvel onglet à droite de Composition et infos techniques
Insérer le même tableau "Composition du pack" (toute la largeur de l'écran) qui se base sur les données issues de CGN.
Ajouter deux nouvelles colonnes dans le tableau
```
Précision sur les deux nouvelles colonnes :
**Nom colonne : Prix hors FD (En €)**
```
Si tauxDistri > 0
PrixHorsFD = puht - fraisDistri
Sinon
PrixHorsFD = puht
```
**Nom colonne : Frais distrib. (en €)**
```
Si tauxDistri > 0
FraisDistrib = fraisDistri
Sinon si tauxDistri == 0
FraisDistrib = 0
Sinon
FraisDistrib = vide
```
Renommer la colonne Prix de vente unitaire HT par **Prix Catalogue HT (en €)**
### ==TMA-127 - Persistance des filtres sur onglet Liste Magasin/Recap Commande pour utilisateur SA==
La persistance des filtres se fait uniquement coté front.
L'objectif est d'ajouter de nouveaux éléments persistants et de garder la même logique de persistance des filtres dans le projet.
Les filtres à persister sont : "conseiller ALI/NAL/ULF", "plateforme", "statut" et "BOX/CAM Obligatoire/Vrac"
Filtres persistant à ajouter au fichier environnement.ts :
```ts
// Filtre BOX CAM VRAC de l'onglet recap commande
RECAP_COMMANDE_FILTERS_BOX_CAM_VRAC: 'RecapCommandeFiltersBCC',
// Filtre Plateforme de l'onglet recap commande et liste magasin
GES_FILTERS_PLATEFORMES: 'GesFiltersPlateformes',
// Filtre conseillers de l'onglet recap commande et liste magasin
GES_FILTERS_CONSEILLERS: 'GesFiltersConseillers',
// Filtre Statut de l'onglet liste magasins
LISTE_MAGASIN_FILTERS_STATUT: 'ListeMagFiltersStatut'
```
Ajouter un service 'GestionnaireFiltreService'
Implémenter les fonctions suivantes :
```ts
// Permet de stocker les valeurs sélectionnées du filtre en question
void registerFiltre(valeur, filtre)
// Permet de récupérer les valeurs précédemment sélectionnées du filtre en question
getValuesFiltre(filtre)
// Permet de supprimer les valeurs des filtres RECAP_COMMANDE_FILTERS_BOX_CAM_VRAC, GES_FILTERS_PLATEFORMES, LISTE_MAGASIN_FILTERS_STATUT
resetFiltre()
```
**Algorithme à intégrer :**
- Le filtre "conseiller ALI/NAL/ULF" est tout le temps persistant. (Il n'y a pas de bouton de réinitialisation).
- Ne pas conserver le filtre "Statut", "Plateforme et BOX/CAM Obligatoire/Vrac" lors d'un changement d'offre ni après déconnexion/reconnexion
Uniquement filtre conseiller
```
// Initilisation
Lors du chargement de l'onglet recap-commande ou liste magasins
values = getValuesFiltre(GES_FILTERS_CONSEILLERS);
Si values est vide :
Charger la page (Existant à ne pas modifier).
Sinon
Associer les conseillers avec values et filtrer selon les values
```
```
// Click sur conseiller
registerFiltre(listeConseillerSelectionné, GES_FILTERS_CONSEILLERS)
```
Filtre "Statut", "Plateforme et "BOX/CAM Obligatoire/Vrac"
```
// A repeter pour chaque filtre a l'initilsiation
values = getValuesFiltre(FILTRE);
Si values est vide :
Charger la page (Existant à ne pas modifier).
Sinon
Associer le FILTRE avec values et filtrer selon les valeurs
```
```
// Click sur le filtre
registerFiltre(listeduFiltreSelectionné, FILTRE)
```
```
// Sortie de l'offre
Si l'utilisateur change d'url et que l'url ne contient pas '/references' ou '/magasins' ou '/recap' ou 'performances'
resetFiltre()
```
:::info
### Risques de régression
Risque que les autres filtres persistants ne fonctionnent plus exactement suite à l'ajout des 4 nouveaux filtres.
Du nouveau code vient s'ajouter aux composants B2bioDetailOffreRecapPage et B2bioListeMagasinsComponent qui sont déjà assez complexes. De nouvelles conditions vont donc s'ajouter ce qui pourrait potentiellement changer le comportement existant.
Il pourrait y avoir des difficultés à valoriser les filtres plateformes puisqu'ils ne sont pas structurés de la même manière sur les deux onglets.
Ces éléments feront l'objet d'une recette fine.
:::
### ==TMA-161 - Affichage du suivi de commande en magasin==
Modifier l'affichage des offres sur l'onglet suivi de commande en fonction de leur ancienneté et de leur type.
Uniquement coté back-end.
**Travail à effectuer :**
1. Ajouter de nouvelles valeurs dans la table ParametreFonctionnel et les indiquer dans le fichier ParametreFonctionnelCode.java
Ajouter 5 nouvelles cle/valeurs en BDD (table paramètres fonctionnels, schéma référentiel) correspondant au critère d'affichage (en nb de mois) :
- PRECO : 6
- PRECO_EVENEMENTIEL : 14
- PRECO_FEL : 6
- OPE : 2
- OPE_FEL : 2
2. Modifier le endpoint `/search` du micro-service commande et l'adapter en fonction des valeurs indiquées dans la table ParametreFonctionnel.
Fonction a créer :
```java
public EsPagedResponse<CommandeEsDto> suiviDeCommande(SearchCommandeDto searchDto)
```
Ne pas impacter la requete Elastic search
Ajouter du code JAVA qui va venir filtrer les catalogues en fonction des valeurs indiquées dans la table ParametreFonctionnel, puis associer les catalogues filtrés avec les commandes.
Modifier le end-point coté front pour appeler le nouveau afin d'afficher les commandes filtrées.
**Offre à filter**
#### Offre précommande ferme ou avec réassort
Afficher les offres de type "offre évenementielle" datant de moins de 14 mois après la date de fin d'opération (commandes préco et réassort)
--> Récupérer en base les commandes si finCommande >= dateDuJour - 14 mois puis afficher commande
--> Récupérer en base les commandes si dateFinReassort >= dateDuJour - 14 mois puis afficher commande
Afficher les offres pour tous les autres types datant de moins de 6 mois après date de fin d'opération (commandes préco et réassort)
--> Récupérer en base les commandes si finCommande >= dateDuJour - 6 mois puis afficher commande
--> Récupérer en base les commandes si dateFinReassort >= dateDuJour - 6 mois puis afficher commande
#### Offre précommande FEL
Afficher les offres datant de moins de deux mois après la date de fin de précommande
--> Récupérer en base les commandes si dateFinPrecommande >= dateDuJour - 2 mois puis afficher commande
#### Offre opération
Afficher les offres de type "FEL" datant de moins de 2 mois après la date de création de commande
--> Récupérer en base les commandes si dateCreationCommande >= dateDuJour - 2 mois puis afficher commande
Afficher les autres offres datant de moins de 2 mois après la date de création de commande réelle
--> Récupérer en base les commandes si dateCreationCommande >= dateDuJour - 2 mois puis afficher commande
:::info
### Remarque
La requete va par conséquent prendre légèrement plus de temps qu'aujourdhui.
:::
### ==TMA-314 - Suppression sur offre en réassort des semaines ou jours affichés en opérations==
#### **Travail a faire :**
1. Masquer la colonne 'Sem Jour livraison'
2. Modifier l'intégration des articles à une commande si l'offre est en période de réassort lors d'un retour ERP.
3. Modifier l'affichage du recap commande
4. Ajout d'un nouveau flag pour déterminer que la commande est de type REASSORT
#### **Ajout d'article à une commande:**
precommande = NULL signifie "Précommande avec réassort"
```
Si precommande == NULL ET que la date du jour est supérieur ou égale à la date de debut réassort
FLAG REASSORT = true (commande)
article.commandeSemaine = vide;
article.typeSemaine = null;
article.semaineOriginal = null;
article.semaine = null;
Sinon
FLAG REASSORT = false (commande)
```
#### **Retour ERP**
Lors de l'intégration d'une offre sur une commande dont le flag REASSORT = true, l'intégration se fait uniquement sur **codeArt**
#### **Page récap coté gestionnaire**
Ajout d'une nouvelle colonne "OPE" sur les onglets : 'Contrôle des quantités / engagement / Total'.
La colonne est affichée dès lors qu'une des commandes du tableau contient le flag REASSORT.
Cette colonne OPE, contiendra le cumul des quantités de l'article correspondant dont le flag REASSORT de la commande est égal à TRUE.
#### Export appro et tableau intégration
Lors de l'export des deux tableaux, les quantités renvoyées sont uniquement les commandes ou le flag REASSORT est différent de TRUE.
**Travail à faire**: Ajuster les requêtes ES de récupération de commande , en ajoutant la condition 'REASSORT !== TRUE' lors des deux exports.
### ==TMA-308 Ordre d'affichage du BDC sur lot2==
Ajouter le champ "ordre" sur les articles des catalogues d'offres.
Trier les articles en fonction de cette nouvelle valeur dans le BDC, l'export BDC Excel, l'affichage SA et les retours ERP par ordre d'affichage croissant.
Règle de regroupement :
Si valeur de champ "ordre" consécutive ET si arborescence en commun, alors regrouper l'arborescence (nature/rayon/famille/sous-famille) des articles au maximum,
Sinon répéter les niveaux.
**Travail à effectuer :**
Le tri se fera uniquement coté back-end, au niveau de la fonction sortArticlesCatalogueMarque du fichier CatalogueESHelper.java. Cela veut dire que les niveaux seront triés en amont coté back-end et sauvegardé via ElasticSearch. Le front récupérera donc les articles déjà triés.
1. Adapter la fonction de tri des niveaux lors de l’intégration d’une offre en y ajoutant de nouvelles règles métiers qui respectent les scénarios suivants :
#### **Scénario 1 : Champs "ordre" nul**
Si le champ "ordre" n'existe pas alors on laisse l'ordre existant (aujourd'hui).
#### **Scénario 2 : Tous les articles possèdent un champ "ordre" différent de null**
Trier les articles en fonction de leur valeur "ordre" par ordre croissant ET respecter règle de regroupement.
Si même valeur de champ "ordre" alors on laisse l'ordre existant (aujourd'hui).
#### **Scénario 3 : Seulement une partie des articles possèdent un champ "ordre" non nul**
Si champ "ordre" alors afficher en premier ces articles par ordre croissant ET respecter règle de regroupement puis afficher les autres articles d'ordre existant (aujourd'hui).
:::info
### Risque de regression
Potentiel risque de régression au niveau de l’export du bon de commande.
Potentiel risque de régression au niveau de l’impression.
:::
### ==TMA-281 - Ré-import des stocks limités==
#### **Travail a faire :**
- Ajouter Redis et Redisson (utile pour les verrous)
- Ajouter un service dédié à Redis au projet BtoBio-Back
- Service de connection à Redis
- Implémenter les différentes fonction utiles à la récupération et la modification de données
- Prévoir l'architecture permettant l'ajout d'un nouveau service REST dédié à Redis
- Intégrer redis au micro-service Catalogue et Commande (injection de dépendance)
- Ajouter le champ "stockLimite": (boolean) à un catalogue (true = si au moins un article est à stock limité sinon false)
- Ajouter le champ "stockLimite": (boolean) à un article du catalogue (true = un article à stock limité sinon false)
- Ajouter le champ "maj" à CatalogueDto (XML OFFRE COM)
- Adapter la fonction d'import d'une offre pour permettre la mise à jour du stock sur les articles associés à une offre
#### **Architecture Redis**
CLE :
```
codeOffre#codeProduit // A verifier codeOffre peut pas '#' et codeProduit
```
VALEUR :
```json
{
"stockCommandee" : number, // Nombre d'articles commandés
"stockActuel" : number // La quantité commandable associée à l'article
}
```
:::info
### Attention
En clé, il faut ajouter le code de l'offre et le code produit.
Nous suggérons d'ajouter le symbole '**#**' comme délimiteur.
Cela implique que le code produit ET que le code d'une offre ne pourra jamais contenir le symbole '**#**'.
:::
#### **Initialisation de redis**
Lors du lancement du micro service commande et catalogue. Le micro service en question fera uniquement en sorte de se connecter à l’instance de redis. Aucun calcul et aucun chargement de données ne sont effectués.
#### **Algorithme stock restant Integration d'une offre**
Lors de l'intégration d'un Catalogue d'offre
```
Si <maj></maj> est présent ET que maj est égale à "contingentement"
Mettre a jour les stocks de tous les articles
Pour chaque article du fichier XML:
Si l'article est connu du catalogue
Si contingentement est vide ou absent
stockLimite = false (L'article n'a pas de stock limité)
Sinon
stockLimite = true (L'article à un stock limité)
POSER VERROU(codeOffre#codeArticle)
Si aucune valeur existe dans redis
stockActuel = contingentement
stockCommandee = 0
Sinon
Si stockCommandee est vide (exemple : erreur serveur, tout est supprimé pour X raison)
stockCommandee = Récupération des quantités déja commandées (sum(qte) articlecommande coté BDD)
Si contingentement >= stockCommandee
stockActuel = contingentement (mise à jour du stock)
Sinon
stockActuel = stockCommandee
Afficher Warning
LIBERER VERROU(codeOffre#codeArticle)
Ajout d'un AUDIT 'CONTINGENTEMENT' qui contient le libelle 'Mise à jour du contingentement du codeArticle : XXXXX avec un stock à XX.XX du catalogue XXXXXX'
Pour chaque article du catalogue non présent dans le fichier XML :
POSER VERROU(codeOffre#codeArticle)
stockActuel = stockCommandee
LIBERER VERROU(codeOffre#codeArticle)
Sinon
Laisser traitement actuel
```
### ==TMA-280 - Gestion des stocks limités==
#### **Travail a faire :**
- Ajouter un nouveau end point (coté back) permettant de fournir les stocks restant à partir d'une liste de code article.
- Ajouter une nouvelle ligne 'Stock restant XXX' (coté front) (5 digits possibles sans retour à la ligne uniquement sur la première ligne) en dessous de la quantité d'un article en bon de commande et en fiche article qui affiche le stock restant associé à l'article.
- Modifier la requête PATCH (coté back) permettant l'ajout ou la modification d'une quantité d'un article en vérifiant si la quantité demandée est inférieur ou égale au stock restant ainsi que la gestion d'erreur.
- Ajuster le service de gestion d'erreur (coté front) qui vient ajouter des erreurs bloquantes si qteDemandé >= stockRestant
#### **Algorithme Lecture**
Lors de la lecture d'un article à stock restant, si aucune valeur n'est présente via REDIS (Exemple : erreur serveur, ou l'instance redis est supprimé pour X raison), il est nécessaire de recalculer les quantités commandées. La vérification si le stock est inexistant sera séquentiel.
```
// Fonction de lecture des stocks pour une commande magasin
Stocks = Récupération des stock de rédis
Si(Stocks inexistant){ // L'ensemble des appelants sera bloqué via l'utilisation du synchronized
Lock de la clé Redis(codeOffre#codeProduit)
Stocks.stockActuel = Récupération du stock actuel de l'article pour l'offre
Stocks.stockCommandee = Récupération des quantités déja commandées (sum(qte) articlecommande)
Stocks = Valorisation du stock dans la variable locale
Mise à jour dans Redis de la clé Redis(codeOffre#codeProduit)
Libération du Lock de la clé Redis(codeOffre#codeProduit)
}
renvoyer Stocks
```
#### **Accès au bon de commande**
Lors de l'accès au bon de commande, si stockLimite du catalogue est égal à true alors appeller le nouveau service REST qui va renvoyer les stocks limités des articles.
Et appeler le service de gestion d'erreur qui va automatiquement afficher les erreurs s'il y en a.
#### **Scénario 1 : Création d'une commande (bon de commande ou fiche article)**
Aucune mise à jour REDIS peut être effectuée.
```
Si la quantité est supérieure au stock restant ALORS
- Créer commande ET Afficher message d'erreur
```
#### **Scénario 2 : Modification de commande (Statut Brouillon) (bon de commande ou fiche article)**
Aucune mise à jour REDIS peut être effectuée.
```
Si la quantité est supérieure au stock restant ALORS
- Modifier la quantité et Afficher message erreur
```
#### **Scénario 3 : Click sur "commander"**
Cet algorithme permet une validation ou un refus global de la commande.
Une mise à jour REDIS est effectuée. Les quantités ne seront pas sauvegardées avant de faire les contrôles des stocks restants.
Un verrou mettra tous les autres clients en attente tant qu'il ne sera pas libéré.
Algorithme executé coté back-end.
```
// Fonction existante lors de l'action commander
Parcourir chaque article avec stockRestant de la commande
List<VERROU>.add(Verou article) // Liste des verrous des articles stocks
Si qte <= stock disponible
article suivant
else
Erreur, Envoyer ExceptionCustomStock ( status 409) sortie de boucle et libération de tous les verrous
Fin de boucle
Parcourir tous les vérrous
si pas erreur
Mise à jour de Redis et sauvegarde des quantités pour chaque article
finsi
Libération du verrou
Fin de boucle
```
Si une erreur est renvoyée, le front détectera l'exception, appellera le nouveau service REST qui va renvoyer les nouveaux stocks limités des articles et afficher les erreurs bloquante.
#### **Scénario 4 : Modification de commande (Statut Commandé) (bon de commande ou fiche article)**
Tout ce qui est autorisé par le stock restant est enregistré et sauvegardé en base et REDIS.
Tout ce qui excède les quantités restantes est refusé, avec message d'erreur, le stock restant est actualisé au niveau du bon de commande MAIS on conserve dans le champ de saisie, la nouvelle demande, charge à l'utilisateur d'adapter sa quantité au stock
Algorithme executé coté back-end.
```
// Fonction existante lors de l'action commander
Parcourir chaque article avec stockRestant de la commande
Poser verrou
Si qte <= stock disponible
Mise à jour BDD
Mise à jour coté REDIS
else
erreur = true
Libération du verrou
Fin de boucle
Si erreur = true
Envoyer erreur (notifier front)
```
Le même algorithme ci-dessus sera exécuté.
La seule différence est que :
```
Lors de la mise à jour de redis :
La quantité à metre à jour = QteSaisie - QtePrecedente
```
#### **Scénario 5 : Modification d'une quantité coté GESTIONNAIRE (Controle des quantités)**
```
Pour chaque article du tableau
Si l'Article contient un stock restant
- Alors griser la colonne (background-color : lightgrey;) + readonly
Sinon
- Laisser tel quel
```
:::info
### Risque de regression
Risque de régression sur l'affichage du bon de commande puisque le bon de commande contient déjà du code assez complexe, il se pourrait que certaines actions ne se comportent pas exactement de la même manière, comme c'est le cas aujourd'hui suite à l'ajout de nouvelles fonctions qui viennent complexifier le model métier.
:::