diff --git a/CHANGELOG.md b/CHANGELOG.md index c669724..5d074b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ version tags are cut in this repo — POC stage, `main` is the release line). ## [Unreleased] ### Added +- **Manual mode plate entry**: legacy `manual` batch start is now locked until a + plate number is entered — plate input in operator + monitoring start modals + (confirm button disabled while empty), `POST /api/batch/start` rejects + manual start with 400 `missing_plate` (strip + uppercase, no format regex); + plate flows through `current_batch.json` → `batches.plate` on stop, so + history/XLSX show it for manual batches. Operator plate tile now also shows + for manual batches (was `do_manual` only). - **DO-gated manual batch mode** (`auto` default · `do_manual` · legacy `manual`): smartphone photo capture → OCR draft → plate-grouped start gates → net expected/counted on live panel → stop soft-warn + force → discard only when diff --git a/counter_dashboard.py b/counter_dashboard.py index dbad551..4022dda 100644 --- a/counter_dashboard.py +++ b/counter_dashboard.py @@ -472,6 +472,17 @@ def api_batch_start(): expected_sack = sum(int(d.get("expected_sack") or 0) for d in dos) expected_box = sum(int(d.get("expected_box") or 0) for d in dos) + elif mode == "manual": + # Legacy manual mode: batch start locked until plate entered. + req_data = request.get_json(silent=True) or request.form or {} + plate = str(req_data.get("plate", "")).strip().upper() + if not plate: + return jsonify({ + "success": False, + "reason": "missing_plate", + "error": "Plat nomor wajib diisi sebelum batch dimulai.", + }), 400 + counting_date = get_counting_date() batch_num = get_next_batch_number(counting_date) now_iso = datetime.now().isoformat() diff --git a/docs/configuration.md b/docs/configuration.md index 0078647..52763b4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -38,7 +38,7 @@ deprecated (warned). |---|---|---| | `auto` (default) | AI truck FSM | n/a | | `do_manual` | Operator start/stop + staged DO photos | yes | -| `manual` | Operator start/stop (legacy) | no | +| `manual` | Operator start/stop (legacy) — plate required at start | no | `POST /api/batch/mode` with `mode` and/or `model_mode` is **office port only** (403 on operator `:5000`); mode switch while a batch is active → **409**. diff --git a/templates/monitoring.html b/templates/monitoring.html index cb52f8f..879e332 100644 --- a/templates/monitoring.html +++ b/templates/monitoring.html @@ -405,10 +405,16 @@
@@ -479,7 +485,21 @@ } } + function onMonStartPlateInput() { + const plate = document.getElementById('monStartPlateInput').value.trim(); + const btn = document.getElementById('monBtnStartConfirm'); + btn.style.opacity = plate.length === 0 ? '0.6' : ''; + btn.style.pointerEvents = plate.length === 0 ? 'none' : ''; + } + function confirmStartBatch() { + const plateRow = document.getElementById('monStartPlateRow'); + const isManual = currentBatchMode === 'manual'; + plateRow.style.display = isManual ? 'block' : 'none'; + if (isManual) { + document.getElementById('monStartPlateInput').value = ''; + onMonStartPlateInput(); + } document.getElementById('modalStart').style.display = 'flex'; } @@ -490,7 +510,18 @@ async function executeStartBatch() { document.getElementById('modalStart').style.display = 'none'; try { - const res = await fetch('/api/batch/start', { method: 'POST' }); + let body = null; + let headers = {}; + if (currentBatchMode === 'manual') { + const plate = document.getElementById('monStartPlateInput').value.trim().toUpperCase(); + if (!plate) { + alert('Plat nomor wajib diisi sebelum batch dimulai.'); + return; + } + body = JSON.stringify({ plate: plate }); + headers = { 'Content-Type': 'application/json' }; + } + const res = await fetch('/api/batch/start', { method: 'POST', headers: headers, body: body }); const data = await res.json(); if (data.success) { await pollCurrentBatch(); diff --git a/templates/operator.html b/templates/operator.html index 6d6fb51..62fbfe7 100644 --- a/templates/operator.html +++ b/templates/operator.html @@ -118,6 +118,7 @@ .btn-disabled { opacity: 0.6; cursor: not-allowed; + pointer-events: none; } /* Simple Confirmation Modal */ @@ -425,10 +426,16 @@Pastikan truk sudah siap di posisi pemuatan karung.
+