415 lines
13 KiB
Markdown
415 lines
13 KiB
Markdown
# Ordinamento di prelievo delle celle
|
|
|
|
## 1. Scopo del documento
|
|
|
|
Questo documento descrive il significato e l'origine del campo
|
|
`dbo.Celle.Ordinamento`, il modo in cui viene utilizzato per proporre le UDC al
|
|
barcode e le differenze riscontrate tra i due magazzini storici:
|
|
|
|
- Area 5, identificata nel database legacy come magazzino `MDE5`;
|
|
- Area 6, identificata nel database legacy come magazzino `MDE6`.
|
|
|
|
Nel linguaggio operativo si parla di Area 5 e Area 6. Nel modello legacy,
|
|
tuttavia, la tabella `Magazzini` contiene `MDE5` e `MDE6`, mentre la tabella
|
|
`Aree` contiene le singole corsie o scaffali. Gli ID della tabella `Aree` non
|
|
devono quindi essere confusi con i nomi operativi Area 5 e Area 6.
|
|
|
|
Le conclusioni riportate derivano da:
|
|
|
|
- struttura e dati correnti della tabella `dbo.Celle`;
|
|
- stored procedure legacy contenute in `script.sql`;
|
|
- viste usate dalle picking list;
|
|
- codice Python del barcode e della gestione picking list;
|
|
- confronto tra `ID`, ubicazione e `Ordinamento` delle celle reali.
|
|
|
|
## 2. Significato di `Celle.Ordinamento`
|
|
|
|
`Celle.Ordinamento` e' una priorita' numerica associata all'anagrafica della
|
|
cella. Rappresenta la posizione della cella nel percorso predefinito di
|
|
prelievo.
|
|
|
|
Il campo non indica:
|
|
|
|
- la quantita' di UDC presenti;
|
|
- la priorita' della picking list;
|
|
- lo stato libero o occupato della cella;
|
|
- l'ordine cronologico di inserimento delle UDC;
|
|
- l'ID della UDC;
|
|
- la distanza calcolata dinamicamente dal barcode.
|
|
|
|
Il valore non viene ricalcolato durante un versamento o un prelievo. E' un dato
|
|
statico dell'anagrafica della cella, salvo interventi amministrativi o
|
|
procedure specifiche di rinumerazione.
|
|
|
|
Il tipo SQL storico e' `float`, ma nei dati analizzati viene usato come numero
|
|
intero progressivo. Nella futura riprogettazione sarebbe preferibile un tipo
|
|
intero o una struttura esplicita di percorso.
|
|
|
|
## 3. Dove viene assegnato
|
|
|
|
La stored procedure legacy `dbo.spt_SaveCelle` riceve il parametro
|
|
`@Ordinamento` e lo salva direttamente:
|
|
|
|
```sql
|
|
UPDATE Celle
|
|
SET Ordinamento = @Ordinamento
|
|
WHERE ID = @ID;
|
|
```
|
|
|
|
Se la cella non esiste, la stessa stored procedure esegue una `INSERT` e
|
|
inserisce il valore ricevuto. La procedura non contiene una formula per
|
|
calcolarlo: chi crea o modifica la cella deve decidere il valore e passarlo.
|
|
|
|
Nel database non risultano trigger sulla tabella `Celle` che aggiornino
|
|
automaticamente `Ordinamento`.
|
|
|
|
Sono state individuate anche procedure legacy di supporto:
|
|
|
|
- `CreaNuoveCelle`;
|
|
- `CreaNuoveCelleMDE6`;
|
|
- `CreaNuoveCelleMDE6_BIS`;
|
|
- `sp_OrdinaCelle`;
|
|
- `spt_SaveCelle`.
|
|
|
|
Le procedure di creazione MDE6 impostano normalmente:
|
|
|
|
```sql
|
|
SET @Ordinamento = @ID;
|
|
```
|
|
|
|
La procedura `sp_OrdinaCelle` dimostra invece che il campo puo' essere
|
|
rinumerato in un secondo momento per rappresentare un percorso differente
|
|
dall'ID della cella.
|
|
|
|
## 4. Uso durante una picking list
|
|
|
|
Le viste operative associano ogni UDC alla cella corrente e recuperano
|
|
`Celle.Ordinamento`. Il barcode richiede la prima riga residua secondo l'ordine
|
|
effettivo.
|
|
|
|
Prima dell'introduzione della sequenza personalizzata, il criterio principale
|
|
era sostanzialmente:
|
|
|
|
```sql
|
|
ORDER BY Ordinamento;
|
|
```
|
|
|
|
Questo significa che il barcode non percorre tutte le celle del magazzino. La
|
|
vista contiene soltanto le UDC ancora presenti nella picking list: le celle che
|
|
non contengono una UDC richiesta vengono saltate automaticamente.
|
|
|
|
Esempio: se il percorso contiene le celle con ordine `1001`, `1002`, `1003` e
|
|
`1004`, ma la picking list contiene UDC soltanto nelle celle `1001` e `1004`, il
|
|
barcode propone direttamente la UDC di `1001` e poi quella di `1004`.
|
|
|
|
## 5. Ordinamento dell'Area 5 / MDE5
|
|
|
|
### 5.1 Caratteristica generale
|
|
|
|
Nell'Area 5 `Ordinamento` non coincide normalmente con l'ID della cella. Dai
|
|
dati emerge un percorso fisico costruito intenzionalmente, verosimilmente
|
|
hardcoded o rinumerato durante la configurazione iniziale del magazzino.
|
|
|
|
Le corsie principali coinvolte sono:
|
|
|
|
- `1A`;
|
|
- `2B`;
|
|
- `3C`;
|
|
- `4D`.
|
|
|
|
Il percorso iniziale delle corsie `1A` e `2B` e' a serpentina. Le due corsie
|
|
vengono trattate come lati o scaffali adiacenti di uno stesso tragitto fisico.
|
|
|
|
### 5.2 Esempio reale dell'inizio del percorso
|
|
|
|
```text
|
|
Ordine Ubicazione ID cella
|
|
1001 1A.1.e 1005
|
|
1002 1A.1.d 1004
|
|
1003 1A.1.c 1003
|
|
1004 1A.1.b 1002
|
|
1005 1A.1.a 1001
|
|
|
|
1007 2B.1.e 2005
|
|
1008 2B.1.d 2004
|
|
1009 2B.1.c 2003
|
|
1010 2B.1.b 2002
|
|
1011 2B.1.a 2001
|
|
|
|
1013 2B.2.e 2011
|
|
1014 2B.2.d 2010
|
|
1015 2B.2.c 2009
|
|
1016 2B.2.b 2008
|
|
1017 2B.2.a 2007
|
|
|
|
1019 1A.2.e 1011
|
|
1020 1A.2.d 1010
|
|
1021 1A.2.c 1009
|
|
1022 1A.2.b 1008
|
|
1023 1A.2.a 1007
|
|
```
|
|
|
|
La sequenza prosegue con lo stesso principio:
|
|
|
|
```text
|
|
1A campata 1
|
|
2B campata 1
|
|
2B campata 2
|
|
1A campata 2
|
|
1A campata 3
|
|
2B campata 3
|
|
2B campata 4
|
|
1A campata 4
|
|
...
|
|
```
|
|
|
|
### 5.3 Movimento verticale nella campata
|
|
|
|
All'interno di ciascuna campata l'ordine verificato e':
|
|
|
|
```text
|
|
e -> d -> c -> b -> a
|
|
```
|
|
|
|
Il percorso procede quindi dal livello identificato con `e` verso il livello
|
|
`a`. Non viene prelevata una sola UDC per campata per poi ricominciare il giro.
|
|
Vengono considerate, in sequenza, tutte le celle richieste della campata
|
|
corrente prima di passare alla campata successiva.
|
|
|
|
Se una campata contiene piu' UDC richieste in livelli diversi, il barcode le
|
|
propone secondo `e, d, c, b, a`. Se alcuni livelli non contengono UDC della
|
|
picking list, vengono semplicemente saltati.
|
|
|
|
### 5.4 Alternanza tra 1A e 2B
|
|
|
|
Il sistema non esaurisce tutto `1A` prima di iniziare `2B`. Alterna blocchi di
|
|
campate tra le due corsie per seguire un tragitto a serpentina ed evitare
|
|
ritorni inutili.
|
|
|
|
Il comportamento predefinito storico e' quindi:
|
|
|
|
- completare le UDC richieste nella campata corrente;
|
|
- passare alla campata fisicamente successiva del percorso;
|
|
- alternare `1A` e `2B` secondo la serpentina configurata;
|
|
- non tornare all'inizio dopo ogni singola UDC.
|
|
|
|
### 5.5 Passaggio a 3C e 4D
|
|
|
|
Le corsie `3C` e `4D` hanno valori di ordinamento molto piu' alti. Nei dati
|
|
analizzati:
|
|
|
|
```text
|
|
1A: minimo 1001, massimo 1275
|
|
2B: minimo 1007, massimo 1251
|
|
3C: minimo 10019, massimo 10227
|
|
4D: valori nell'intervallo 10055 - 10233 circa
|
|
```
|
|
|
|
Di conseguenza il percorso storico esaurisce normalmente il blocco `1A/2B`
|
|
prima di passare al blocco `3C/4D`.
|
|
|
|
La presenza di famiglie numeriche differenti indica che l'ordinamento
|
|
dell'Area 5 e' stato costruito o modificato in piu' fasi storiche.
|
|
|
|
### 5.6 Significato dei numeri mancanti
|
|
|
|
La progressione contiene intervalli non utilizzati, per esempio `1005` seguito
|
|
da `1007`. Il numero mancante non indica necessariamente una cella eliminata o
|
|
un errore. Puo' essere stato lasciato come separatore tra campate o derivare
|
|
dalla procedura di rinumerazione.
|
|
|
|
Il software deve usare il confronto numerico e non deve presumere che tutti i
|
|
valori siano consecutivi.
|
|
|
|
## 6. Ordinamento dell'Area 6 / MDE6
|
|
|
|
### 6.1 Caratteristica generale
|
|
|
|
Nell'Area 6 il modello e' piu' semplice. La maggior parte delle celle e' stata
|
|
generata con `Ordinamento` uguale all'ID della cella.
|
|
|
|
Le famiglie principali sono:
|
|
|
|
```text
|
|
1M -> celle e ordinamenti 5001, 5002, 5003, ...
|
|
2N -> celle e ordinamenti 6001, 6002, 6003, ...
|
|
3O -> celle e ordinamenti 7001, 7002, 7003, ...
|
|
4P -> celle e ordinamenti 8001, 8002, 8003, ...
|
|
```
|
|
|
|
Le procedure `CreaNuoveCelleMDE6` e `CreaNuoveCelleMDE6_BIS` creano le celle
|
|
con cicli annidati e assegnano esplicitamente:
|
|
|
|
```sql
|
|
SET @Ordinamento = @ID;
|
|
```
|
|
|
|
### 6.2 Ordine degli scaffali
|
|
|
|
Poiche' le famiglie numeriche sono separate, l'ordine globale predefinito e':
|
|
|
|
```text
|
|
1M -> 2N -> 3O -> 4P
|
|
```
|
|
|
|
Senza una sequenza personalizzata vengono quindi considerate prima tutte le
|
|
UDC richieste in `1M`, poi quelle in `2N`, successivamente `3O` e infine `4P`.
|
|
|
|
### 6.3 Ordine interno dello scaffale
|
|
|
|
Durante la generazione delle celle, i cicli legacy incrementano prima la
|
|
campata e, all'interno della campata, il piano. L'ordine risultante e':
|
|
|
|
```text
|
|
1M.1.a -> 1M.1.b -> 1M.1.c -> 1M.1.d -> 1M.1.e
|
|
1M.2.a -> 1M.2.b -> 1M.2.c -> 1M.2.d -> 1M.2.e
|
|
...
|
|
2N.1.a -> 2N.1.b -> ...
|
|
```
|
|
|
|
Quindi l'Area 6 differisce dall'Area 5 in due aspetti principali:
|
|
|
|
- non presenta l'alternanza a serpentina tra due corsie adiacenti;
|
|
- dentro la campata procede da `a` verso `e`, mentre nell'Area 5 verificata
|
|
procede da `e` verso `a`.
|
|
|
|
### 6.4 Limiti della ricostruzione
|
|
|
|
Il comportamento descritto deriva dalla procedura di generazione e dai valori
|
|
correnti. Eventuali celle aggiunte manualmente in tempi successivi possono
|
|
avere eccezioni. L'applicazione deve sempre leggere il valore effettivo dal
|
|
database e non ricostruirlo aritmeticamente dall'ubicazione.
|
|
|
|
## 7. Celle virtuali
|
|
|
|
Nel sistema legacy esistono due ubicazioni convenzionali:
|
|
|
|
```text
|
|
ID 1000 -> 5E.1.1 -> Non scaff. -> Ordinamento 99999
|
|
ID 9999 -> 7G.1.1 -> Spedita -> Ordinamento 0
|
|
```
|
|
|
|
Questi valori non rappresentano un percorso fisico:
|
|
|
|
- `5E.1.1` identifica UDC presenti nel magazzino ma non allocate in uno
|
|
scaffale fisico;
|
|
- `7G.1.1` identifica UDC spedite.
|
|
|
|
Storicamente `Non scaff.` aveva ordinamento `99999`, quindi finiva in fondo
|
|
alla picking list. Il nuovo requisito operativo stabilisce invece che le UDC
|
|
non scaffalate devono essere proposte per prime.
|
|
|
|
La nuova vista Python non modifica `Celle.Ordinamento`: assegna a `Non scaff.`
|
|
una precedenza logica di gruppo pari a zero. La cella `Spedita` non entra nella
|
|
vista residuale e quindi non viene proposta dal barcode.
|
|
|
|
## 8. Nuovo ordinamento predefinito Python
|
|
|
|
In assenza di una configurazione specifica per il documento, il nuovo ordine
|
|
effettivo e':
|
|
|
|
1. tutte le UDC `Non scaff.` ancora appartenenti alla picking list;
|
|
2. tutte le UDC nelle celle fisiche secondo `Celle.Ordinamento`;
|
|
3. codice pallet come criterio stabile in caso di parita'.
|
|
|
|
In forma semplificata:
|
|
|
|
```sql
|
|
ORDER BY
|
|
OrdinePrelievoGruppo,
|
|
Ordinamento,
|
|
Pallet;
|
|
```
|
|
|
|
Per le celle fisiche, se non esiste una personalizzazione,
|
|
`OrdinePrelievoGruppo` conserva la progressione storica. Il percorso dell'Area
|
|
5 rimane quindi a serpentina e quello dell'Area 6 rimane progressivo.
|
|
|
|
## 9. Effetto della sequenza personalizzata
|
|
|
|
La sequenza personalizzata opera a livello di gruppo o scaffale, non a livello
|
|
di singola cella.
|
|
|
|
Esempio di configurazione:
|
|
|
|
```text
|
|
1. Non scaff.
|
|
2. 3C
|
|
3. 1A
|
|
4. 2B
|
|
5. 4D
|
|
```
|
|
|
|
In questo caso il sistema esaurisce prima il gruppo `Non scaff.`, poi tutte le
|
|
UDC di `3C`, quindi tutte quelle di `1A` e cosi' via.
|
|
|
|
All'interno di ciascun gruppo continua a usare `Celle.Ordinamento`. Per
|
|
esempio, se `1A` viene posizionata prima di `2B`, non viene piu' conservata
|
|
l'alternanza storica tra `1A` e `2B`: vengono esaurite prima tutte le UDC di
|
|
`1A`, nel loro ordine interno, e successivamente quelle di `2B`.
|
|
|
|
Questa differenza e' intenzionale:
|
|
|
|
- ordine predefinito: conserva il percorso storico globale;
|
|
- ordine personalizzato: impone la precedenza degli scaffali scelta
|
|
dall'operatore e conserva l'ordine storico soltanto dentro ogni scaffale.
|
|
|
|
Se la sequenza personalizzata non include tutti i gruppi, quelli mancanti
|
|
vengono accodati secondo il percorso predefinito. Nessuna UDC viene esclusa.
|
|
|
|
## 10. UDC multiple, lotti e parita' di ordine
|
|
|
|
Piu' righe della vista possono riferirsi alla stessa UDC quando contiene piu'
|
|
lotti o articoli. Questo non significa che il magazziniere debba movimentare
|
|
fisicamente la stessa UDC piu' volte: l'unita' di movimentazione rimane il
|
|
pallet/UDC.
|
|
|
|
Piu' UDC possono inoltre risultare associate alla stessa cella nel modello
|
|
legacy. In quel caso condividono lo stesso `Ordinamento`. Il nuovo codice usa
|
|
anche `Pallet` come criterio finale per rendere stabile la sequenza, ma il
|
|
percorso fisico resta quello della cella.
|
|
|
|
## 11. Considerazioni per la futura riprogettazione
|
|
|
|
Nel futuro FlyWMS Core e' consigliabile separare esplicitamente:
|
|
|
|
- ordine fisico della cella dentro lo scaffale;
|
|
- ordine predefinito degli scaffali;
|
|
- percorso o strategia di visita del magazzino;
|
|
- ordine personalizzato per documento;
|
|
- priorita' operativa della picking list;
|
|
- eventuale ottimizzazione dinamica del percorso.
|
|
|
|
Il campo legacy `Celle.Ordinamento` incorpora piu' significati e dipende da
|
|
decisioni storiche non completamente documentate. Non dovrebbe essere copiato
|
|
alla lettera nel nuovo modello dati senza scomporne la semantica.
|
|
|
|
Una possibile struttura futura potrebbe prevedere:
|
|
|
|
- `Location.SequenceWithinRack` per l'ordine interno;
|
|
- `Rack.DefaultSequence` per l'ordine tra scaffali;
|
|
- `Route` e `RouteStep` per percorsi configurabili;
|
|
- `PickingDocumentRoute` per la personalizzazione della singola lista.
|
|
|
|
## 12. Riferimenti tecnici nel progetto
|
|
|
|
- `script.sql`: definizioni di `spt_SaveCelle`, `CreaNuoveCelleMDE6`,
|
|
`CreaNuoveCelleMDE6_BIS` e `sp_OrdinaCelle`;
|
|
- `barcode_repository.py`: interrogazione della prossima UDC;
|
|
- `gestione_pickinglist.py`: visualizzazione del dettaglio ordinato;
|
|
- `pickinglist_sequence.py`: gestione della sequenza per documento;
|
|
- `apply_pickinglist_sequence_patch.sql`: tabella e vista Python dedicate;
|
|
- `specifica_sequenza_prelievo.md`: specifica funzionale della nuova
|
|
configurazione.
|
|
|
|
## 13. Conclusione
|
|
|
|
L'Area 5 utilizza un percorso storico a serpentina, costruito per alternare
|
|
corsie e campate secondo la disposizione fisica. L'Area 6 utilizza invece una
|
|
progressione piu' semplice, sostanzialmente coincidente con gli ID creati in
|
|
sequenza.
|
|
|
|
Il nuovo software conserva entrambi i comportamenti come default, anticipa le
|
|
UDC non scaffalate e permette di sostituire l'ordine globale degli scaffali per
|
|
una singola picking list senza modificare l'anagrafica delle celle.
|