fix(shopfloor): Phase C review findings — lock_session closes unlock event + cron test
Important 1: lock_session now closes the original unlock event's session_ended_at via the same parameterized-SQL bypass pattern used by the force-lock cron. Without this, every Hand-Off click became a duplicate force_lock event 8 hours later (cron saw the unlock still open and re-processed). Important 2: test_unlock_lock_session_endpoints setUp now unconditionally overrides the kiosk password (was gated on 'if not get_param(...)' which broke on entech where the post-migrate hook already generated a random password — tests failed against the real value). HttpCase rolls back per test so no persistence. Minor 4: _cron_force_lock_stale_sessions now routes the force_lock create through write_event helper for consistency (single audit-write path; helper captures acting_uid/ip/ua uniformly). Minor 5: Hoisted local imports inside method bodies to top-of-file in tablet_controller.py (AccessDenied, _tablet_session_audit) and fp_tablet_session_event.py (timedelta, write_event). Minor 6: New test_force_lock_cron.py with 3 tests: stale session emits force_lock + closes original; recent session unaffected; already-closed session not re-processed. Would have caught Important 1 if it had existed during Phase C review. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,9 +16,11 @@ import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import _, fields, http
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import AccessDenied, UserError
|
||||
from odoo.http import request
|
||||
|
||||
from ._tablet_session_audit import write_event, _sha256_session_sid
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -226,8 +228,6 @@ class FpTabletController(http.Controller):
|
||||
|
||||
Spec: docs/superpowers/specs/2026-05-24-tablet-pin-session-redesign-design.md
|
||||
"""
|
||||
from odoo.exceptions import AccessDenied
|
||||
from ._tablet_session_audit import write_event, _sha256_session_sid
|
||||
env = request.env
|
||||
Users = env['res.users'].sudo()
|
||||
target = Users.browse(int(user_id))
|
||||
@@ -336,7 +336,6 @@ class FpTabletController(http.Controller):
|
||||
ceiling -> ceiling_lock
|
||||
Anything else falls back to manual_lock.
|
||||
"""
|
||||
from ._tablet_session_audit import write_event, _sha256_session_sid
|
||||
env = request.env
|
||||
now = fields.Datetime.now()
|
||||
sid = request.session.sid
|
||||
@@ -376,6 +375,18 @@ class FpTabletController(http.Controller):
|
||||
session_started_at=session_started_at,
|
||||
session_ended_at=now,
|
||||
duration_seconds=duration_seconds)
|
||||
# Close the original unlock event (mirror what the cron does
|
||||
# for stale sessions) so the cron doesn't re-process it later.
|
||||
# The Python write override blocks updates without the explicit
|
||||
# admin context flag, so use parameterized SQL (consistent with
|
||||
# _cron_force_lock_stale_sessions in fp_tablet_session_event.py).
|
||||
if open_event:
|
||||
self.env.cr.execute(
|
||||
"""UPDATE fp_tablet_session_event
|
||||
SET session_ended_at = %s, duration_seconds = %s
|
||||
WHERE id = %s""",
|
||||
(now, duration_seconds or 0, open_event.id),
|
||||
)
|
||||
_logger.info(
|
||||
'Tablet locked (reason=%s) for uid %s (sid %s..) duration=%ss',
|
||||
reason, tech_id, sid[:8] if sid else '', duration_seconds,
|
||||
|
||||
Reference in New Issue
Block a user