- Refactor portal templates to eliminate intra-module template inheritance - Integrate emergency contacts section into player injuries template - Add full internal admin views for treatment notes with chatter support - Fix ORM warning in test_rights by using proper ORM commands - Update manifest to reflect new functionality (v18.0.1.9.0) This refactoring improves template stability by removing XPath errors and provides treatment professionals with better access to emergency contacts and treatment notes both in portal and backend interfaces.
634 lines
28 KiB
Python
634 lines
28 KiB
Python
import logging
|
|
import base64
|
|
import io
|
|
from odoo import http, fields, _
|
|
from odoo.exceptions import UserError, ValidationError
|
|
from odoo.http import request
|
|
from odoo.addons.portal.controllers.portal import CustomerPortal, pager
|
|
from datetime import datetime
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PatientInjuryPortal(CustomerPortal):
|
|
"""Controller for all injury reporting functionality in the portal"""
|
|
|
|
def _check_access_to_patient(self, patient_id):
|
|
"""Verify the user has access to this patient"""
|
|
user = request.env.user
|
|
patient = request.env['sports.patient'].browse(int(patient_id))
|
|
|
|
# Check if user has access to any team this patient belongs to
|
|
patient_id_int = int(patient_id)
|
|
accessible_teams = request.env['sports.team'].search([
|
|
('staff_ids.user_ids', 'in', user.id),
|
|
('patient_ids', 'in', patient_id_int)
|
|
])
|
|
|
|
# Medical professionals might have specific access
|
|
is_medical = user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
|
|
if not patient.exists() or (not accessible_teams and not is_medical):
|
|
raise UserError(_('You do not have access to this patient.'))
|
|
|
|
return patient
|
|
|
|
@http.route(['/my/patient/injury/new'], type='http', auth='user', website=True)
|
|
def create_injury_form(self, patient_id=None, **post):
|
|
"""Show form to create a new injury report"""
|
|
if not patient_id:
|
|
return request.redirect('/my/players')
|
|
|
|
try:
|
|
patient = self._check_access_to_patient(patient_id)
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
return_url = post.get('return_url', f'/my/player?player_id={patient_id}')
|
|
|
|
# Get patient's teams for the dropdown
|
|
teams = patient.team_ids
|
|
|
|
# Pre-selected team ID (when player is only on one team)
|
|
default_team_id = teams[0].id if len(teams) == 1 else None
|
|
|
|
# Check if user is a treatment professional
|
|
user = request.env.user
|
|
is_treatment_prof = user.has_group('bemade_sports_clinic.group_portal_treatment_professional')
|
|
|
|
values = {
|
|
'patient': patient,
|
|
'teams': teams, # Pass teams to the template for dropdown
|
|
'default_team_id': default_team_id, # Will be None if multiple teams
|
|
'return_url': return_url,
|
|
'page_name': 'report_injury',
|
|
'is_treatment_prof': is_treatment_prof, # Pass flag to template for conditional display
|
|
}
|
|
|
|
return request.render('bemade_sports_clinic.portal_create_injury', values)
|
|
|
|
@http.route(['/my/patient/injury/create'], type='http', auth='user', website=True, methods=['POST'])
|
|
def create_injury_submit(self, **post):
|
|
"""Process the form submission to create a new injury"""
|
|
patient_id = post.get('patient_id')
|
|
|
|
if not patient_id:
|
|
return request.redirect('/my/players')
|
|
|
|
try:
|
|
patient = self._check_access_to_patient(patient_id)
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
# Get the selected team
|
|
team_id = post.get('team_id')
|
|
if not team_id:
|
|
return request.redirect(f'/my/patient/injury/new?patient_id={patient_id}')
|
|
|
|
# Check if the current user is a treatment professional
|
|
is_treatment_prof = request.env.user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
|
|
# Prepare values for injury creation
|
|
vals = {
|
|
'patient_id': int(patient_id),
|
|
'diagnosis': post.get('diagnosis'),
|
|
'external_notes': post.get('external_notes'),
|
|
# Set stage based on user role - treatment professionals create active injuries
|
|
'stage': 'active' if is_treatment_prof else 'unverified',
|
|
'patient_name': patient.name,
|
|
# Store which team the injury was reported for
|
|
'team_id': int(team_id),
|
|
# Store parental consent value
|
|
'parental_consent': post.get('parental_consent', 'no'),
|
|
}
|
|
|
|
# Handle dates
|
|
if post.get('injury_date'):
|
|
vals['injury_date'] = post.get('injury_date')
|
|
|
|
if post.get('predicted_resolution_date'):
|
|
vals['predicted_resolution_date'] = post.get('predicted_resolution_date')
|
|
|
|
# Create the injury record
|
|
injury = request.env['sports.patient.injury'].sudo().create(vals)
|
|
|
|
user = request.env.user
|
|
# Determine if user is a coach or treatment professional
|
|
is_portal_coach = user.has_group('bemade_sports_clinic.group_portal_team_coach')
|
|
is_treatment_prof = user.has_group('bemade_sports_clinic.group_portal_treatment_professional')
|
|
has_treatment_attr = hasattr(user, 'is_treatment_professional') and user.is_treatment_professional
|
|
|
|
# Detailed logging of the current user's status
|
|
_logger.info(f"Current user: {user.name} (ID: {user.id})")
|
|
_logger.info(f"Is portal coach: {is_portal_coach}")
|
|
_logger.info(f"Is in portal treatment professional group: {is_treatment_prof}")
|
|
_logger.info(f"Has is_treatment_professional=True: {has_treatment_attr}")
|
|
|
|
# If user is a treatment professional, add them to the treatment professionals
|
|
# Make sure to check both the group membership and the is_treatment_professional field
|
|
if is_treatment_prof or has_treatment_attr:
|
|
_logger.info(f"Adding current user {user.name} (ID: {user.id}) to treatment professionals")
|
|
injury.sudo().write({
|
|
'treatment_professional_ids': [(4, user.id)]
|
|
})
|
|
else:
|
|
_logger.info(f"User {user.name} is not identified as a treatment professional, not adding to injury")
|
|
|
|
# Double-check who's assigned after our additions
|
|
treatment_profs = injury.sudo().treatment_professional_ids
|
|
_logger.info(f"Treatment professionals after assignment: {[u.name for u in treatment_profs]} (IDs: {treatment_profs.ids})")
|
|
|
|
# Always try to assign team therapists regardless of who created the injury
|
|
if True:
|
|
# Use the selected team_id from the form
|
|
selected_team_id = int(team_id)
|
|
|
|
# Find therapists specifically for this team
|
|
team_staff = request.env['sports.team.staff'].sudo().search([
|
|
('team_id', '=', selected_team_id), # Only from selected team
|
|
('role', 'in', ['head_therapist', 'therapist'])
|
|
])
|
|
|
|
# Log debug info
|
|
_logger.info(f"Found {len(team_staff)} therapists/head therapists for team {selected_team_id}")
|
|
for staff in team_staff:
|
|
_logger.info(f"Staff: {staff.partner_id.name}, Role: {staff.role}, User IDs: {[u.id for u in staff.user_ids]}")
|
|
if not staff.user_ids:
|
|
_logger.info(f" - WARNING: No user_ids for {staff.partner_id.name}")
|
|
# Try to find a user directly associated with this partner
|
|
users = request.env['res.users'].sudo().search([('partner_id', '=', staff.partner_id.id)])
|
|
_logger.info(f" - Found direct users: {[u.id for u in users]}")
|
|
|
|
# Filter by role
|
|
head_therapists = team_staff.filtered(lambda s: s.role == 'head_therapist')
|
|
therapists = team_staff.filtered(lambda s: s.role == 'therapist')
|
|
|
|
_logger.info(f"Found {len(head_therapists)} head therapists and {len(therapists)} therapists")
|
|
|
|
# First try to assign head therapist, then any therapist from the selected team
|
|
treatment_pros_assigned = False
|
|
|
|
# Try to assign head therapist first
|
|
if head_therapists:
|
|
# Find users associated directly with the head therapist partner
|
|
head_therapist = head_therapists[0]
|
|
users = request.env['res.users'].sudo().search([('partner_id', '=', head_therapist.partner_id.id)])
|
|
|
|
if users:
|
|
_logger.info(f"Assigning head therapist: {head_therapist.partner_id.name} with user ID {users[0].id}")
|
|
injury.sudo().write({
|
|
'treatment_professional_ids': [(4, users[0].id)]
|
|
})
|
|
treatment_pros_assigned = True
|
|
else:
|
|
_logger.info(f"No user account found for head therapist: {head_therapist.partner_id.name}")
|
|
|
|
# Try to assign regular therapist if no head therapist was assigned
|
|
if not treatment_pros_assigned and therapists:
|
|
# Find users associated directly with the therapist partner
|
|
therapist = therapists[0]
|
|
users = request.env['res.users'].sudo().search([('partner_id', '=', therapist.partner_id.id)])
|
|
|
|
if users:
|
|
_logger.info(f"Assigning therapist: {therapist.partner_id.name} with user ID {users[0].id}")
|
|
injury.sudo().write({
|
|
'treatment_professional_ids': [(4, users[0].id)]
|
|
})
|
|
treatment_pros_assigned = True
|
|
else:
|
|
_logger.info(f"No user account found for therapist: {therapist.partner_id.name}")
|
|
|
|
# If no therapist was assigned, log a warning
|
|
if not treatment_pros_assigned:
|
|
_logger.warning("No valid therapists found to assign to the injury")
|
|
|
|
# Trigger recomputation of patient status based on the injury
|
|
patient.sudo()._compute_is_injured()
|
|
patient.sudo()._compute_stage()
|
|
|
|
return_url = f'/my/player?player_id={patient_id}'
|
|
values = {
|
|
'return_url': return_url,
|
|
}
|
|
|
|
return request.render('bemade_sports_clinic.portal_injury_created', values)
|
|
|
|
def _check_access_to_injury(self, injury_id):
|
|
"""Verify the user has access to this injury"""
|
|
user = request.env.user
|
|
injury = request.env['sports.patient.injury'].browse(int(injury_id))
|
|
|
|
# Check if user has access to the team this injury is associated with
|
|
if not injury.exists():
|
|
raise UserError(_('Injury not found.'))
|
|
|
|
# Get the team from the injury
|
|
team = injury.team_id
|
|
|
|
if team:
|
|
# Check if user is part of the team staff
|
|
is_team_staff = team.staff_ids.filtered(lambda s: s.user_ids and user.id in s.user_ids.ids)
|
|
# Or if user is a medical professional with broader access
|
|
is_medical = user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
|
|
if not is_team_staff and not is_medical:
|
|
raise UserError(_('You do not have access to this injury.'))
|
|
else:
|
|
# If no team is specified, only medical professionals can access
|
|
if not user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional'):
|
|
raise UserError(_('You do not have access to this injury.'))
|
|
|
|
return injury
|
|
|
|
@http.route(['/my/injury/edit'], type='http', auth='user', website=True)
|
|
def edit_injury_form(self, injury_id=None, **post):
|
|
"""Show form to edit an existing injury"""
|
|
if not injury_id:
|
|
return request.redirect('/my/players')
|
|
|
|
try:
|
|
injury = self._check_access_to_injury(injury_id)
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
return_url = post.get('return_url', f'/my/player?player_id={injury.patient_id.id}')
|
|
|
|
# Get possible injury stages - treatment professionals can change stage
|
|
stages = []
|
|
user = request.env.user
|
|
is_treatment_prof = user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
|
|
if is_treatment_prof:
|
|
stage_selection = request.env['sports.patient.injury']._fields['stage'].selection
|
|
stages = [(k, v) for k, v in stage_selection]
|
|
|
|
# Get body locations for dropdown
|
|
body_locations = request.env['sports.body.location'].search([])
|
|
|
|
# Get possible injury types for dropdown
|
|
injury_types = request.env['sports.injury.type'].search([])
|
|
|
|
# Get possible severity options
|
|
severity_options = request.env['sports.patient.injury']._fields['severity'].selection
|
|
|
|
# Get parental consent options if treatment professional
|
|
parental_consent_options = None
|
|
if is_treatment_prof:
|
|
parental_consent_options = request.env['sports.patient.injury']._fields['parental_consent'].selection
|
|
|
|
values = {
|
|
'injury': injury,
|
|
'stages': stages,
|
|
'body_locations': body_locations,
|
|
'injury_types': injury_types,
|
|
'severity_options': severity_options,
|
|
'parental_consent_options': parental_consent_options,
|
|
'return_url': return_url,
|
|
'is_treatment_prof': is_treatment_prof,
|
|
'page_name': 'edit_injury',
|
|
'error': post.get('error'),
|
|
'success': post.get('success'),
|
|
}
|
|
|
|
return request.render('bemade_sports_clinic.portal_edit_injury', values)
|
|
|
|
@http.route(['/my/injury/save'], type='http', auth='user', website=True, methods=['POST'])
|
|
def edit_injury_submit(self, **post):
|
|
"""Process the form submission to update an injury"""
|
|
injury_id = post.get('injury_id')
|
|
|
|
if not injury_id:
|
|
return request.redirect('/my/players')
|
|
|
|
try:
|
|
injury = self._check_access_to_injury(injury_id)
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
# Get user's role
|
|
user = request.env.user
|
|
is_treatment_prof = user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
|
|
# Prepare values for injury update
|
|
vals = {}
|
|
|
|
# Fields everyone can update
|
|
vals.update({
|
|
'diagnosis': post.get('diagnosis', injury.diagnosis or ''),
|
|
'external_notes': post.get('external_notes', injury.external_notes or ''),
|
|
})
|
|
|
|
# Fields only treatment professionals can update
|
|
if is_treatment_prof:
|
|
# Only add fields that were actually submitted
|
|
if post.get('body_location_id'):
|
|
vals['body_location_id'] = int(post.get('body_location_id'))
|
|
|
|
if post.get('injury_type_id'):
|
|
vals['injury_type_id'] = int(post.get('injury_type_id'))
|
|
|
|
if post.get('severity'):
|
|
vals['severity'] = post.get('severity')
|
|
|
|
if post.get('internal_notes'):
|
|
vals['internal_notes'] = post.get('internal_notes')
|
|
|
|
if post.get('stage'):
|
|
vals['stage'] = post.get('stage')
|
|
|
|
if post.get('parental_consent'):
|
|
vals['parental_consent'] = post.get('parental_consent')
|
|
|
|
# Update the injury
|
|
injury.sudo().write(vals)
|
|
|
|
# Add a treatment note if provided
|
|
if post.get('treatment_note') and is_treatment_prof:
|
|
self._add_treatment_note(injury, post.get('treatment_note'))
|
|
|
|
# Redirect back to the edit form with success message
|
|
return_url = post.get('return_url', f'/my/injury/edit?injury_id={injury_id}')
|
|
return request.redirect(f'{return_url}&success=injury_updated')
|
|
|
|
def _add_treatment_note(self, patient, note_content, injury=None):
|
|
"""Helper method to add a treatment note to a patient, optionally linked to an injury"""
|
|
if not note_content.strip():
|
|
return False
|
|
|
|
# Create a new treatment note linked to patient, optionally to injury
|
|
vals = {
|
|
'patient_id': patient.id,
|
|
'note': note_content,
|
|
'date': fields.Date.today(),
|
|
'user_id': request.env.user.id,
|
|
}
|
|
|
|
# If injury is provided, link the note to it
|
|
if injury:
|
|
vals['injury_id'] = injury.id
|
|
|
|
request.env['sports.treatment.note'].sudo().create(vals)
|
|
|
|
return True
|
|
|
|
@http.route(['/my/injury/notes'], type='http', auth='user', website=True)
|
|
def view_treatment_notes(self, injury_id=None, patient_id=None, **post):
|
|
"""View treatment notes for an injury or a patient"""
|
|
# Determine context - are we viewing injury-specific notes or all patient notes?
|
|
# At least one of injury_id or patient_id must be provided
|
|
if not injury_id and not patient_id:
|
|
return request.redirect('/my/players')
|
|
|
|
# Get user's role
|
|
is_treatment_prof = request.env.user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
|
|
if injury_id:
|
|
# Injury context
|
|
try:
|
|
injury = self._check_access_to_injury(injury_id)
|
|
patient = injury.patient_id
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
# Get notes for this injury
|
|
notes = request.env['sports.treatment.note'].sudo().search(
|
|
[('injury_id', '=', int(injury_id))],
|
|
order='date desc, id desc'
|
|
)
|
|
|
|
values = {
|
|
'injury': injury,
|
|
'notes': notes,
|
|
'patient': patient,
|
|
'is_treatment_prof': is_treatment_prof,
|
|
'page_name': 'injury_notes',
|
|
'error': post.get('error'),
|
|
'success': post.get('success'),
|
|
'context': 'injury',
|
|
}
|
|
|
|
else:
|
|
# Patient context
|
|
try:
|
|
patient = self._check_access_to_patient(patient_id)
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
# Get all notes for this patient
|
|
notes = request.env['sports.treatment.note'].sudo().search(
|
|
[('patient_id', '=', int(patient_id))],
|
|
order='date desc, id desc'
|
|
)
|
|
|
|
values = {
|
|
'injury': None,
|
|
'notes': notes,
|
|
'patient': patient,
|
|
'is_treatment_prof': is_treatment_prof,
|
|
'page_name': 'patient_notes',
|
|
'error': post.get('error'),
|
|
'success': post.get('success'),
|
|
'context': 'patient',
|
|
}
|
|
|
|
return request.render('bemade_sports_clinic.portal_treatment_notes', values)
|
|
|
|
@http.route(['/my/injury/note/add'], type='http', auth='user', website=True, methods=['POST'])
|
|
def add_treatment_note(self, **post):
|
|
"""Add a new treatment note to a patient, optionally linked to an injury"""
|
|
# Get context - are we adding a note to an injury or just to a patient?
|
|
injury_id = post.get('injury_id')
|
|
patient_id = post.get('patient_id')
|
|
|
|
# Either injury_id or patient_id must be provided
|
|
if not injury_id and not patient_id:
|
|
return request.redirect('/my/players')
|
|
|
|
# Check if user is a treatment professional
|
|
is_treatment_prof = request.env.user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
if not is_treatment_prof:
|
|
# Determine redirect URL based on context
|
|
if injury_id:
|
|
return request.redirect(f'/my/injury/notes?injury_id={injury_id}&error=permission_denied')
|
|
else:
|
|
return request.redirect(f'/my/injury/notes?patient_id={patient_id}&error=permission_denied')
|
|
|
|
# Get note content and validate
|
|
note_content = post.get('note')
|
|
if not note_content or not note_content.strip():
|
|
if injury_id:
|
|
return request.redirect(f'/my/injury/notes?injury_id={injury_id}&error=empty_note')
|
|
else:
|
|
return request.redirect(f'/my/injury/notes?patient_id={patient_id}&error=empty_note')
|
|
|
|
# Determine context and add the note
|
|
if injury_id:
|
|
# Injury context
|
|
try:
|
|
injury = self._check_access_to_injury(injury_id)
|
|
patient = injury.patient_id
|
|
self._add_treatment_note(patient, note_content, injury)
|
|
return request.redirect(f'/my/injury/notes?injury_id={injury_id}&success=note_added')
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
else:
|
|
# Patient context
|
|
try:
|
|
patient = self._check_access_to_patient(patient_id)
|
|
self._add_treatment_note(patient, note_content)
|
|
return request.redirect(f'/my/injury/notes?patient_id={patient_id}&success=note_added')
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
@http.route(['/my/injury/documents'], type='http', auth='user', website=True)
|
|
def view_injury_documents(self, injury_id=None, **post):
|
|
"""View documents attached to an injury"""
|
|
if not injury_id:
|
|
return request.redirect('/my/players')
|
|
|
|
try:
|
|
injury = self._check_access_to_injury(injury_id)
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
# Get documents for this injury
|
|
documents = request.env['sports.injury.document'].sudo().search(
|
|
[('injury_id', '=', int(injury_id))],
|
|
order='create_date desc'
|
|
)
|
|
|
|
# Get user's role
|
|
is_treatment_prof = request.env.user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
|
|
# Document categories
|
|
categories = [('medical', 'Medical'), ('xray', 'X-Ray'), ('mri', 'MRI'),
|
|
('prescription', 'Prescription'), ('other', 'Other')]
|
|
|
|
values = {
|
|
'injury': injury,
|
|
'documents': documents,
|
|
'patient': injury.patient_id,
|
|
'is_treatment_prof': is_treatment_prof,
|
|
'page_name': 'injury_documents',
|
|
'error': post.get('error'),
|
|
'success': post.get('success'),
|
|
'categories': categories,
|
|
}
|
|
|
|
return request.render('bemade_sports_clinic.portal_injury_documents', values)
|
|
|
|
@http.route(['/my/injury/document/upload'], type='http', auth='user', website=True, methods=['POST'])
|
|
def upload_injury_document(self, **post):
|
|
"""Upload a document for an injury"""
|
|
injury_id = post.get('injury_id')
|
|
|
|
if not injury_id:
|
|
return request.redirect('/my/players')
|
|
|
|
try:
|
|
injury = self._check_access_to_injury(injury_id)
|
|
except UserError as e:
|
|
return request.render('portal.403', {'error': str(e)})
|
|
|
|
# Check if file was uploaded
|
|
attachment = post.get('attachment')
|
|
if not attachment:
|
|
return request.redirect(f'/my/injury/documents?injury_id={injury_id}&error=no_file')
|
|
|
|
# Process the file
|
|
try:
|
|
name = attachment.filename
|
|
file_content = attachment.read()
|
|
file_size = len(file_content)
|
|
|
|
# Check file size (limit to 10MB)
|
|
if file_size > 10 * 1024 * 1024: # 10MB in bytes
|
|
return request.redirect(f'/my/injury/documents?injury_id={injury_id}&error=file_too_large')
|
|
|
|
# Create the document
|
|
document = request.env['sports.injury.document'].sudo().create({
|
|
'injury_id': int(injury_id),
|
|
'name': post.get('document_name', name),
|
|
'description': post.get('description', ''),
|
|
'category': post.get('category', 'other'),
|
|
'file_content': base64.b64encode(file_content),
|
|
'file_name': name,
|
|
'created_by_id': request.env.user.id,
|
|
})
|
|
|
|
# Redirect back to documents page with success message
|
|
return request.redirect(f'/my/injury/documents?injury_id={injury_id}&success=document_uploaded')
|
|
|
|
except Exception as e:
|
|
_logger.error(f"Error uploading document: {e}")
|
|
return request.redirect(f'/my/injury/documents?injury_id={injury_id}&error=upload_failed')
|
|
|
|
@http.route(['/my/injury/document/download/<int:document_id>'], type='http', auth='user')
|
|
def download_injury_document(self, document_id, **post):
|
|
"""Download a document attached to an injury"""
|
|
document = request.env['sports.injury.document'].sudo().browse(int(document_id))
|
|
|
|
if not document.exists():
|
|
return request.not_found()
|
|
|
|
try:
|
|
# Check access to the injury this document belongs to
|
|
injury = self._check_access_to_injury(document.injury_id.id)
|
|
except UserError:
|
|
return request.not_found()
|
|
|
|
# Return the file for download
|
|
return request.make_response(
|
|
base64.b64decode(document.file_content),
|
|
headers=[
|
|
('Content-Type', 'application/octet-stream'),
|
|
('Content-Disposition', f'attachment; filename="{document.file_name}"'),
|
|
]
|
|
)
|
|
|
|
@http.route(['/my/injury/document/delete/<int:document_id>'], type='http', auth='user', website=True)
|
|
def delete_injury_document(self, document_id, **post):
|
|
"""Delete a document attached to an injury"""
|
|
document = request.env['sports.injury.document'].sudo().browse(int(document_id))
|
|
|
|
if not document.exists():
|
|
return request.not_found()
|
|
|
|
try:
|
|
# Check access to the injury this document belongs to
|
|
injury = self._check_access_to_injury(document.injury_id.id)
|
|
except UserError:
|
|
return request.not_found()
|
|
|
|
# Check if user is a treatment professional (only they can delete documents)
|
|
is_treatment_prof = request.env.user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
|
if not is_treatment_prof:
|
|
return request.redirect(f'/my/injury/documents?injury_id={document.injury_id.id}&error=permission_denied')
|
|
|
|
# Delete the document
|
|
injury_id = document.injury_id.id
|
|
document.sudo().unlink()
|
|
|
|
# Redirect back to documents page with success message
|
|
return request.redirect(f'/my/injury/documents?injury_id={injury_id}&success=document_deleted')
|
|
|
|
@http.route(['/my/injury/verify'], type='http', auth='user', website=True, methods=['POST'])
|
|
def verify_injury(self, injury_id, **post):
|
|
"""Verify an injury (change status from unverified to active)"""
|
|
try:
|
|
injury = request.env['sports.patient.injury'].browse(int(injury_id))
|
|
|
|
# Check access - user must be a treatment professional or admin
|
|
if not (request.env.user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional') or
|
|
request.env.user.has_group('base.group_system')):
|
|
return request.redirect('/my')
|
|
|
|
# Verify the injury
|
|
injury.sudo().action_verify_injury()
|
|
|
|
# Redirect back to the player page
|
|
return request.redirect(f'/my/player?player_id={injury.patient_id.id}')
|
|
|
|
except Exception as e:
|
|
_logger.error(f"Error verifying injury: {e}")
|
|
return request.redirect('/my')
|