From 6d02389b80384a2c515820b4368fa9a4b382aa6f Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sat, 18 Apr 2026 23:06:27 -0400 Subject: [PATCH] fix(bridge_mrp): revert malformed hr_employee.py from conflict-marker commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit a2efc9f committed a hr_employee.py with unresolved <<<<<<< HEAD / >>>>>>> Stashed changes markers — Python wouldn't have imported the file. Restoring to f340c87's version. The intended fix (Odoo 19 'in' operator handling) lives on main as 0f41eb1. --- .../models/hr_employee.py | 133 ------------------ 1 file changed, 133 deletions(-) diff --git a/fusion_plating/fusion_plating_bridge_mrp/models/hr_employee.py b/fusion_plating/fusion_plating_bridge_mrp/models/hr_employee.py index e5b94ff6..bf5d4acc 100644 --- a/fusion_plating/fusion_plating_bridge_mrp/models/hr_employee.py +++ b/fusion_plating/fusion_plating_bridge_mrp/models/hr_employee.py @@ -22,136 +22,3 @@ class HrEmployee(models.Model): help='Which shop roles this employee performs. Used by the ' 'Manager Desk and auto-assignment on WO generation.', ) -<<<<<<< Updated upstream -======= - # Per-role lead-hand list. Sarah might be a lead hand for masking + - # racking but not for plating; Mike might cover everything during - # a graveyard shift. Stored on a separate relation table so the - # primary "Shop Roles" list stays distinct from the cover-anything - # authority. - x_fc_lead_hand_role_ids = fields.Many2many( - 'fp.work.role', 'fp_employee_lead_hand_role_rel', - 'employee_id', 'role_id', string='Lead Hand For', - help='Roles where this employee is authorised to lead or cover ' - 'for an absent operator. Lead hands are surfaced first in ' - 'the Manager Desk worker picker for these roles.', - ) - - x_fc_proficiency_ids = fields.One2many( - 'fp.operator.proficiency', 'employee_id', - string='Task Proficiency', - help='Per-role completion tally. Workers earn one count per WO ' - 'they finish on a given role. Once the count crosses the ' - "role's mastery threshold the role is added to their " - 'Shop Roles list automatically.', - ) - - # ------------------------------------------------------------------ - # Attendance helpers — used by the Manager Desk to show who is - # currently clocked in. Works with vanilla hr_attendance or the - # full fusion_clock module — both store an open record (no - # check_out) for as long as the employee is on shift. - # ------------------------------------------------------------------ - x_fc_is_clocked_in = fields.Boolean( - string='Clocked In', - compute='_compute_x_fc_is_clocked_in', - search='_search_x_fc_is_clocked_in', - help='True if this employee currently has an open hr.attendance ' - 'record (clocked in but not clocked out).', - ) - - def _compute_x_fc_is_clocked_in(self): - """Compute attendance status from hr.attendance. - - Batched so the manager dashboard doesn't issue one query per - employee — important when the shop has dozens of operators. - """ - if not self: - return - Att = self.env.get('hr.attendance') - if Att is None: - for emp in self: - emp.x_fc_is_clocked_in = False - return - # One read for the whole recordset. - open_emp_ids = set(Att.sudo().search([ - ('employee_id', 'in', self.ids), - ('check_out', '=', False), - ]).mapped('employee_id').ids) - for emp in self: - emp.x_fc_is_clocked_in = emp.id in open_emp_ids - - def _search_x_fc_is_clocked_in(self, *args): - """Lets `[('x_fc_is_clocked_in', '=', True)]` work as a domain. - - Odoo 19 normalises the equality term ``('=', True)`` into - ``('in', OrderedSet([True]))`` before calling this method, so - we have to handle ``in`` / ``not in`` as well as the bare - ``=`` / ``!=``. The signature is also variadic so a future - Odoo refactor that prepends a ``records`` argument doesn't - break us. - - Strategy: - 1. Reduce the caller's intent to a *match_set* of booleans - — which values of ``x_fc_is_clocked_in`` should match. - 2. Negative operators flip that set. - 3. Translate the set into an ``id IN`` (or ``NOT IN``) term - on the cached open-attendance employee ids. - """ - # Variable signature — Odoo 19 may pass (records, op, val). - if len(args) == 3: - _records, operator, value = args - elif len(args) == 2: - operator, value = args - else: - return [('id', '=', False)] - - Att = self.env.get('hr.attendance') - if Att is None: - return [('id', '=', False)] - - # Build the set of bool values the caller wants. - if operator in ('=', '!='): - match_set = {bool(value)} - elif operator in ('in', 'not in'): - # value is a (possibly OrderedSet) iterable of bools. - match_set = set(map(bool, value)) - else: - return [('id', '=', False)] - - # Negated operators flip the match set so we can reason in - # purely positive terms below. - if operator in ('!=', 'not in'): - match_set = {True, False} - match_set - - if not match_set: - return [('id', '=', False)] - if match_set == {True, False}: - # No filter at all — every employee matches. - return [] - - open_emp_ids = Att.sudo().search( - [('check_out', '=', False)] - ).employee_id.ids - # Sentinel guards against an empty list — Odoo treats - # `('id', 'in', [])` as no constraint in some versions and - # ends up matching every row. - ids_term = open_emp_ids or [0] - return [('id', 'in' if True in match_set else 'not in', ids_term)] - - @api.model - def _fp_clocked_in_user_ids(self): - """Return the set of res.users.ids whose linked employee is on shift. - - Used by the Manager Desk controller to short-circuit the worker - dropdown to "present today" without an N+1 attendance query - per worker. - """ - Att = self.env.get('hr.attendance') - if Att is None: - return set() - emps = Att.sudo().search([ - ('check_out', '=', False), - ]).mapped('employee_id') - return set(emps.user_id.ids) ->>>>>>> Stashed changes