From fae0d986373f294748689a8cee625a31d3ab49e1 Mon Sep 17 00:00:00 2001 From: Denis Durepos Date: Sun, 27 Jul 2025 20:20:23 -0400 Subject: [PATCH] Fix treatment professional portal access and group assignment - Add patient address management in portal UI for therapists/coaches - Fix treatment professional selection dropdown in injury detail forms - Implement automatic group assignment when portal access is granted - Add create() and write() overrides in res.users to detect portal access - Expand treatment professional roles to include doctors - Add comprehensive debugging for portal access workflow - Update portal UI buttons to use Odoo company colors - Add ACLs for snailmail.letter and res.users access for portal groups Resolves issues with treatment professionals not appearing in portal dropdowns after being granted portal access. Now works for all roles: doctors, therapists, and head therapists. --- bemade_sports_clinic/TODO.md | 4 +- .../controllers/player_management_portal.py | 28 ++++++ bemade_sports_clinic/models/res_users.py | 77 +++++++++++++++ bemade_sports_clinic/models/sports_team.py | 12 ++- .../security/ir.model.access.csv | 3 + .../injury_management_portal_templates.xml | 41 ++++---- .../player_management_portal_templates.xml | 93 +++++++++++++++++-- .../views/portal_activity_detail_template.xml | 28 +++--- .../views/sports_clinic_portal_views.xml | 36 +++---- .../views/sports_patient_injury_portal.xml | 6 +- .../task_management_portal_templates.xml | 28 +++--- 11 files changed, 272 insertions(+), 84 deletions(-) diff --git a/bemade_sports_clinic/TODO.md b/bemade_sports_clinic/TODO.md index 06bbd23..66dd746 100644 --- a/bemade_sports_clinic/TODO.md +++ b/bemade_sports_clinic/TODO.md @@ -158,5 +158,5 @@ - [ ]Change action button colors to Fit Crew color scheme (instead of the weird turquoise) - [ ]Confirm followers added correctly when therapist adds player to team - [x]Remove Team from injury detail (including from model - was not there before) -- [ ]Fix treatment professional selection in injury detail -- [ ]Add patient address add/edit to coach/therapist portal \ No newline at end of file +- [x]Fix treatment professional selection in injury detail +- [x]Add patient address add/edit to coach/therapist portal \ No newline at end of file diff --git a/bemade_sports_clinic/controllers/player_management_portal.py b/bemade_sports_clinic/controllers/player_management_portal.py index ebbf581..5363052 100644 --- a/bemade_sports_clinic/controllers/player_management_portal.py +++ b/bemade_sports_clinic/controllers/player_management_portal.py @@ -78,10 +78,17 @@ class PlayerManagementPortal(CustomerPortal): # Debug log for the entire patient_info dictionary _logger.info(f"DEBUG - patient_info: {patient_info}") + # Get Canada and Canadian provinces/territories for address dropdowns + canada = request.env['res.country'].search([('code', '=', 'CA')], limit=1) + states = request.env['res.country.state'].search([('country_id', '=', canada.id)], order='name') if canada else request.env['res.country.state'] + countries = canada if canada else request.env['res.country'].search([], order='name') + values = { 'patient': patient, # Keep original patient 'patient_info': patient_info, # Add patient_info for protected fields 'teams': teams, + 'states': states, + 'countries': countries, 'return_url': return_url, 'page_name': 'edit_player', 'is_treatment_prof': is_treatment_prof, @@ -126,6 +133,27 @@ class PlayerManagementPortal(CustomerPortal): 'phone': post.get('phone'), }) + # Address information - any portal user with access can update these + address_fields = ['street', 'street2', 'city', 'zip'] + for field in address_fields: + if field in post: + vals[field] = post.get(field) or False + + # Handle state and country selections + if post.get('state_id'): + try: + state_id = int(post.get('state_id')) + vals['state_id'] = state_id + except (ValueError, TypeError): + pass # Invalid state_id, skip + + if post.get('country_id'): + try: + country_id = int(post.get('country_id')) + vals['country_id'] = country_id + except (ValueError, TypeError): + pass # Invalid country_id, skip + # Additional fields that only treatment professionals can update if is_treatment_prof: if post.get('date_of_birth'): diff --git a/bemade_sports_clinic/models/res_users.py b/bemade_sports_clinic/models/res_users.py index 4ff22a4..4aed86c 100644 --- a/bemade_sports_clinic/models/res_users.py +++ b/bemade_sports_clinic/models/res_users.py @@ -1,4 +1,7 @@ from odoo import models, fields, api, _, Command +import logging + +_logger = logging.getLogger(__name__) class User(models.Model): @@ -32,3 +35,77 @@ class User(models.Model): for team in added_teams ] ) + + def write(self, vals): + """Override write to trigger treatment professional group assignment when portal access is granted.""" + _logger.info(f"DEBUG: res.users.write() called with vals: {vals}") + _logger.info(f"DEBUG: Processing {len(self)} users: {[u.login for u in self]}") + + # Check if groups_id is being modified (portal access being granted/revoked) + if 'groups_id' in vals: + _logger.info(f"DEBUG: groups_id is being modified: {vals['groups_id']}") + # Get the portal group reference + portal_group = self.env.ref('base.group_portal') + _logger.info(f"DEBUG: Portal group ID: {portal_group.id}") + + # Store old group memberships before making changes + old_groups_by_user = {user.id: user.groups_id.ids for user in self} + _logger.info(f"DEBUG: Old groups by user: {old_groups_by_user}") + + # Apply the changes first + result = super().write(vals) + + # Check each user to see if portal access was granted + for user in self: + old_groups = old_groups_by_user[user.id] + new_groups = user.groups_id.ids + _logger.info(f"DEBUG: User {user.login} - Old groups: {old_groups}, New groups: {new_groups}") + + if portal_group.id in new_groups and portal_group.id not in old_groups: + _logger.info(f"DEBUG: Portal access granted to {user.login} - triggering group assignment") + # Portal access was just granted - trigger treatment professional group assignment + staff_records = self.env['sports.team.staff'].search([ + ('partner_id', '=', user.partner_id.id) + ]) + _logger.info(f"DEBUG: Found {len(staff_records)} staff records for user {user.login}") + if staff_records: + _logger.info(f"DEBUG: Staff roles: {[(s.team_id.name, s.role) for s in staff_records]}") + staff_records._update_treatment_professional_group(user) + _logger.info(f"DEBUG: Group assignment completed for {user.login}") + + return result + else: + _logger.info(f"DEBUG: groups_id not in vals, using normal write") + + # If groups_id is not being modified, use normal write + return super().write(vals) + + @api.model_create_multi + def create(self, vals_list): + """Override create to trigger treatment professional group assignment when portal users are created.""" + _logger.info(f"DEBUG: res.users.create() called with vals_list: {vals_list}") + + # Create the users first + users = super().create(vals_list) + + # Get the portal group reference + portal_group = self.env.ref('base.group_portal') + _logger.info(f"DEBUG: Portal group ID: {portal_group.id}") + + # Check each created user to see if they were created with portal access + for user in users: + _logger.info(f"DEBUG: Created user {user.login} with groups: {user.groups_id.ids}") + + if portal_group.id in user.groups_id.ids: + _logger.info(f"DEBUG: User {user.login} created with portal access - triggering group assignment") + # User was created with portal access - trigger treatment professional group assignment + staff_records = self.env['sports.team.staff'].search([ + ('partner_id', '=', user.partner_id.id) + ]) + _logger.info(f"DEBUG: Found {len(staff_records)} staff records for user {user.login}") + if staff_records: + _logger.info(f"DEBUG: Staff roles: {[(s.team_id.name, s.role) for s in staff_records]}") + staff_records._update_treatment_professional_group(user) + _logger.info(f"DEBUG: Group assignment completed for {user.login}") + + return users diff --git a/bemade_sports_clinic/models/sports_team.py b/bemade_sports_clinic/models/sports_team.py index 9f973bf..0a98305 100644 --- a/bemade_sports_clinic/models/sports_team.py +++ b/bemade_sports_clinic/models/sports_team.py @@ -371,9 +371,19 @@ class TeamStaff(models.Model): """ return self.env['sports.team.staff'].sudo().search([ ('partner_id', '=', partner_id), - ('role', 'in', ['head_therapist', 'therapist']) + ('role', 'in', ['head_therapist', 'therapist', 'doctor']) ]) + def update_all_treatment_professional_groups(self): + """Manual method to update treatment professional group assignments for all staff. + + This can be called to refresh group assignments after role changes or system updates. + Useful for fixing cases where staff members were added but not assigned to correct groups. + """ + all_staff = self.env['sports.team.staff'].search([]) + all_staff._update_treatment_professional_group() + return True + def _update_treatment_professional_group(self, specific_user=None): """Update treatment professional status based on staff role. diff --git a/bemade_sports_clinic/security/ir.model.access.csv b/bemade_sports_clinic/security/ir.model.access.csv index 8a88dbf..5f3d813 100644 --- a/bemade_sports_clinic/security/ir.model.access.csv +++ b/bemade_sports_clinic/security/ir.model.access.csv @@ -42,8 +42,11 @@ access_mail_notification_portal_tp,Portal TP Access for Mail Notifications,mail. access_ir_attachment_portal_tp,Portal TP Access for Attachments,base.model_ir_attachment,bemade_sports_clinic.group_portal_treatment_professional,1,1,1,0 access_res_users_portal_tp,Portal TP Access for Users,base.model_res_users,bemade_sports_clinic.group_portal_treatment_professional,1,0,0,0 +access_res_users_portal_coach,Portal Coach Access for Users,base.model_res_users,bemade_sports_clinic.group_portal_team_coach,1,0,0,0 access_res_partner_portal_tp,Portal TP Access for Partners,base.model_res_partner,bemade_sports_clinic.group_portal_treatment_professional,1,1,1,0 access_res_partner_portal_coach,Portal Coach Access for Partners,base.model_res_partner,bemade_sports_clinic.group_portal_team_coach,1,1,1,0 access_mail_followers_portal_tp,Portal TP Access for Followers,mail.model_mail_followers,bemade_sports_clinic.group_portal_treatment_professional,1,1,1,0 access_mail_followers_portal_coach,Portal Coach Access for Followers,mail.model_mail_followers,bemade_sports_clinic.group_portal_team_coach,1,1,1,0 access_bus_bus_portal_tp,Portal TP Access for Bus Messages,bus.model_bus_bus,bemade_sports_clinic.group_portal_treatment_professional,1,1,1,0 +access_snailmail_letter_portal_tp,Portal TP Access for Snailmail Letters,snailmail.model_snailmail_letter,bemade_sports_clinic.group_portal_treatment_professional,1,0,0,0 +access_snailmail_letter_portal_coach,Portal Coach Access for Snailmail Letters,snailmail.model_snailmail_letter,bemade_sports_clinic.group_portal_team_coach,1,0,0,0 diff --git a/bemade_sports_clinic/views/injury_management_portal_templates.xml b/bemade_sports_clinic/views/injury_management_portal_templates.xml index 4b27592..4bd12e1 100644 --- a/bemade_sports_clinic/views/injury_management_portal_templates.xml +++ b/bemade_sports_clinic/views/injury_management_portal_templates.xml @@ -40,10 +40,10 @@
- + Cancel -
@@ -209,17 +209,17 @@
- Cancel -
-
- + Cancel + + + @@ -272,7 +272,7 @@ - + Back to Patient @@ -314,7 +314,7 @@ placeholder="Enter treatment note">
- +
@@ -409,8 +409,8 @@
@@ -475,7 +475,7 @@ Maximum file size: 10MB
- +
@@ -520,16 +520,17 @@ - + Download - - +
+ + +
diff --git a/bemade_sports_clinic/views/player_management_portal_templates.xml b/bemade_sports_clinic/views/player_management_portal_templates.xml index 8677fab..c6f37f8 100644 --- a/bemade_sports_clinic/views/player_management_portal_templates.xml +++ b/bemade_sports_clinic/views/player_management_portal_templates.xml @@ -19,10 +19,10 @@
- + Cancel -
@@ -63,6 +63,79 @@
+ +
+
+
Address Information
+
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+
@@ -140,10 +213,10 @@
- +
@@ -216,10 +289,10 @@
- +
@@ -249,10 +322,10 @@
- + Cancel -
@@ -306,10 +379,10 @@
- +
diff --git a/bemade_sports_clinic/views/portal_activity_detail_template.xml b/bemade_sports_clinic/views/portal_activity_detail_template.xml index ff03c9b..2350c8c 100644 --- a/bemade_sports_clinic/views/portal_activity_detail_template.xml +++ b/bemade_sports_clinic/views/portal_activity_detail_template.xml @@ -89,22 +89,18 @@
- - - Back to Activities + + Back to Activities - -
@@ -137,8 +133,8 @@
@@ -166,8 +162,8 @@
@@ -191,7 +187,7 @@

