màj wiki avec retour MES lot-5 AD

This commit is contained in:
Arthur Ria
2026-05-20 09:41:27 +02:00
commit 23eb3f3c84
4106 changed files with 469381 additions and 0 deletions
@@ -0,0 +1,425 @@
# LIM-84 — Algorithme de séquençage des palettes (TK → PS)
## Ordonnancement des tâches de picking avant sortie de l'ASRS
> **Version 1.1** — 11 mai 2026
>
> Ce document décrit l'algorithme de séquençage qui définit **dans quel ordre** les palettes sources doivent sortir de l'ASRS (TK) à destination du poste de sortie (PS). Il s'exécute **en amont** de l'algorithme de placement PS → table PK [[Logique combinatoire picking - PS vers PK - V1.0]].
>
> Le résultat de cet algorithme est l'écriture des numéros de séquence `Line.CstAtt` sur chaque tâche de picking, et le positionnement de `OS.CstAtt = true` pour autoriser le stacker_crane à consommer les tâches.
### Changelog V1.1 (11/05/2026)
Modifications issues de la réunion Arthur + Justine (MECALUX) — Olivier (LIMAGRAIN), croisées avec l'AF et le DevOps #64854.
- **Hiérarchie des règles** : nouvel ordre de priorité validé (§3). La complétude palette et l'anti-split de lignes de stock sont désormais des contraintes amont prioritaires sur les règles de tri.
- **Picking négatif** : ajout d'une condition cumulative de poids ≥ 7 kg (§3.1 + §6.3).
- **Traitement commercial** : critère de regroupement par TC **supprimé** (`CONTROLE_TRAITEMENT_COMMERCIAL = false`). Le critère 3 de la V1.0 est retiré du tri.
- **Calcul de remplissage** : méthode pro rata Bag/pal validée, remplace la logique DevOps "Bag/pal max" (§3 — contrainte amont C1).
- **Poids max palette** : 1 250 kg (l'AF fait foi, corrige les 1 200 kg du DevOps).
- **Règles confirmées** : mélange d'espèces OK, pas de gerbage, hauteur max 1,90 m, séparateurs inter-lots hors WMS.
---
## 0. Glossaire rapide
|Terme|Définition|
|---|---|
|**TK**|Transtockeur / sortie ASRS (origine physique de la palette)|
|**PS**|Poste de sortie (point d'arrivée de la palette, avant placement sur table PK)|
|**OS**|Ordre de sortie (commande)|
|**OS.CstAtt**|Flag booléen sur l'OS. `false` = séquences non calculées, stacker_crane ignore. `true` = séquences prêtes, stacker_crane peut consommer.|
|**Line.CstAtt**|Numéro de séquence (entier) sur chaque tâche de picking. Définit l'ordre de sortie ASRS. Plusieurs tâches peuvent partager la même valeur (ex-aequo).|
|~~**TC**~~|~~Traitement commercial — attribut article.~~ **Supprimé V1.1** : `CONTROLE_TRAITEMENT_COMMERCIAL = false`. L'entrepôt ne fait pas de bio. Paramètre réactivable si besoin futur.|
|**Bag/pal**|Nombre de sacs par palette pour un lot donné. Sert au calcul de remplissage pro rata.|
---
## 1. Déclenchement
L'algorithme est déclenché sur **deux événements** :
### 1.1. `TaskCreatedEvent`
Une nouvelle tâche de picking vient d'être créée (par le MINI JOB Picking LIM-75, ou suite à une réassignation de stock).
```
SI événement.type == TaskCreatedEvent :
SI tâche.type == PICKING ET tâche.OS.statut == Released :
traiter_séquençage(tâche.OS)
```
### 1.2. `OutboundOrderReleasedEvent`
Un OS passe au statut Released (première mise en service, ou relance après un arrêt).
```
SI événement.type == OutboundOrderReleasedEvent :
traiter_séquençage(OS)
```
---
## 2. Process principal
```
FONCTION traiter_séquençage(OS) :
// ─── Étape 1 : verrouiller l'OS ───
OS.CstAtt ← false
// ─── Étape 2 : récupérer les tâches ───
toutes_tâches ← récupérer_tâches_picking(OS)
// ─── Étape 3 : filtrer ───
tâches_à_séquencer ← [t POUR t DANS toutes_tâches SI t.statut == EN_ATTENTE]
SI tâches_à_séquencer est vide :
OS.CstAtt ← true
RETOURNER
// ─── Étape 4 : trier ───
tâches_triées ← trier_tâches(tâches_à_séquencer) // cf. §3
// ─── Étape 5 : écrire les séquences ───
écrire_séquences(tâches_triées) // cf. §4
// ─── Étape 6 : libérer l'OS ───
OS.CstAtt ← true
```
---
## 3. Contraintes amont et règles de tri
> **V1.1** — La hiérarchie ci-dessous remplace toute hiérarchie antérieure. Elle distingue les **contraintes amont** (appliquées avant/pendant la constitution des palettes filles) et les **règles de tri** (appliquées au séquençage des tâches de picking).
### Contraintes amont (constitution des palettes filles)
Ces contraintes orientent le regroupement des lignes sur les palettes filles **avant** que l'algorithme de tri ne séquence les sorties ASRS. Elles ne sont pas des critères de tri à proprement parler, mais l'algorithme de séquençage doit les respecter : l'ordre de sortie doit être compatible avec la constitution de palettes conformes à ces règles.
#### C1. Palettes les plus complètes possible
Objectif premier — optimisation transport. Seuil de remplissage ~95% (marge de sécurité).
**Calcul : pro rata Bag/pal.** Chaque sac consomme `1/Bag_pal` de son lot. Le calcul est additif et gère nativement des lots avec des Bag/pal différents sur une même palette.
```
Exemple :
16 sacs d'un lot Bag/pal 20 + 7 sacs d'un lot Bag/pal 50
= 16/20 + 7/50
= 0,80 + 0,14
= 94%
```
Regrouper les lots de même Bag/pal sur une même palette fille facilite la complétude.
> _Note : cette méthode remplace la logique DevOps #64854 de "prendre le Bag/pal max entre lots" (V1.0 implicite). Le pro rata est plus précis et ne nécessite pas de Bag/pal de référence unique._
#### C2. Ne pas splitter les lignes de stock
Éviter de répartir les sacs d'une même ligne de stock sur plusieurs palettes. **Cette contrainte est prioritaire sur les règles de tri** : si respecter "Maïs first" implique de splitter une ligne, on regroupe la ligne complète quitte à décaler le maïs.
#### Autres contraintes palette
|Contrainte|Valeur|Source|
|---|---|---|
|Poids max palette|**1 250 kg**|AF (corrige 1 200 kg du DevOps)|
|Hauteur max palette|1,90 m|AF — rejet au PIE si dépassement|
|Gerbage|Interdit|—|
|Mélange d'espèces|Autorisé sur une même palette fille|—|
|Différenciation de marque|Aucune dans une même expédition|—|
|Séparateurs (intercalaires) entre lots|Règle opérateur, hors WMS|—|
### Règles de tri (séquençage des sorties ASRS)
Les tâches de picking d'un même OS sont triées selon les critères suivants, **par ordre de priorité décroissante** :
#### 3.1. Critère 1 — Picking négatif en premier
Les tâches de type PICKING_NÉGATIF passent **avant** les tâches de type PICKING_DIRECT.
Le picking négatif est **prioritaire sur toutes les règles de tri suivantes**, y compris Maïs first : si une tâche négatif concerne du tournesol, elle passe avant une tâche maïs classique.
> **V1.1** — Condition cumulative ajoutée pour la détermination NÉGATIF/DIRECT (cf. §6.3) : pourcentage quantité > seuil fiche article (défaut 55%) **ET** poids unitaire sac ≥ 7 kg. En dessous de 7 kg, pas de picking négatif (raison : instabilité palette si gros sacs ramenés sur petits sacs).
```
tri_1(tâche) → 0 si PICKING_NÉGATIF, 1 si PICKING_DIRECT
```
#### 3.2. Critère 2 — Espèce Maïs en premier
Les tâches portant sur l'espèce **Maïs** passent avant les autres espèces (si la commande contient du maïs).
Raison : le maïs est lourd/stable, il constitue la base de la palette fille.
```
tri_2(tâche) → 0 si espèce == MAÏS, 1 sinon
```
#### ~~3.3. Critère 3 — Regroupement par traitement commercial (TC)~~ **SUPPRIMÉ V1.1**
> `CONTROLE_TRAITEMENT_COMMERCIAL = false`. L'entrepôt ne fait pas de bio. Réactivable si besoin futur.
#### 3.3. Critère 3 — Espèce avec la plus grande quantité totale dans la commande
_(anciennement critère 4 en V1.0)_
Les tâches sont regroupées par espèce, et l'espèce ayant la **plus grande quantité totale de sacs** dans l'OS passe en premier.
Raison : commencer par l'espèce la plus volumineuse permet de constituer rapidement la base de la palette fille.
```
tri_3(tâche) → -quantité_totale_espèce(tâche.espèce, OS)
// négatif pour tri décroissant
```
#### 3.4. Critère 4 — Article/lot le plus lourd en base
_(anciennement critère 5 en V1.0)_
À espèce égale, les tâches portant sur les articles/lots **les plus lourds** passent en premier.
Corollaire : les semences essais, très légères, se retrouvent naturellement en haut de palette.
```
tri_4(tâche) → -tâche.article.poids
// négatif pour tri décroissant
```
#### 3.5. Critère 5 — Regroupement par palette source
_(anciennement critère 6 en V1.0)_
Toutes les tâches portant sur la **même palette source** sont consécutives.
Raison : l'opérateur enchaîne toutes les tâches d'une palette source avant de la libérer.
```
tri_5(tâche) → tâche.PALETTE_SOURCE.identifiant
```
### Récapitulatif du tri multi-critères (V1.1)
```
FONCTION trier_tâches(tâches) :
RETOURNER tâches.trier_par(
(1) type_picking ASC // NÉGATIF (0) avant DIRECT (1)
(2) espèce_maïs ASC // MAÏS (0) avant autres (1)
(3) quantité_espèce DESC // espèce la + volumineuse en premier
(4) poids_article DESC // article le + lourd en premier
(5) palette_source // regroupement par palette source
)
// Note V1.1 : le critère TC (V1.0 §3.3) est supprimé.
// La contrainte anti-split lignes de stock (C2) est gérée
// en amont lors de la constitution des palettes filles,
// pas dans ce tri.
```
---
## 4. Écriture des séquences (`Line.CstAtt`)
Une fois les tâches triées, on attribue un numéro de séquence à chacune.
### 4.1. Règle des ex-aequo
Quand deux tâches consécutives dans le tri sont **interchangeables** (l'ordre entre elles n'a aucun impact fonctionnel), elles reçoivent le **même numéro de séquence**. Cela laisse de la flexibilité au stacker_crane pour optimiser son débit.
### 4.2. Critères d'interchangeabilité
Deux tâches A et B sont interchangeables si :
- Elles portent sur la **même palette source**, **OU**
- Elles portent sur des **palettes sources différentes** mais tous les critères de tri sont identiques : même type de picking, même espèce, même quantité espèce, même poids article. Rien ne les départage fonctionnellement.
> _Note V1.1 : le TC n'entre plus dans les critères d'interchangeabilité._
### 4.3. Algorithme d'écriture
```
FONCTION écrire_séquences(tâches_triées) :
séquence_actuelle ← max(Line.CstAtt des tâches en cours) + 1
SI aucune tâche en cours :
séquence_actuelle ← 1
POUR i DE 0 À len(tâches_triées) - 1 :
tâche ← tâches_triées[i]
tâche.Line.CstAtt ← séquence_actuelle
SI i < len(tâches_triées) - 1 :
tâche_suivante ← tâches_triées[i + 1]
SI interchangeables(tâche, tâche_suivante) :
CONTINUER
SINON :
séquence_actuelle ← séquence_actuelle + 1
```
### 4.4. Exemple
```
Commande avec 5 tâches, après tri :
Tâche 1 : Palette A, Maïs, 500kg → séq 1
Tâche 2 : Palette B, Maïs, 500kg → séq 1 (interchangeable avec 1)
Tâche 3 : Palette C, Maïs, 500kg → séq 1 (interchangeable)
Tâche 4 : Palette D, Blé, 300kg → séq 2 (espèce différente)
Tâche 5 : Palette E, Blé, 300kg → séq 2 (interchangeable avec 4)
Résultat Line.CstAtt : [1, 1, 1, 2, 2]
Le stacker_crane peut sortir les palettes A, B, C dans n'importe quel ordre,
puis D ou E dans n'importe quel ordre.
```
> _Note V1.1 : l'exemple V1.0 avec TC différent (tâche 6) est retiré car le critère TC est désactivé._
---
## 5. Comportement du stacker_crane après séquençage
Ce n'est pas le périmètre de cet algorithme, mais pour mémoire :
```
Le stacker_crane :
- IGNORE les tâches dont OS.CstAtt == false
- Consomme les tâches dont OS.CstAtt == true
- Respecte l'ordre croissant des Line.CstAtt
- Entre tâches à séquence égale : libre d'optimiser (proximité ASRS, charge TK)
- Crée les tâches de mouvement TK → PS
```
Les palettes arrivent ensuite au PS, où l'algorithme de placement (document dédié) décide sur quelle table du PK les poser.
---
## 6. Cas particuliers
### 6.1. Recalcul suite à une nouvelle tâche (réassignation de stock)
Si une tâche est créée après que l'OS a déjà été séquencé, le `TaskCreatedEvent` déclenche un recalcul :
```
1. OS.CstAtt ← false
2. Filtrer : tâches EN_ATTENTE uniquement
3. Re-trier et réécrire les Line.CstAtt
(en commençant après le dernier numéro des tâches en cours)
4. OS.CstAtt ← true
```
### 6.2. Relance d'un OS arrêté
Si un OS est arrêté puis relancé (`OutboundOrderReleasedEvent`), le même process s'applique. Les tâches déjà en cours conservent leur séquence, les tâches en attente sont re-séquencées.
### 6.3. Picking négatif et détermination du type
Le type de picking (NÉGATIF ou DIRECT) est déterminé **par tâche** au moment de la création des tâches par le MINI JOB Picking (LIM-75), selon la règle :
```
SI quantité_à_prélever > seuil_article × quantité_palette_source
ET article unique dans la palette source
ET pas d'attribut logistique à capturer
ET poids_unitaire_sac ≥ 7 kg // ← AJOUT V1.1
ALORS → PICKING_NÉGATIF
SINON → PICKING_DIRECT
```
> **V1.1** — La condition de poids ≥ 7 kg est ajoutée comme condition **cumulative** (ET). En dessous de 7 kg, pas de picking négatif même si le % dépasse le seuil. Raison : instabilité palette (gros sacs ramenés sur petits sacs).
Le seuil % reste paramétrable par fiche article (champ "Complete quantity percent excess for negative picking", défaut : 55%).
La détermination négatif/direct se fait **en amont** (MINI JOB Picking, LIM-75), avant l'algorithme de séquençage. L'algorithme de séquençage lit ce type mais ne le calcule pas.
---
## 7. Paramètres WMS utilisés
|Paramètre|Description|Défaut|Statut V1.1|
|---|---|---|---|
|`CONTROLE_TRAITEMENT_COMMERCIAL`|Active le regroupement par TC dans le tri|~~`true`~~|**`false`** — désactivé|
|Seuil picking négatif|Par fiche article ("Complete quantity percent excess for negative picking")|55%|Inchangé|
|Poids min picking négatif|Poids unitaire sac minimum pour autoriser le picking négatif|**7 kg**|**NOUVEAU V1.1**|
|Seuil remplissage palette|Taux cible de remplissage palette fille|**~95%**|**NOUVEAU V1.1**|
|Poids max palette|Poids maximum d'une palette fille|**1 250 kg**|Corrigé (était 1 200 kg dans DevOps)|
---
## 8. Diagramme de flux
```
TaskCreatedEvent OutboundOrderReleasedEvent
(nouvelle tâche picking) (OS passe en Released)
│ │
▼ │
Tâche type PICKING │
ET OS statut Released ? │
│ │
OUI │
│ │
└──────────┬────────────────────┘
OS.CstAtt ← false
(stacker_crane bloqué)
Récupérer tâches de l'OS
Filtrer : tâches EN_ATTENTE uniquement
(tâches en cours = intouchables)
┌────────────────────────────┐
│ TRIER │
│ │
│ 1. Picking négatif first │
│ 2. Espèce Maïs first │
│ 3. Espèce + volumineuse │
│ 4. Article + lourd │
│ 5. Regrouper par palette │
│ source │
└────────────┬───────────────┘
Écrire Line.CstAtt
(ex-aequo si interchangeables)
OS.CstAtt ← true
(stacker_crane libéré)
Stacker_crane consomme
par Line.CstAtt croissant
→ crée mouvements TK → PS
Palette arrive au PS
→ algo de placement PS → PK
(autre document)
```
---
## 9. Points non traités (hors scope)
- Affichage opérateur au PK (combien de sacs ajouter, possibilité de dévier de la consigne) — à traiter une fois les fondations posées.
- Picking négatif < 7 kg en option (avantage opérationnel sans obligation) — nécessite discussion élargie.
- Messagerie carton (moins prioritaire que prépa classique, navette du lendemain, zone angle Est) — en attente de précisions.
- Verrou réception → recomptage avant picking (mentionné dans l'AF uniquement, non reconfirmé).
---
## 10. Sources de référence
Par ordre de fiabilité décroissante :
1. **Réunion 11/05/2026 + mails** — fait foi sur tous les points traités
2. **AF (Analyse Fonctionnelle)** — référence principale pour les points non abordés en réunion
3. **DevOps #64854** — le plus ancien, peut contenir des règles passées à la trappe mais utile pour vérification croisée