Freeze 2.0 warehouse monolista e documento fisso F1/F2

This commit is contained in:
2026-10-02 10:09:44 +02:00
parent 3a2893dc3d
commit a60610c03e
10 changed files with 1019 additions and 20 deletions

View File

@@ -60,6 +60,8 @@ class BarcodeService:
self.repository = repository
self.operator_id = int(operator_id)
self._current_priority_state = -1
# Independent document identities survive confirmations, F1/F2 and pause.
self._priority_documents: dict[int, str] = {}
self._state = BarcodeViewState()
@property
@@ -72,6 +74,7 @@ class BarcodeService:
"""Return the client to its neutral state."""
self._current_priority_state = -1
self._priority_documents.clear()
self._state = BarcodeViewState()
return self._state
@@ -121,6 +124,7 @@ class BarcodeService:
if state.mode not in ("priority_high", "priority_low"):
return self._state
self._current_priority_state = 1 if state.mode == "priority_high" else 0
self._priority_documents[self._current_priority_state] = state.document
self._state = replace(state, scanned_pallet="", auto_advance_delay_ms=0)
return self._state
@@ -163,20 +167,25 @@ class BarcodeService:
return BarcodeActionResult(True, self._state, self._state.status_text)
async def start_priority_queue(self, id_stato: int) -> BarcodeActionResult:
"""Load the next item of the selected legacy priority queue."""
"""Keep each F1/F2 cycle bound to its document until the cycle stops."""
row = await self.repository.fetch_next_picking(id_stato)
self._current_priority_state = int(id_stato)
id_stato = int(id_stato)
active_document = self._priority_documents.get(id_stato)
row = await self.repository.fetch_next_picking(id_stato, documento=active_document)
self._current_priority_state = id_stato
queue_label = "Alta priorita' (F1)" if int(id_stato) == 1 else "Bassa priorita' (F2)"
if not row:
skipped_doc = await self.repository.fetch_active_skipped_document(int(id_stato))
skipped_doc = await self.repository.fetch_active_skipped_document(id_stato, documento=active_document)
if skipped_doc:
documento = str(skipped_doc.get("Documento") or "").strip()
skipped_count = int(skipped_doc.get("SkippedCount") or 0)
await self.repository.release_picking_document(
rc = await self.repository.release_picking_document(
documento=documento,
operator_id=self.operator_id,
)
if rc != 0:
raise RuntimeError(f"Impossibile sospendere PL {documento}: RC={rc}")
self._priority_documents.pop(id_stato, None)
self._current_priority_state = -1
self._state = BarcodeViewState(
mode="manual_unload",
@@ -187,17 +196,36 @@ class BarcodeService:
destination_readonly=False,
)
return BarcodeActionResult(True, self._state)
status_text = "Pronto."
remaining = 0
if active_document:
remaining = await self.repository.count_picking_document_remaining(active_document)
status_text = (
f"PL {active_document}: {remaining} UDC residue, coda non disponibile. Verifica la prenotazione."
if remaining else f"PL {active_document} terminata. Premi F1 o F2 per iniziare."
)
log_runtime_event("Barcode WMS", f"PICKING CYCLE STOP documento={active_document} priority={id_stato} remaining={remaining}")
# A changed reservation or visibility filter must not silently
# replace an unfinished document on the next press of F1/F2.
if not remaining:
self._priority_documents.pop(id_stato, None)
self._current_priority_state = -1
self._state = BarcodeViewState(
mode="manual_unload",
queue_label=queue_label,
status_text="Pronto.",
status_text=status_text,
status_color=self.RED,
destination_barcode=self.NON_SCAFFALATA_BARCODE,
destination_readonly=False,
)
return BarcodeActionResult(True, self._state)
document = str(row.get("Documento") or "").strip()
if not document or (active_document is not None and document != active_document):
raise RuntimeError(f"Cambio inatteso documento picking: atteso={active_document}, ricevuto={document}")
self._priority_documents[id_stato] = document
if active_document is None:
log_runtime_event("Barcode WMS", f"PICKING CYCLE START documento={document} priority={id_stato}")
customer = f"{row.get('CodNazione') or ''} - {row.get('NAZIONE') or ''}".strip(" -")
source_location = self._display_location(
cella=row.get("Cella"),
@@ -289,7 +317,10 @@ class BarcodeService:
picking_before_move = (
None
if current_location
else await self.repository.fetch_picking_by_pallet(pallet)
else await self.repository.fetch_picking_by_pallet(
pallet,
documento=self._priority_documents.get(self._current_priority_state) if is_picking_unload else None,
)
)
if not current_location and not picking_before_move:
if is_direct_load:
@@ -651,7 +682,9 @@ class BarcodeService:
and last_priority_state in (0, 1)
)
picking_row = (
await self.repository.fetch_picking_by_pallet(barcode_pallet)
await self.repository.fetch_picking_by_pallet(
barcode_pallet, documento=self._priority_documents.get(last_priority_state),
)
if is_priority_shipping_confirmation
else None
)