Are you sure you want to cancel this activity? This action cannot be undone.

diff --git a/bemade_sports_clinic/views/sports_clinic_portal_views.xml b/bemade_sports_clinic/views/sports_clinic_portal_views.xml index cd4017b..6f1eff1 100644 --- a/bemade_sports_clinic/views/sports_clinic_portal_views.xml +++ b/bemade_sports_clinic/views/sports_clinic_portal_views.xml @@ -91,7 +91,7 @@
- + Add Player @@ -151,7 +151,7 @@
Injury @@ -180,7 +180,7 @@
@@ -293,16 +293,16 @@

- + Edit Player - + Report Injury - + Add Activity - + View Notes @@ -455,13 +455,13 @@ @@ -475,7 +475,7 @@

No injuries recorded

- + Report First Injury
@@ -681,7 +681,7 @@
Emergency Contacts
- + Add Emergency Contact
@@ -706,7 +706,7 @@
- + Edit
@@ -727,7 +727,7 @@

No emergency contacts found

- + Add First Contact
@@ -826,10 +826,10 @@
- + Cancel -
diff --git a/bemade_sports_clinic/views/sports_patient_injury_portal.xml b/bemade_sports_clinic/views/sports_patient_injury_portal.xml index 3e2fc2d..95a90f9 100644 --- a/bemade_sports_clinic/views/sports_patient_injury_portal.xml +++ b/bemade_sports_clinic/views/sports_patient_injury_portal.xml @@ -50,8 +50,8 @@
- - Cancel + + Cancel
@@ -71,7 +71,7 @@

The injury has been reported successfully.

diff --git a/bemade_sports_clinic/views/task_management_portal_templates.xml b/bemade_sports_clinic/views/task_management_portal_templates.xml index ae891fb..5d9b1ef 100644 --- a/bemade_sports_clinic/views/task_management_portal_templates.xml +++ b/bemade_sports_clinic/views/task_management_portal_templates.xml @@ -120,12 +120,12 @@ - - @@ -156,8 +156,8 @@ @@ -187,8 +187,8 @@ @@ -213,7 +213,7 @@

Are you sure you want to cancel this activity? This action cannot be undone.

@@ -306,10 +306,10 @@
- +
@@ -345,10 +345,10 @@
@@ -416,10 +416,10 @@
- +