Freeze stato gestione picking e storico
This commit is contained in:
61
INSTALL_PRODUZIONE_20260610.md
Normal file
61
INSTALL_PRODUZIONE_20260610.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Installazione produzione - Warehouse/FlyWMS bridge
|
||||
|
||||
## Ordine consigliato
|
||||
|
||||
1. Fare backup del database `Mediseawall`.
|
||||
2. Copiare il contenuto dello zip in una cartella locale, ad esempio `C:\flywms`.
|
||||
3. Installare le dipendenze Python:
|
||||
|
||||
```bat
|
||||
python -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
4. In SSMS, sul database `Mediseawall`, lanciare:
|
||||
|
||||
```text
|
||||
apply_python_parallel_pickinglist_patch.sql
|
||||
apply_online_history_forms_patch.sql
|
||||
```
|
||||
|
||||
## Cosa fanno gli script
|
||||
|
||||
- `apply_python_parallel_pickinglist_patch.sql` crea il ramo SQL Python per gestione picking list, senza modificare le stored procedure C# legacy.
|
||||
- `apply_online_history_forms_patch.sql` crea le viste Python-only per "Storico Picking List".
|
||||
- "Storico movimenti UDC" non richiede script dedicati: legge in sola lettura `MagazziniPallet`, `Celle` e `XMag_GiacenzaPalletPlistChiuse`.
|
||||
|
||||
## Rollback SQL
|
||||
|
||||
Se serve tornare indietro sugli oggetti Python, usare:
|
||||
|
||||
```text
|
||||
rollback_online_history_forms_patch.sql
|
||||
rollback_python_parallel_pickinglist_patch.sql
|
||||
```
|
||||
|
||||
La tabella `dbo.PyPickingListReservation`, se creata, puo' rimanere anche in caso di rollback perche' il C# legacy non la usa.
|
||||
|
||||
## Avvio
|
||||
|
||||
Backoffice con console:
|
||||
|
||||
```bat
|
||||
python main.py
|
||||
```
|
||||
|
||||
Backoffice senza console:
|
||||
|
||||
```bat
|
||||
pythonw warehouse.pyw
|
||||
```
|
||||
|
||||
Barcode senza console:
|
||||
|
||||
```bat
|
||||
pythonw barcode.pyw
|
||||
```
|
||||
|
||||
Se si usa un collegamento Windows, impostare anche la cartella "Da" alla cartella dell'applicazione, ad esempio `C:\flywms`.
|
||||
|
||||
## File esclusi dal pacchetto
|
||||
|
||||
Il pacchetto non include `db_connection.json`, log, cache Python e vecchi zip locali. Alla prima apertura il programma chiedera' la configurazione DB se `db_connection.json` non esiste.
|
||||
@@ -203,7 +203,7 @@ if _MODULE_LOG_ENABLED:
|
||||
# -------------------- SQL --------------------
|
||||
SQL_PL = """
|
||||
SELECT
|
||||
COUNT(DISTINCT Pallet) AS Pallet,
|
||||
COUNT(DISTINCT NULLIF(LTRIM(RTRIM(CAST(Pallet AS varchar(32)))), '')) AS Pallet,
|
||||
COUNT(DISTINCT Lotto) AS Lotto,
|
||||
COUNT(DISTINCT Articolo) AS Articolo,
|
||||
COUNT(DISTINCT Descrizione) AS Descrizione,
|
||||
@@ -907,13 +907,25 @@ class GestionePickingListFrame(ctk.CTkFrame):
|
||||
self.after_idle(_paint)
|
||||
break
|
||||
|
||||
def _reselect_documento_after_reload(self, documento: str):
|
||||
"""(Opzionale) Dopo un reload DB, riseleziona la PL con lo stesso Documento."""
|
||||
def _reselect_documento_after_reload(self, documento: str) -> bool:
|
||||
"""After a reload, reselect the same document and reload its details."""
|
||||
for m in self.rows_models:
|
||||
if _s(m.pl.get("Documento")) == _s(documento):
|
||||
self._detail_cache.pop(documento, None)
|
||||
m.set_checked(True)
|
||||
self.on_row_checked(m, True)
|
||||
break
|
||||
return True
|
||||
return False
|
||||
|
||||
def _selected_documento_for_reload(self) -> str | None:
|
||||
"""Return the document that should survive a toolbar reload."""
|
||||
|
||||
selected = self._get_selected_model()
|
||||
if selected is not None:
|
||||
documento = _s(selected.pl.get("Documento"))
|
||||
return documento or None
|
||||
documento = _s(self.detail_doc)
|
||||
return documento or None
|
||||
|
||||
# ----- eventi -----
|
||||
@_log_call()
|
||||
@@ -967,6 +979,8 @@ class GestionePickingListFrame(ctk.CTkFrame):
|
||||
@_log_call()
|
||||
def reload_from_db(self, first: bool = False, reselect_documento: str | None = None):
|
||||
"""Load or reload the picking list summary table from the database."""
|
||||
if reselect_documento is None and not first:
|
||||
reselect_documento = self._selected_documento_for_reload()
|
||||
self.spinner.start(" Carico…") # spinner ON
|
||||
async def _job():
|
||||
_log_sql("SQL_PL", SQL_PL, {})
|
||||
@@ -976,7 +990,17 @@ class GestionePickingListFrame(ctk.CTkFrame):
|
||||
_log_dataset("SQL_PL", rows)
|
||||
self._refresh_mid_rows(rows)
|
||||
if reselect_documento:
|
||||
self.after_idle(lambda doc=reselect_documento: self._reselect_documento_after_reload(doc))
|
||||
def _reselect_or_clear(doc=reselect_documento):
|
||||
found = self._reselect_documento_after_reload(doc)
|
||||
if not found:
|
||||
self.detail_doc = None
|
||||
self._draw_details_hint()
|
||||
self.spinner.stop()
|
||||
self.busy.hide()
|
||||
self.after_idle(_reselect_or_clear)
|
||||
else:
|
||||
self.detail_doc = None
|
||||
self._draw_details_hint()
|
||||
self.spinner.stop() # spinner OFF
|
||||
# se era il primo load, ripristina il cursore standard
|
||||
if self._first_loading:
|
||||
|
||||
@@ -21,46 +21,66 @@ __version__ = module_version(__name__)
|
||||
|
||||
SQL_STORICO_PL = """
|
||||
WITH base AS (
|
||||
SELECT *
|
||||
SELECT
|
||||
*,
|
||||
NULLIF(LTRIM(RTRIM(CAST(Pallet AS varchar(32)))), '') AS PalletKey
|
||||
FROM dbo.py_XMag_ViewPackingListStorico
|
||||
),
|
||||
agg AS (
|
||||
pallets AS (
|
||||
SELECT
|
||||
Documento,
|
||||
PalletKey,
|
||||
MAX(CASE WHEN Cella <> 9999 OR Cella IS NULL THEN 1 ELSE 0 END) AS HasResiduo,
|
||||
MAX(CASE WHEN Cella = 9999 THEN 1 ELSE 0 END) AS HasSpedito
|
||||
FROM base
|
||||
WHERE PalletKey IS NOT NULL
|
||||
GROUP BY Documento, PalletKey
|
||||
),
|
||||
meta AS (
|
||||
SELECT
|
||||
Documento,
|
||||
MAX(DataDocumento) AS DataDocumento,
|
||||
MAX(StatoDocumento) AS StatoDocumento,
|
||||
MAX(NAZIONE) AS NAZIONE,
|
||||
MAX(CodNazione) AS CodNazione,
|
||||
COUNT(DISTINCT Pallet) AS TotUDC,
|
||||
SUM(CASE WHEN Cella = 9999 THEN 1 ELSE 0 END) AS RigheSpedite,
|
||||
SUM(CASE WHEN Cella <> 9999 OR Cella IS NULL THEN 1 ELSE 0 END) AS RigheResidue,
|
||||
COUNT(*) AS RigheTotali,
|
||||
MIN(Ordinamento) AS PrimoOrdine,
|
||||
MAX(IDStato) AS IDStato
|
||||
FROM base
|
||||
GROUP BY Documento
|
||||
)
|
||||
),
|
||||
agg AS (
|
||||
SELECT
|
||||
Documento,
|
||||
DataDocumento,
|
||||
StatoDocumento,
|
||||
NAZIONE,
|
||||
CodNazione,
|
||||
TotUDC,
|
||||
RigheResidue,
|
||||
RigheSpedite,
|
||||
RigheTotali,
|
||||
COUNT(*) AS TotUDC,
|
||||
SUM(CASE WHEN p.HasResiduo = 0 AND p.HasSpedito = 1 THEN 1 ELSE 0 END) AS RigheSpedite,
|
||||
SUM(CASE WHEN p.HasResiduo = 1 THEN 1 ELSE 0 END) AS RigheResidue
|
||||
FROM pallets p
|
||||
GROUP BY Documento
|
||||
)
|
||||
SELECT
|
||||
m.Documento,
|
||||
m.DataDocumento,
|
||||
m.StatoDocumento,
|
||||
m.NAZIONE,
|
||||
m.CodNazione,
|
||||
COALESCE(a.TotUDC, 0) AS TotUDC,
|
||||
COALESCE(a.RigheResidue, 0) AS RigheResidue,
|
||||
COALESCE(a.RigheSpedite, 0) AS RigheSpedite,
|
||||
m.RigheTotali,
|
||||
CASE
|
||||
WHEN StatoDocumento = 'D' THEN 'Chiusa'
|
||||
WHEN RigheResidue = 0 THEN 'Esaurita'
|
||||
WHEN RigheSpedite > 0 THEN 'In corso'
|
||||
WHEN m.StatoDocumento = 'D' AND COALESCE(a.RigheResidue, 0) > 0 THEN 'Chiusa ERP con residui'
|
||||
WHEN m.StatoDocumento = 'D' THEN 'Chiusa'
|
||||
WHEN COALESCE(a.RigheResidue, 0) = 0 THEN 'Esaurita'
|
||||
WHEN COALESCE(a.RigheSpedite, 0) > 0 THEN 'In corso'
|
||||
ELSE 'Da lavorare'
|
||||
END AS StatoOperativo,
|
||||
IDStato,
|
||||
PrimoOrdine
|
||||
FROM agg
|
||||
WHERE (:documento IS NULL OR CAST(Documento AS varchar(32)) LIKE CONCAT('%', :documento, '%'))
|
||||
ORDER BY Documento DESC;
|
||||
m.IDStato,
|
||||
m.PrimoOrdine
|
||||
FROM meta m
|
||||
LEFT JOIN agg a ON a.Documento = m.Documento
|
||||
WHERE (:documento IS NULL OR CAST(m.Documento AS varchar(32)) LIKE CONCAT('%', :documento, '%'))
|
||||
ORDER BY m.Documento DESC;
|
||||
"""
|
||||
|
||||
SQL_STORICO_PL_DETAILS = """
|
||||
|
||||
@@ -20,14 +20,14 @@ MODULE_VERSIONS: dict[str, str] = {
|
||||
"db_config": "1.0.0",
|
||||
"gestione_aree": "1.0.0",
|
||||
"gestione_layout": "1.0.0",
|
||||
"gestione_pickinglist": "1.0.0",
|
||||
"gestione_pickinglist": "1.0.2",
|
||||
"gestione_scarico": "1.0.0",
|
||||
"locale_text": "1.0.0",
|
||||
"login_window": "1.0.0",
|
||||
"prenota_sprenota_sql": "1.0.0",
|
||||
"reset_corsie": "1.0.0",
|
||||
"search_pallets": "1.0.0",
|
||||
"storico_pickinglist": "1.0.0",
|
||||
"storico_pickinglist": "1.0.2",
|
||||
"storico_udc": "1.0.0",
|
||||
"tooltips": "1.0.0",
|
||||
"ui_theme": "1.0.0",
|
||||
|
||||
Reference in New Issue
Block a user