fix(fusion_repairs): admin + office users get full read/schedule access

When admin (gsingh, uid=2) opened a repair on the dashboard:
  "Sorry, Gurpreet Singh (id=2) doesn't have 'read' access to:
   - Repair Order, RO-202605-04 (repair.order: 34)
   Blame the following rules:
   - Repair Order: Technician sees own repairs"

Root cause: per-group record rules in Odoo are OR'd within the same
model. Admin had been added directly to fusion_tasks.group_field_technician
in this database (verified via res_groups_users_rel - direct=1), so the
technician's restrictive rule ('only repairs you are assigned to') kicked
in. Until now there was no per-group rule for the Repairs Office groups
to OR against, so the restrictive rule won by default.

Fix - added two pairs of permissive rules:

  rule_repair_order_repairs_user_full        - User can read/write/create
  rule_repair_order_repairs_manager_unlink   - Manager also can delete
  rule_technician_task_repairs_office        - User can read/write/create tasks
  rule_technician_task_repairs_manager_unlink - Manager also can delete tasks

Both have domain_force=[(1,'=',1)] so they grant unrestricted access for
the Repairs groups. OR'd with the field_technician rule, admin and other
office users now see everything. Field technicians who do NOT have any
Repairs group still see only their assigned repairs (rule unchanged).

Also added the matching ir.model.access.csv entries - record rules don't
fire if the user has no model-level ACL. This is the second fix
('office users can schedule') from the same complaint - Repairs User now
has read/write/create on fusion.technician.task; Repairs Manager also
gets unlink.

Verified end-to-end on westin-v19:
  Admin can see 17 repairs (was 0 before fix)
  Admin can read RO-202605-04 -> 'Gurpreet Singh' (the exact failing record)
  Admin can create fusion.technician.task -> permission check passes
  (model's own time-overlap business validation correctly rejects an
  overlap, but that is a value error not a permission error)

Bumped to 19.0.1.0.7.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
gsinghpal
2026-05-20 23:11:37 -04:00
parent 7f8a80fecb
commit d15d9e4303
3 changed files with 60 additions and 2 deletions

View File

@@ -4,7 +4,7 @@
{
'name': 'Fusion Repairs',
'version': '19.0.1.0.6',
'version': '19.0.1.0.7',
'category': 'Inventory/Repairs',
'summary': 'Guided medical equipment repair intake, dispatch, maintenance, and self-service portal',
'description': """

View File

@@ -19,3 +19,7 @@ access_repair_visit_report_wizard_line_user,Visit Report Line User,model_fusion_
access_repair_maintenance_user,Maintenance Contract User Read,model_fusion_repair_maintenance_contract,group_fusion_repairs_user,1,0,0,0
access_repair_maintenance_dispatcher,Maintenance Contract Dispatcher,model_fusion_repair_maintenance_contract,group_fusion_repairs_dispatcher,1,1,1,0
access_repair_maintenance_manager,Maintenance Contract Manager Full,model_fusion_repair_maintenance_contract,group_fusion_repairs_manager,1,1,1,1
access_repair_order_repairs_user,Repair Order Repairs User Read/Write,repair.model_repair_order,group_fusion_repairs_user,1,1,1,0
access_repair_order_repairs_manager,Repair Order Repairs Manager Full,repair.model_repair_order,group_fusion_repairs_manager,1,1,1,1
access_technician_task_repairs_user,Technician Task Repairs User Schedule,fusion_tasks.model_fusion_technician_task,group_fusion_repairs_user,1,1,1,0
access_technician_task_repairs_manager,Technician Task Repairs Manager Full,fusion_tasks.model_fusion_technician_task,group_fusion_repairs_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
19 access_repair_maintenance_user Maintenance Contract User Read model_fusion_repair_maintenance_contract group_fusion_repairs_user 1 0 0 0
20 access_repair_maintenance_dispatcher Maintenance Contract Dispatcher model_fusion_repair_maintenance_contract group_fusion_repairs_dispatcher 1 1 1 0
21 access_repair_maintenance_manager Maintenance Contract Manager Full model_fusion_repair_maintenance_contract group_fusion_repairs_manager 1 1 1 1
22 access_repair_order_repairs_user Repair Order Repairs User Read/Write repair.model_repair_order group_fusion_repairs_user 1 1 1 0
23 access_repair_order_repairs_manager Repair Order Repairs Manager Full repair.model_repair_order group_fusion_repairs_manager 1 1 1 1
24 access_technician_task_repairs_user Technician Task Repairs User Schedule fusion_tasks.model_fusion_technician_task group_fusion_repairs_user 1 1 1 0
25 access_technician_task_repairs_manager Technician Task Repairs Manager Full fusion_tasks.model_fusion_technician_task group_fusion_repairs_manager 1 1 1 1

View File

@@ -64,7 +64,11 @@
</record>
<!-- Field technicians (from fusion_tasks) see only repairs they're assigned to as technician on a linked task.
Uses STORED fields (technician_id + additional_technician_ids) - not the computed all_technician_ids. -->
Uses STORED fields (technician_id + additional_technician_ids) - not the computed all_technician_ids.
NOTE: per-group rules in Odoo are OR'd. A user who is BOTH a field
technician AND a Repairs User/Dispatcher/Manager will see all repairs
because the permissive Repairs rules below grant access via the OR. -->
<record id="rule_repair_order_technician_own" model="ir.rule">
<field name="name">Repair Order: Technician sees own repairs</field>
<field name="model_id" ref="repair.model_repair_order"/>
@@ -76,6 +80,56 @@
<field name="perm_unlink" eval="False"/>
</record>
<!-- Repairs office users (User / Dispatcher / Manager) see all repairs
across companies they have access to. OR'd with the technician rule
above so admin / dispatchers who happen to also be in field_technician
still see everything. -->
<record id="rule_repair_order_repairs_user_full" model="ir.rule">
<field name="name">Repair Order: Repairs Office Full Access</field>
<field name="model_id" ref="repair.model_repair_order"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('group_fusion_repairs_user'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="False"/>
</record>
<record id="rule_repair_order_repairs_manager_unlink" model="ir.rule">
<field name="name">Repair Order: Repairs Manager Can Delete</field>
<field name="model_id" ref="repair.model_repair_order"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('group_fusion_repairs_manager'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
<!-- Repairs office users can read AND schedule technician tasks. This is
what makes "office can dispatch / reschedule" work without requiring
them to also be in the sales_team groups that fusion_tasks normally
keys off of. -->
<record id="rule_technician_task_repairs_office" model="ir.rule">
<field name="name">Technician Task: Repairs Office Access</field>
<field name="model_id" ref="fusion_tasks.model_fusion_technician_task"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('group_fusion_repairs_user'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="False"/>
</record>
<record id="rule_technician_task_repairs_manager_unlink" model="ir.rule">
<field name="name">Technician Task: Repairs Manager Can Delete</field>
<field name="model_id" ref="fusion_tasks.model_fusion_technician_task"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('group_fusion_repairs_manager'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
<!-- Intake answer access scoped to repair access -->
<record id="rule_repair_intake_answer_company" model="ir.rule">
<field name="name">Repair Intake Answer: Multi-Company</field>