Stabilizza picking barcode e patch cumulativa online
This commit is contained in:
@@ -52,8 +52,8 @@ class BarcodeService:
|
||||
LIGHT_GREEN = "#d9ead3"
|
||||
GREEN_YELLOW = "#e2f0cb"
|
||||
CONVENTIONAL_LOCATION_BY_CELL = {
|
||||
1000: "5E1.1",
|
||||
9999: "7G.1.1",
|
||||
1000: "5E.1.1 - Non scaffalata",
|
||||
9999: "7G.1.1 - Spedita",
|
||||
}
|
||||
|
||||
def __init__(self, repository: BarcodeRepository, operator_id: int):
|
||||
@@ -160,6 +160,24 @@ class BarcodeService:
|
||||
self._current_priority_state = int(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))
|
||||
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(
|
||||
documento=documento,
|
||||
operator_id=self.operator_id,
|
||||
)
|
||||
self._current_priority_state = -1
|
||||
self._state = BarcodeViewState(
|
||||
mode="manual_unload",
|
||||
queue_label=queue_label,
|
||||
status_text=f"PL {documento} sospesa: {skipped_count} UDC saltate. Riprenota per completare.",
|
||||
status_color=self.RED,
|
||||
destination_barcode=self.NON_SCAFFALATA_BARCODE,
|
||||
destination_readonly=False,
|
||||
)
|
||||
return BarcodeActionResult(True, self._state)
|
||||
self._current_priority_state = -1
|
||||
self._state = BarcodeViewState(
|
||||
mode="manual_unload",
|
||||
@@ -215,6 +233,11 @@ class BarcodeService:
|
||||
self._state.status_color = self.RED
|
||||
return BarcodeActionResult(False, self._state, self._state.status_text)
|
||||
|
||||
if not is_picking_unload:
|
||||
blocked = await self._block_closed_picking_free_move(pallet, destination)
|
||||
if blocked is not None:
|
||||
return blocked
|
||||
|
||||
target_barcode = destination
|
||||
target_numero_cella = int(destination)
|
||||
target_id_cella = 9999 if destination == self.SHIPPED_BARCODE else (1000 if destination == self.NON_SCAFFALATA_BARCODE else None)
|
||||
@@ -351,7 +374,7 @@ class BarcodeService:
|
||||
destination_barcode=destination,
|
||||
destination_display=target_display,
|
||||
last_priority_state=self._current_priority_state,
|
||||
auto_advance_delay_ms=5000 if (is_direct_unload or is_direct_load) else 3000 if is_picking_unload else 0,
|
||||
auto_advance_delay_ms=3000 if is_picking_unload else 0,
|
||||
)
|
||||
except Exception as exc:
|
||||
log_exception("Barcode WMS", exc, context=f"post move state pallet={pallet} destination={destination}")
|
||||
@@ -377,6 +400,10 @@ class BarcodeService:
|
||||
if not source.isdigit():
|
||||
return BarcodeActionResult(False, self._state, "La cella da scaricare deve essere numerica.")
|
||||
|
||||
blocked = await self._block_closed_picking_free_move(pallet, source)
|
||||
if blocked is not None:
|
||||
return blocked
|
||||
|
||||
current_location = await self.repository.fetch_current_location_by_pallet(pallet)
|
||||
if not current_location:
|
||||
self._state.scanned_pallet = pallet
|
||||
@@ -451,6 +478,30 @@ class BarcodeService:
|
||||
|
||||
return await self.submit(scanned_pallet=pallet, destination_barcode=self.NON_SCAFFALATA_BARCODE)
|
||||
|
||||
async def _block_closed_picking_free_move(
|
||||
self,
|
||||
pallet: str,
|
||||
destination_barcode: str,
|
||||
) -> BarcodeActionResult | None:
|
||||
closed_row = await self.repository.fetch_closed_picking_by_pallet(pallet)
|
||||
if not closed_row:
|
||||
return None
|
||||
log_runtime_event(
|
||||
"Barcode WMS",
|
||||
(
|
||||
"MOVE BLOCKED CLOSED_PICKING "
|
||||
f"pallet={pallet} "
|
||||
f"destination={destination_barcode} "
|
||||
f"id_cella={closed_row.get('IDCella')} "
|
||||
f"id_stato={closed_row.get('IDStato')}"
|
||||
),
|
||||
)
|
||||
self._state.scanned_pallet = pallet
|
||||
self._state.destination_barcode = destination_barcode
|
||||
self._state.status_text = "Errore: UDC gia' spedita, problema nella locazione o nella UDC."
|
||||
self._state.status_color = self.RED
|
||||
return BarcodeActionResult(False, self._state, self._state.status_text)
|
||||
|
||||
async def reconcile_after_submit_exception(
|
||||
self,
|
||||
*,
|
||||
@@ -505,7 +556,7 @@ class BarcodeService:
|
||||
|
||||
last_priority_state = self._current_priority_state
|
||||
is_recovered_picking = bool(destination == self.SHIPPED_BARCODE and last_priority_state in (0, 1))
|
||||
auto_advance_delay_ms = 3000 if is_recovered_picking else 5000
|
||||
auto_advance_delay_ms = 3000 if is_recovered_picking else 0
|
||||
state = await self._build_post_move_state(
|
||||
barcode_pallet=pallet,
|
||||
destination_barcode=destination,
|
||||
@@ -542,7 +593,15 @@ class BarcodeService:
|
||||
) -> BarcodeViewState:
|
||||
"""Mirror the legacy confirmation flow after one stored-procedure move."""
|
||||
|
||||
picking_row = await self.repository.fetch_picking_by_pallet(barcode_pallet)
|
||||
is_priority_shipping_confirmation = (
|
||||
destination_barcode == self.SHIPPED_BARCODE
|
||||
and last_priority_state in (0, 1)
|
||||
)
|
||||
picking_row = (
|
||||
await self.repository.fetch_picking_by_pallet(barcode_pallet)
|
||||
if is_priority_shipping_confirmation
|
||||
else None
|
||||
)
|
||||
if picking_row:
|
||||
customer = f"{picking_row.get('CodNazione') or ''} - {picking_row.get('NAZIONE') or ''}".strip(" -")
|
||||
source_location = self._display_location(
|
||||
@@ -569,14 +628,20 @@ class BarcodeService:
|
||||
prodotto = str(trace_row.get("Prodotto") or "")
|
||||
descrizione = str(trace_row.get("Descrizione") or "")
|
||||
queue_label = "Alta priorita' (F1)" if last_priority_state == 1 else ("Bassa priorita' (F2)" if last_priority_state == 0 else "Conferma movimento")
|
||||
destination_label = self._display_destination_location(
|
||||
destination_barcode=destination_barcode,
|
||||
destination_display=destination_display,
|
||||
)
|
||||
return BarcodeViewState(
|
||||
mode="confirm",
|
||||
queue_label=queue_label,
|
||||
status_text=(
|
||||
"Ok Scarico" if destination_barcode in (self.NON_SCAFFALATA_BARCODE, self.SHIPPED_BARCODE) else f"Ok Carico - {destination_display}"
|
||||
f"Ok Scarico - {destination_label}"
|
||||
if destination_barcode in (self.NON_SCAFFALATA_BARCODE, self.SHIPPED_BARCODE)
|
||||
else f"Ok Carico - {destination_label}"
|
||||
),
|
||||
status_color=self.GREEN_YELLOW,
|
||||
source_location=str(destination_display or destination_barcode or ""),
|
||||
source_location=destination_label,
|
||||
document=(
|
||||
self.CONVENTIONAL_LOCATION_BY_CELL[9999 if destination_barcode == self.SHIPPED_BARCODE else 1000]
|
||||
if destination_barcode in (self.NON_SCAFFALATA_BARCODE, self.SHIPPED_BARCODE) and last_priority_state in (0, 1)
|
||||
@@ -607,6 +672,15 @@ class BarcodeService:
|
||||
scanned_pallet=barcode_pallet,
|
||||
)
|
||||
|
||||
def _display_destination_location(self, *, destination_barcode: str, destination_display: str) -> str:
|
||||
"""Return the confirmation label for a movement destination."""
|
||||
|
||||
if destination_barcode == self.NON_SCAFFALATA_BARCODE:
|
||||
return self.CONVENTIONAL_LOCATION_BY_CELL[1000]
|
||||
if destination_barcode == self.SHIPPED_BARCODE:
|
||||
return self.CONVENTIONAL_LOCATION_BY_CELL[9999]
|
||||
return str(destination_display or destination_barcode or "")
|
||||
|
||||
def _display_location(self, *, cella: object, ubicazione: object) -> str:
|
||||
"""Return the operator-facing location, honoring legacy conventional cells."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user