Files
ware_house/docs/review/module_gestione_pickinglist.md

7.1 KiB

Modulo gestione_pickinglist.py

Scopo

Il modulo implementa la finestra operativa "Gestione Picking List". La finestra serve al backoffice/magazzino per:

  • visualizzare le picking list ancora lavorabili;
  • selezionare una sola lista alla volta;
  • visualizzare le UDC residue della lista selezionata;
  • prenotare una lista per darle priorita' alta sul barcode;
  • s-prenotare la lista correntemente prenotata;
  • mantenere UI reattiva tramite query asincrone, overlay e spinner.

La finestra lavora sulla vista residuale dbo.py_ViewPackingListRestante, quindi mostra cio' che resta da scaricare, non necessariamente il documento ERP completo. Il documento completo e' invece esposto dalla form "Storico Picking List".

Processo logico

Apertura finestra

  1. open_pickinglist_window crea o riporta in primo piano una singola finestra.
  2. La finestra viene inizialmente nascosta con withdraw e alpha 0.0.
  3. Viene creato GestionePickingListFrame.
  4. Dopo la stabilizzazione layout, _first_show avvia il primo caricamento.
  5. La finestra viene mostrata solo quando il layout e' pronto, riducendo flicker.

Caricamento lista alta

  1. reload_from_db esegue SQL_PL.
  2. SQL_PL legge da dbo.py_ViewPackingListRestante.
  3. Il risultato viene normalizzato con _rows_to_dicts.
  4. _refresh_mid_rows ricrea la tabella alta.
  5. Ogni riga e' rappresentata da un PLRow, che incapsula dizionario dati e checkbox.

Selezione lista

  1. Il click sul checkbox chiama on_row_checked.
  2. La selezione e' esclusiva: eventuali altre righe selezionate vengono deselezionate.
  3. Il documento selezionato viene salvato in detail_doc.
  4. Viene eseguita SQL_PL_DETAILS.
  5. Il dettaglio viene messo in cache in _detail_cache.
  6. _refresh_details_incremental ordina e renderizza il dettaglio con tksheet.

Ricarica

reload_from_db preserva il documento selezionato quando possibile. Questo e' importante per il caso operativo in cui il barcode sta scaricando UDC mentre l'operatore aggiorna la finestra.

Flusso:

  1. _selected_documento_for_reload determina il documento da mantenere.
  2. La griglia alta viene ricaricata.
  3. _reselect_documento_after_reload riseleziona la stessa lista se ancora presente.
  4. Il dettaglio viene ricaricato dalla vista residuale.

Prenotazione

  1. on_prenota verifica il permesso pickinglist.prenota.
  2. Richiede una riga selezionata.
  3. Se IDStato == 1, l'operazione e' no-op.
  4. Verifica sessione operatore valida.
  5. Chiama sp_xExePackingListPallet_async(..., Azione="P").
  6. Se rc == 0, logga audit e ricarica la griglia mantenendo il documento.

S-prenotazione

  1. on_sprenota verifica il permesso pickinglist.sprenota.
  2. Richiede una riga selezionata.
  3. Se IDStato == 0, l'operazione e' no-op.
  4. Chiama sp_xExePackingListPallet_async(..., Azione="S").
  5. Se rc == 0, logga audit e ricarica.

Semantica operativa

La UI non implementa toggle implicito. I pulsanti hanno semantica esplicita:

Pulsante Effetto
Prenota porta la lista selezionata a priorita' alta se non gia' prenotata
S-prenota libera la lista selezionata se e' la lista attiva

Premere piu' volte Prenota sulla stessa lista gia' prenotata non la libera. Premere piu' volte S-prenota su lista non prenotata non la prenota.

Strutture dati principali

Nome Tipo Ruolo
rows_models list[PLRow] modelli riga della griglia alta
_detail_cache dict[Any, list] cache righe dettaglio per documento
detail_doc Any documento correntemente selezionato
_detail_sort_key `str None`
_detail_sort_reverse bool verso ordinamento dettaglio
pl_table ScrollTable tabella custom griglia alta
detail_sheet tksheet.Sheet griglia dettaglio ad alto volume
spinner ToolbarSpinner feedback leggero toolbar
busy InlineBusyOverlay overlay query/operazioni lente

Funzioni e classi principali

Oggetto Firma Ruolo
_rows_to_dicts _rows_to_dicts(res: Dict[str, Any]) -> List[Dict[str, Any]] normalizza payload DB
_s _s(v) -> str converte None in stringa vuota
_first _first(d: Dict[str, Any], keys: List[str], default: str = "") estrae il primo campo valorizzato
ColSpec dataclass(title, key, width, anchor) descrive una colonna tabellare
ToolbarSpinner classe animazione leggera toolbar
ScrollTable classe tabella custom per griglia alta
PLRow classe modello riga PL + checkbox
GestionePickingListFrame classe frame principale
_build_detail_sheet _build_detail_sheet(self) crea tksheet dettaglio
_detail_rows_to_sheet_data _detail_rows_to_sheet_data(self, rows) converte righe DB in righe tksheet
_load_detail_sheet_data _load_detail_sheet_data(self, data) applica headers, dati e zebra
_refresh_mid_rows _refresh_mid_rows(self, rows) ricrea griglia alta
_get_selected_model _get_selected_model(self) -> Optional[PLRow] ritorna riga selezionata
on_row_checked on_row_checked(self, model: PLRow, is_checked: bool) carica dettaglio della lista
reload_from_db reload_from_db(self, first=False, reselect_documento=None) aggiorna griglia alta
_refresh_details _refresh_details(self) ridisegna dettaglio da cache
_refresh_details_incremental _refresh_details_incremental(self, batch_size=25) render dettaglio con overlay
on_prenota on_prenota(self) prenota lista selezionata
on_sprenota on_sprenota(self) s-prenota lista selezionata
create_frame create_frame(parent, *, db_client=None, conn_str=None, session=None) factory frame
open_pickinglist_window open_pickinglist_window(parent, db_client, session=None) -> tk.Misc entry point finestra

Query runtime

SQL_PL

Aggrega dbo.py_ViewPackingListRestante per documento. Conta UDC con:

COUNT(DISTINCT NULLIF(LTRIM(RTRIM(CAST(Pallet AS varchar(32)))), '')) AS Pallet

Questo evita il doppio conteggio di UDC multi-lotto.

SQL_PL_DETAILS

Ritorna tutte le righe residuali della lista selezionata, ordinate per Ordinamento.

Effetti sul database

Il modulo UI non aggiorna direttamente tabelle. Tutte le modifiche passano da sp_xExePackingListPallet_async, che esegue dbo.py_sp_xExePackingListPallet.

Effetti indiretti:

  • aggiorna dbo.PyPickingListReservation;
  • aggiorna dbo.Celle.IDStato;
  • scrive audit applicativo con log_user_action;
  • la stored puo' scrivere log legacy tramite sp_LogPackingList.

Rischi e note review

  • La vista residuale cambia mentre il barcode scarica UDC: per questo Ricarica conserva la selezione e ricarica il dettaglio.
  • La tabella alta e il dettaglio possono non avere lo stesso numero di righe dello storico, perche' qui si vedono solo residui.
  • La convivenza C#/Python dipende dalla presenza degli oggetti py_*.
  • La selezione e' esclusiva lato UI, ma il secondo livello F2 barcode dipende dalla logica barcode/stato DB, non da una seconda prenotazione backoffice.