Milestone alpha2

This commit is contained in:
2026-05-22 15:15:43 +02:00
parent a5e704c214
commit d2a1f6a068
4 changed files with 508 additions and 64 deletions

View File

@@ -586,3 +586,236 @@ Dopo approvazione di questo documento:
2. testare il risultato con almeno 3 picking list attive
3. verificare il comportamento sul backoffice
4. verificare il comportamento sul barcode (`F1` / `F2`)
---
## Revisione dopo test reale su documenti 133 / 135 / 137
Dopo avere applicato la prima correzione proposta solo sulla stored, il bug **resta presente**:
- prenotando il documento `133`
- la picking list `135` continua a risultare prenotata
Questo comportamento è coerente con le evidenze raccolte:
- `133` e `135` condividono la cella `8057`
- `135` e `137` condividono la cella `1000`
### Conclusione aggiornata
La correzione che agisce **solo** su `Celle.IDStato` non è sufficiente.
Il motivo è strutturale:
1. la stored può anche rendere idempotente `Prenota` / `S-prenota`
2. ma se la UI e il barcode continuano a dedurre lo stato della prenotazione da `Celle.IDStato`
3. una cella condivisa continuerà a far risultare prenotati anche documenti diversi
Quindi il modello corretto deve spostare la **sorgente di verità** della prenotazione:
- **da:** stato della cella
- **a:** documento prenotato attivo
### Nuova architettura proposta
La soluzione corretta è questa:
1. introdurre una piccola tabella di stato, ad esempio `dbo.PickingListReservation`
2. salvare lì il **documento attualmente prenotato**
3. fare in modo che `XMag_ViewPackingList.IDStato` non legga più la prenotazione da `Celle.IDStato`
4. calcolare invece `IDStato` così:
- `1` se `Documento = documento prenotato attivo`
- `0` negli altri casi
In questo modo:
- il backoffice mostra prenotata una sola picking list
- il barcode continua a usare `F1` = `IDStato 1` e `F2` = `IDStato 0`
- le celle condivise `1000` / `8057` non contaminano più altri documenti
### Ruolo residuo di `Celle.IDStato`
`Celle.IDStato` può restare utile come supporto:
- per visualizzazioni legacy
- per evidenziare le celle del documento attivo
- per non rompere altre parti del sistema che si aspettano quel flag
Ma non deve più essere la **fonte primaria** della prenotazione documento.
### Stored definitiva da realizzare
La stored `sp_xExePackingListPallet` deve quindi:
1. mantenere il parametro `@Azione = 'P' | 'S'`
2. aggiornare la tabella `PickingListReservation`
3. opzionalmente riallineare anche `Celle.IDStato`
4. mantenere il log in `LogPackingList`
Semantica definitiva:
- `Prenota`
- se il documento è già quello attivo: nessun effetto
- altrimenti:
- il documento diventa lunico prenotato attivo
- tutte le altre picking list risultano non prenotate
- `S-prenota`
- se il documento non è quello attivo: nessun effetto
- se il documento è quello attivo:
- la prenotazione viene rimossa
- nessun altro documento viene acceso automaticamente
### Nota importante
Questa revisione **supera** la proposta precedente basata soltanto sul reset/set di `Celle.IDStato`.
La patch SQL definitiva deve quindi includere:
1. creazione della tabella `PickingListReservation`
2. `CREATE OR ALTER` della stored `sp_xExePackingListPallet`
3. `CREATE OR ALTER` della vista `XMag_ViewPackingList`
Questo è il primo assetto realmente coerente con il requisito di business:
> una sola picking list prenotata alla volta, anche in presenza di celle condivise.
---
## Evoluzione proposta: usare `ViewPackingListRestante` anche per la lista alta
### Situazione attuale
Nel legacy C# e nel Python attuale la distinzione è questa:
- la **griglia alta** legge la testata aggregata da `XMag_ViewPackingList`
- la **griglia bassa** legge il dettaglio da `ViewPackingListRestante`
La vista `ViewPackingListRestante` è definita come:
```sql
SELECT ...
FROM XMag_ViewPackingList
WHERE Cella <> 9999
```
Quindi:
- `XMag_ViewPackingList` contiene anche le UDC già finite nella locazione convenzionale `9999 = 7G.1.1`
- `ViewPackingListRestante` mostra invece solo le UDC ancora residue
### Conseguenza pratica
Allistante `t = 0` della prenotazione:
- se la picking list non è ancora stata lavorata, `XMag_ViewPackingList` e `ViewPackingListRestante` mostrano di fatto lo stesso insieme di UDC
- le UDC non scaffalate **restano presenti** in entrambe, perché stanno nella cella convenzionale `1000 = 5E1.1`
Dopo che il magazziniere ha iniziato i prelievi:
- le UDC già spedite/prelevate finiscono in `9999 = 7G.1.1`
- quindi spariscono da `ViewPackingListRestante`
- ma restano ancora visibili in `XMag_ViewPackingList`
### Limite del comportamento attuale
Con la summary alta basata su `XMag_ViewPackingList`:
- il comando `Ricarica` può continuare a mostrare picking list già lavorate in parte
- una picking list completamente esaurita può restare visibile nella lista alta
- il contenuto della lista alta non coincide più con il “residuo operativo reale”
In altre parole:
- la griglia bassa mostra il residuo
- la griglia alta mostra ancora lo storico completo
### Modifica proposta
La proposta è:
- usare `ViewPackingListRestante` anche come sorgente della **lista alta aggregata**
quindi sostituire, nella query summary di [gestione_pickinglist.py](C:/devel/python/ware_house/gestione_pickinglist.py):
- `FROM dbo.XMag_ViewPackingList`
con:
- `FROM dbo.ViewPackingListRestante`
mantenendo invariati:
- `GROUP BY Documento, CodNazione, NAZIONE, Stato`
- `COUNT(DISTINCT Pallet)`
- `COUNT(DISTINCT Lotto)`
- `COUNT(DISTINCT Articolo)`
- `SUM(Qta)`
- `MIN(Ordinamento)`
- `MAX(IDStato)`
### Effetti attesi
Con questa modifica:
1. allinizio una picking list nuova continua a comparire normalmente
2. durante il lavoro il pulsante `Ricarica` mostra solo ciò che resta davvero da prelevare
3. le UDC già finite in `7G.1.1` non inquinano più i conteggi della testata
4. una picking list completamente esaurita esce naturalmente dalla lista visibile
5. le UDC non scaffalate continuano a comparire correttamente, perché stanno in `1000 = 5E1.1`, non in `9999`
### Chiusura automatica della prenotazione
Per mantenere coerenti:
- griglia alta
- stato della prenotazione
- comportamento del barcode `F1`
la prenotazione attiva non deve soltanto sparire dalla griglia: deve essere anche **azzerata logicamente** quando il residuo arriva a zero.
La patch SQL definitiva quindi deve fare anche questo:
- dopo ogni movimento, controllare se il documento prenotato ha ancora righe in `ViewPackingListRestante`
- se non ne ha più:
- la prenotazione attiva va portata a `NULL` / `0`
- le eventuali celle residue marcate `IDStato = 1` vanno riportate a `0`
Effetto operativo:
- plist piena allinizio
- plist via via ridotta durante i prelievi
- plist che, allultima UDC, sparisce dalla griglia alta
- e nello stesso momento cessa anche di essere la coda `F1`
### Impatto funzionale
Questa modifica:
- **non è** una replica pedissequa del legacy C#
- ma è un miglioramento operativo coerente con il comportamento atteso dal magazzino
In particolare rende la lista alta:
- più coerente con il significato di “picking list ancora da esaurire”
- allineata al contenuto della griglia bassa
- più utile nei refresh successivi durante il lavoro reale
### Impatto tecnico
Il cambiamento richiesto è piccolo lato Python:
- aggiornare la query summary in [gestione_pickinglist.py](C:/devel/python/ware_house/gestione_pickinglist.py)
Non richiede, in prima battuta:
- modifiche alla stored di prenotazione
- modifiche al barcode
- modifiche a `ViewPackingListRestante`
### Decisione progettuale
Questa modifica va considerata come una scelta esplicita di evoluzione:
- **se vogliamo restare 1:1 col C#**, la lista alta resta su `XMag_ViewPackingList`
- **se vogliamo rendere il modulo più aderente al residuo operativo reale**, conviene passare a `ViewPackingListRestante`