Created portal views for therapists and Report Injury functionality for portal users (coaches and therapists).
This commit is contained in:
parent
b4eea01a20
commit
c60ffd5bfa
18 changed files with 262 additions and 58 deletions
|
|
@ -32,6 +32,11 @@
|
|||
|
||||
External users (portal users) can be added to give coaches and other team
|
||||
personnel access to limited player data such as estimated return-to-play dates.
|
||||
Medical professionals (primarily field therapists) can also access the system
|
||||
via the portal interface instead of requiring full internal user accounts, allowing
|
||||
for more flexible collaboration while maintaining appropriate access controls.
|
||||
Coaches and treatment professionals can signal player injuries directly through the
|
||||
portal interface, streamlining communication and injury tracking.
|
||||
""",
|
||||
"category": "Services/Medical",
|
||||
"author": "Bemade Inc.",
|
||||
|
|
@ -45,14 +50,18 @@
|
|||
},
|
||||
"data": [
|
||||
"security/sports_clinic_groups.xml",
|
||||
"security/sports_clinic_portal_groups.xml",
|
||||
"security/ir.model.access.csv",
|
||||
"security/sports_clinic_rules.xml",
|
||||
"security/sports_clinic_portal_rules.xml",
|
||||
"data/sports_clinic_data.xml",
|
||||
"data/admin_access_data.xml",
|
||||
"views/sports_team_views.xml",
|
||||
"views/sports_clinic_menus.xml",
|
||||
"views/sports_patient_injury_views.xml",
|
||||
"views/sports_patient_views.xml",
|
||||
"views/sports_clinic_portal_views.xml",
|
||||
"views/sports_patient_injury_portal.xml",
|
||||
"views/res_partner_views.xml",
|
||||
"views/res_users_views.xml",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
from . import team_staff_portal
|
||||
from . import patient_injury_portal
|
||||
|
|
|
|||
|
|
@ -165,7 +165,10 @@
|
|||
<field name="partner_id" ref="partner_therapist_team_carabins"/>
|
||||
<field name="login">therapist</field>
|
||||
<field name="password">therapist</field>
|
||||
<field name="groups_id" eval="[Command.clear()]"/>
|
||||
<field name="groups_id" eval="[(5, 0, 0),
|
||||
(4, ref('base.group_portal'))]"/>
|
||||
<!-- Note: Portal users should not be directly assigned to treatment_professional group -->
|
||||
<!-- The is_treatment_professional flag will be set based on staff role instead -->
|
||||
</record>
|
||||
<record id="carabins_coach_user" model="res.users" context="{'no_reset_password': True}">
|
||||
<field name="partner_id" ref="partner_coach_team_carabins"/>
|
||||
|
|
@ -173,12 +176,7 @@
|
|||
<field name="password">coach</field>
|
||||
<field name="groups_id" eval="[Command.clear()]"/>
|
||||
</record>
|
||||
<record id="base.group_portal" model="res.groups">
|
||||
<field name="users" eval="[Command.link(ref('carabins_therapist_user'))]"/>
|
||||
</record>
|
||||
<record id="base.group_portal" model="res.groups">
|
||||
<field name="users" eval="[Command.link(ref('carabins_coach_user'))]"/>
|
||||
</record>
|
||||
<!-- Users should be either internal users or portal users, not both -->
|
||||
<record id="group_sports_clinic_admin" model="res.groups">
|
||||
<field name="users" eval="[Command.link(ref('base.user_admin'))]"/>
|
||||
</record>
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ msgid "Date of Injury"
|
|||
msgstr "Date de la blessure"
|
||||
|
||||
#. module: bemade_sports_clinic
|
||||
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_injury_view_tree
|
||||
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_injury_view_list
|
||||
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_list_embedded
|
||||
msgid "Details"
|
||||
msgstr "Détails"
|
||||
|
|
@ -798,7 +798,7 @@ msgid "Patient Injury"
|
|||
msgstr "La blessure d'un patient."
|
||||
|
||||
#. module: bemade_sports_clinic
|
||||
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_injury_view_tree
|
||||
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_injury_view_list
|
||||
msgid "Patient Injury History"
|
||||
msgstr "Historique des blessures du patient"
|
||||
|
||||
|
|
|
|||
|
|
@ -253,6 +253,40 @@ class Patient(models.Model):
|
|||
"context": self._context,
|
||||
"res_id": self.id,
|
||||
}
|
||||
|
||||
def action_report_injury(self):
|
||||
"""Open the injury report form for this patient.
|
||||
For portal users: redirects to the portal form
|
||||
For backend users: opens a new injury form in the backend
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
# Check if current user is a portal user
|
||||
is_portal = self.env.user.has_group('base.group_portal')
|
||||
|
||||
if is_portal:
|
||||
# Redirect to portal injury form
|
||||
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||
portal_url = f"{base_url}/my/patient/injury/new?patient_id={self.id}"
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': portal_url,
|
||||
'target': 'self',
|
||||
}
|
||||
else:
|
||||
# Open backend injury form
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': f'Report Injury for {self.name}',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'sports.patient.injury',
|
||||
'context': {
|
||||
'default_patient_id': self.id,
|
||||
'default_patient_name': self.name,
|
||||
'default_stage': 'active',
|
||||
'default_team_id': self.team_ids[0].id if self.team_ids else False
|
||||
},
|
||||
}
|
||||
|
||||
@api.onchange("mobile", "country_id")
|
||||
def _onchange_mobile_validation(self):
|
||||
|
|
|
|||
|
|
@ -5,7 +5,12 @@ from odoo.addons.phone_validation.tools import phone_validation
|
|||
class PatientContact(models.Model):
|
||||
_name = 'sports.patient.contact'
|
||||
_description = "Emergency or other contacts for a patient."
|
||||
|
||||
|
||||
@api.model
|
||||
def _valid_field_parameter(self, field, name):
|
||||
# Allow 'unaccent' parameter for fields
|
||||
return name == 'unaccent' or super()._valid_field_parameter(field, name)
|
||||
|
||||
sequence = fields.Integer(required=True, default=0)
|
||||
name = fields.Char(unaccent=True)
|
||||
contact_type = fields.Selection(selection=[
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@ class PatientInjury(models.Model):
|
|||
ondelete="cascade",
|
||||
)
|
||||
patient_name = fields.Char(related="patient_id.name")
|
||||
team_id = fields.Many2one(
|
||||
comodel_name="sports.team",
|
||||
string="Team",
|
||||
help="The team for which this injury was reported, especially important when a player belongs to multiple teams.",
|
||||
)
|
||||
diagnosis = fields.Char(tracking=True)
|
||||
|
||||
injury_date = fields.Date(
|
||||
|
|
@ -171,5 +176,33 @@ class PatientInjury(models.Model):
|
|||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
res = super().create(vals_list)
|
||||
res.patient_id.recompute_followers()
|
||||
|
||||
for record in res:
|
||||
# Automatically assign therapist when creating an injury
|
||||
current_user = self.env.user
|
||||
|
||||
# If the injury creator is a treatment professional, assign them
|
||||
if current_user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional'):
|
||||
record.treatment_professional_ids = [(4, current_user.id)]
|
||||
# Otherwise, if there's a team_id, find and assign team therapists
|
||||
elif record.team_id:
|
||||
# Find all team staff users
|
||||
team_staff = self.env['sports.team.staff'].search([
|
||||
('team_id', '=', record.team_id.id)
|
||||
])
|
||||
|
||||
# Filter to only staff users who are treatment professionals
|
||||
if team_staff:
|
||||
treatment_professional_group = self.env.ref('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
||||
# Get all users from staff and filter them by group
|
||||
staff_users = team_staff.mapped('user_ids')
|
||||
therapist_users = staff_users.filtered(
|
||||
lambda user: user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
||||
)
|
||||
|
||||
if therapist_users:
|
||||
record.treatment_professional_ids = [(6, 0, therapist_users.ids)]
|
||||
|
||||
record.patient_id.recompute_followers()
|
||||
|
||||
return res
|
||||
|
|
|
|||
|
|
@ -14,12 +14,25 @@ class User(models.Model):
|
|||
inverse="_inverse_accessible_team_ids",
|
||||
)
|
||||
|
||||
@api.depends("groups_id")
|
||||
@api.depends("groups_id", "partner_id", "partner_id.staff_ids", "partner_id.staff_ids.role")
|
||||
def _compute_is_treatment_professional(self):
|
||||
for rec in self:
|
||||
rec.is_treatment_professional = rec.has_group(
|
||||
# Check if user has the security group
|
||||
has_security_group = rec.has_group(
|
||||
"bemade_sports_clinic.group_sports_clinic_treatment_professional"
|
||||
)
|
||||
|
||||
# Check if user is linked to any team staff as head therapist or therapist
|
||||
is_therapist_staff = False
|
||||
if rec.partner_id:
|
||||
staff_records = self.env['sports.team.staff'].sudo().search([
|
||||
('partner_id', '=', rec.partner_id.id),
|
||||
('role', 'in', ['head_therapist', 'therapist'])
|
||||
])
|
||||
is_therapist_staff = bool(staff_records)
|
||||
|
||||
# Set field based on either condition
|
||||
rec.is_treatment_professional = has_security_group or is_therapist_staff
|
||||
|
||||
def _compute_accessible_team_ids(self):
|
||||
for rec in self:
|
||||
|
|
|
|||
|
|
@ -193,26 +193,33 @@ class TeamStaff(models.Model):
|
|||
@api.depends("user_ids", "user_ids.groups_id")
|
||||
def _compute_has_portal_access(self):
|
||||
for rec in self:
|
||||
# Check if the partner has any active users with portal or internal access
|
||||
rec.has_portal_access = (
|
||||
bool(rec.user_ids.filtered(lambda r: r.has_group("base.group_portal")))
|
||||
or bool(rec.user_ids.filtered(lambda r: r.has_group("base.group_user")))
|
||||
or bool(rec.partner_id.signup_token)
|
||||
)
|
||||
|
||||
def action_revoke_portal_access(self):
|
||||
group_portal = self.env.ref("base.group_portal")
|
||||
group_public = self.env.ref("base.group_public")
|
||||
self.user_ids.write(
|
||||
{
|
||||
"groups_id": [
|
||||
Command.unlink(group_portal.id),
|
||||
Command.link(group_public.id),
|
||||
],
|
||||
"active": False,
|
||||
}
|
||||
)
|
||||
# Remove the signup token, so it cannot be used
|
||||
self.partner_id.sudo().signup_token = False
|
||||
# Deactivate the user and remove from portal group
|
||||
if self.user_ids:
|
||||
self.user_ids.write(
|
||||
{
|
||||
"groups_id": [
|
||||
Command.unlink(group_portal.id),
|
||||
Command.link(group_public.id),
|
||||
],
|
||||
"active": False,
|
||||
}
|
||||
)
|
||||
|
||||
# If there's an active signup invitation, cancel it
|
||||
# This uses the portal.wizard from Odoo core to handle all the details
|
||||
if self.partner_id and self.has_portal_access:
|
||||
self.env['res.partner'].sudo().invalidate_model(['signup_valid'])
|
||||
users = self.env['res.users'].sudo().search([('partner_id', '=', self.partner_id.id)])
|
||||
users.write({'active': False})
|
||||
|
||||
def action_grant_portal_access(self):
|
||||
wiz = self.env["portal.wizard"].create(
|
||||
|
|
@ -223,22 +230,110 @@ class TeamStaff(models.Model):
|
|||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
res = super().create(vals_list)
|
||||
|
||||
# Update treatment professional group membership for new records
|
||||
res._update_treatment_professional_group()
|
||||
|
||||
# Recompute the is_treatment_professional field on affected users
|
||||
affected_users = res.mapped('user_ids')
|
||||
if affected_users:
|
||||
affected_users.sudo()._compute_is_treatment_professional()
|
||||
|
||||
# Handle follower recomputation
|
||||
res.team_id.mapped("patient_ids").recompute_followers()
|
||||
return res
|
||||
|
||||
def unlink(self):
|
||||
# Store affected partners and users before deletion
|
||||
affected_partners = self.mapped('partner_id')
|
||||
affected_users = self.mapped('user_ids')
|
||||
|
||||
# Store roles - only therapist roles matter for the update
|
||||
had_therapist_role = self.filtered(lambda s: s.role in ['head_therapist', 'therapist'])
|
||||
therapist_partners = had_therapist_role.mapped('partner_id')
|
||||
|
||||
# Standard processing for follower recomputation
|
||||
patients = self.team_id.mapped("patient_ids")
|
||||
res = super().unlink()
|
||||
patients.recompute_followers()
|
||||
|
||||
# After deletion, check if therapist partners still have any therapist roles
|
||||
# and update their group membership accordingly
|
||||
for partner in therapist_partners:
|
||||
remaining_therapist_roles = self.env['sports.team.staff'].sudo().search_count([
|
||||
('partner_id', '=', partner.id),
|
||||
('role', 'in', ['head_therapist', 'therapist']),
|
||||
])
|
||||
|
||||
if not remaining_therapist_roles:
|
||||
# No therapist roles left, remove from treatment professional group
|
||||
users = self.env['res.users'].sudo().search([('partner_id', '=', partner.id)])
|
||||
treatment_prof_group = self.env.ref('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
||||
for user in users:
|
||||
if user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional'):
|
||||
user.sudo().write({'groups_id': [(3, treatment_prof_group.id)]})
|
||||
|
||||
# Recompute is_treatment_professional on all affected users
|
||||
affected_users.sudo().invalidate_model(['is_treatment_professional'])
|
||||
|
||||
return res
|
||||
|
||||
def _update_treatment_professional_group(self):
|
||||
"""Update treatment professional status based on staff role
|
||||
|
||||
For internal users, this adds them to the treatment professional group.
|
||||
For portal users, we set the flag via recomputation.
|
||||
"""
|
||||
treatment_prof_group = self.env.ref('bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
||||
|
||||
for staff in self:
|
||||
# Skip if partner has no user accounts
|
||||
if not staff.user_ids:
|
||||
continue
|
||||
|
||||
# Check if this partner has any staff records with therapist roles
|
||||
all_staff_records = self.env['sports.team.staff'].sudo().search([
|
||||
('partner_id', '=', staff.partner_id.id),
|
||||
('role', 'in', ['head_therapist', 'therapist'])
|
||||
])
|
||||
|
||||
should_be_treatment_professional = bool(all_staff_records)
|
||||
|
||||
# Update all users linked to this partner
|
||||
for user in staff.user_ids:
|
||||
# Skip changes during module installation to avoid conflicts in demo data
|
||||
if self.env.context.get('module'):
|
||||
continue
|
||||
|
||||
# Always trigger a recomputation of is_treatment_professional
|
||||
user.sudo().invalidate_model(['is_treatment_professional'])
|
||||
|
||||
# For internal users, we can directly manage group membership
|
||||
if user.has_group('base.group_user'):
|
||||
if should_be_treatment_professional and not user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional'):
|
||||
user.sudo().write({'groups_id': [(4, treatment_prof_group.id)]}) # Add to group
|
||||
elif not should_be_treatment_professional and user.has_group('bemade_sports_clinic.group_sports_clinic_treatment_professional'):
|
||||
user.sudo().write({'groups_id': [(3, treatment_prof_group.id)]}) # Remove from group
|
||||
|
||||
def write(self, values):
|
||||
old_roles = {record.id: record.role for record in self}
|
||||
result = super().write(values)
|
||||
|
||||
# If role changed or team changed, handle group membership updates
|
||||
if 'role' in values or 'team_id' in values:
|
||||
self._update_treatment_professional_group()
|
||||
|
||||
# Recompute the `is_treatment_professional` field on affected users
|
||||
affected_users = self.mapped('user_ids')
|
||||
if affected_users:
|
||||
affected_users.sudo()._compute_is_treatment_professional()
|
||||
|
||||
# Handle team changes for follower recomputation
|
||||
if "team_id" in values:
|
||||
to_recompute = self.env["sports.patient"]
|
||||
for rec in self:
|
||||
if rec.team_id.id != values["team_id"]:
|
||||
to_recompute |= rec.team_id.patient_ids
|
||||
res = super().write(values)
|
||||
to_recompute.recompute_followers()
|
||||
return res
|
||||
return super().write(values)
|
||||
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -11,3 +11,4 @@ access_team_admin,Admin Access for Teams,model_sports_team,group_sports_clinic_a
|
|||
access_team_portal,Portal Access for Teams,model_sports_team,base.group_portal,1,0,0,0
|
||||
access_team_staff_user,User Access for Team Staff,model_sports_team_staff,group_sports_clinic_user,1,1,1,1
|
||||
access_team_staff_portal,Portal Access for Team Staff,model_sports_team_staff,base.group_portal,1,0,0,0
|
||||
access_team_staff_admin,Admin Access for Team Staff,model_sports_team_staff,group_sports_clinic_admin,1,1,1,1
|
||||
|
|
|
|||
|
|
|
@ -19,13 +19,14 @@
|
|||
<record id="group_sports_clinic_treatment_professional" model="res.groups">
|
||||
<field name="name">Treatment Professional</field>
|
||||
<field name="category_id" ref="module_category_sports_clinic_management"/>
|
||||
<field name="implied_ids" eval="[Command.link(ref('group_sports_clinic_user'))]"/>
|
||||
<!-- No implied_ids to allow both internal and portal treatment professionals -->
|
||||
</record>
|
||||
<record id="group_sports_clinic_admin" model="res.groups">
|
||||
<field name="name">Administrator</field>
|
||||
<field name="category_id" ref="module_category_sports_clinic_management"/>
|
||||
<field name="implied_ids"
|
||||
eval="[Command.link(ref('group_sports_clinic_treatment_professional'))]"/>
|
||||
eval="[Command.link(ref('group_sports_clinic_user')),
|
||||
Command.link(ref('group_sports_clinic_treatment_professional'))]"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from . import test_patient
|
||||
from . import test_rights
|
||||
from . import test_users
|
||||
from . import test_portal_access
|
||||
from . import test_treatment_professional_consistency
|
||||
|
|
|
|||
|
|
@ -1,14 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<!-- Add Sports Clinic security groups to the user form access rights section -->
|
||||
<record id="view_users_form_inherit" model="ir.ui.view">
|
||||
<field name="name">view.users.form.inherit</field>
|
||||
<field name="inherit_id" ref="base.view_users_form"/>
|
||||
<field name="model">res.users</field>
|
||||
<field name="arch" type="xml">
|
||||
<!-- Add the existing page for team access -->
|
||||
<page name="preferences" position="before">
|
||||
<page name="Sports Team Access"
|
||||
<page name="sports_team_access" string="Sports Team Access"
|
||||
groups="base.group_system,bemade_sports_clinic.group_sports_clinic_admin">
|
||||
<field name="accessible_team_ids" widget="many2many_checkboxes"/>
|
||||
<group>
|
||||
<field name="accessible_team_ids" widget="many2many_checkboxes"/>
|
||||
</group>
|
||||
</page>
|
||||
</page>
|
||||
|
||||
<!-- Add a dedicated page for Sports Clinic permissions -->
|
||||
<page name="access_rights" position="after">
|
||||
<page name="sports_clinic_access" string="Sports Clinic Access Rights" groups="base.group_system">
|
||||
<group>
|
||||
<field name="groups_id" widget="many2many_checkboxes"
|
||||
domain="[('category_id','=',ref('bemade_sports_clinic.module_category_sports_clinic_management'))]"
|
||||
readonly="0" nolabel="1"/>
|
||||
</group>
|
||||
</page>
|
||||
</page>
|
||||
</field>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
<record id="action_view_organization" model="ir.actions.act_window">
|
||||
<field name="name">Organizations</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="domain">[('is_company', '=', True)]</field>
|
||||
</record>
|
||||
<record id="action_view_patient" model="ir.actions.act_window">
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@
|
|||
<span t-field="injury.diagnosis" class="text-wrap"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-raw="injury.external_notes" class="text-wrap"/>
|
||||
<span t-out="injury.external_notes" class="text-wrap"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
<group>
|
||||
<group col="2">
|
||||
<field name="patient_id" invisible="1"/>
|
||||
<field name="team_id"/>
|
||||
<span colspan="2">
|
||||
<label for="injury_date"/>
|
||||
<field name="injury_date" widget="date" class="oe_inline"/>
|
||||
|
|
@ -37,22 +38,19 @@
|
|||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="activity_ids" widget="mail_activity"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
<chatter reload_on_post="True"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="sports_patient_injury_view_tree" model="ir.ui.view">
|
||||
<field name="name">sports.patient.injury.view.tree</field>
|
||||
<record id="sports_patient_injury_view_list" model="ir.ui.view">
|
||||
<field name="name">sports.patient.injury.view.list</field>
|
||||
<field name="model">sports.patient.injury</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Patient Injury History" editable="bottom"
|
||||
multi_edit="True">
|
||||
<field name="patient_id" invisible="1"/>
|
||||
<field name="patient_id" column_invisible="True"/>
|
||||
<field name="injury_date" widget="date"/>
|
||||
<field name="team_id"/>
|
||||
<field name="diagnosis"/>
|
||||
<field name="predicted_resolution_date" widget="date"/>
|
||||
<field name="resolution_date" widget="date"/>
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@
|
|||
<field name="return_date" widget="date"/>
|
||||
<field name="activity_ids" widget="list_activity"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<t t-name="card">
|
||||
<t t-set="stage" t-value="record.stage.raw_value"/>
|
||||
<div t-attf-class="oe_kanban_global_click
|
||||
{{stage === 'no_play' ? 'text-danger' : stage === 'practice_ok' ? 'text-warning' : ''}}">
|
||||
|
|
@ -114,7 +114,14 @@
|
|||
<field name="stage" widget="statusbar" />
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box"></div>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_report_injury" type="object" class="oe_stat_button" icon="fa-medkit">
|
||||
<div class="o_stat_info">
|
||||
<span class="o_stat_text">Report</span>
|
||||
<span class="o_stat_text">Injury</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title"><h1>Patient Record</h1></div>
|
||||
<group>
|
||||
<group col="3">
|
||||
|
|
@ -176,11 +183,7 @@
|
|||
</notebook>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="activity_ids" widget="mail_activity"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
<chatter reload_on_post="True"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
<field name="injured_count"/>
|
||||
<field name="healthy_count"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<t t-name="card">
|
||||
<div t-attf-class="oe_kanban_content oe_kanban_global_click">
|
||||
<div>
|
||||
<strong class="o_kanban_record_title">
|
||||
|
|
@ -110,8 +110,8 @@
|
|||
<field name="name"/>
|
||||
<field name="role"/>
|
||||
<field name="mobile" widget="phone"/>
|
||||
<field invisible="1" name="has_portal_access"/>
|
||||
<field invisible="1" name="partner_id"/>
|
||||
<field column_invisible="True" name="has_portal_access"/>
|
||||
<field column_invisible="True" name="partner_id"/>
|
||||
<button class="oe_highlight" groups="bemade_sports_clinic.group_sports_clinic_admin,base.group_system" icon="fa-user-plus" invisible="has_portal_access == True" name="action_grant_portal_access" title="Grant Portal Access" type="object"/>
|
||||
<button class="oe_highlight" groups="bemade_sports_clinic.group_sports_clinic_admin,base.group_system" icon="fa-ban" invisible="has_portal_access == False" name="action_revoke_portal_access" title="Revoke Portal Access" type="object"/>
|
||||
</list></field>
|
||||
|
|
@ -120,7 +120,7 @@
|
|||
<notebook>
|
||||
<page name="players" string="Players">
|
||||
<field name="patient_ids" nolabel="1"
|
||||
context="{'tree_view_ref': 'bemade_sports_clinic.sports_patient_view_list_embedded'}"/>
|
||||
context="{'list_view_ref': 'bemade_sports_clinic.sports_patient_view_list_embedded'}"/>
|
||||
</page>
|
||||
<page name="user_access"
|
||||
string="User Access"
|
||||
|
|
@ -129,11 +129,7 @@
|
|||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="activity_ids" widget="mail_activity"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
<chatter reload_on_post="True"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
|||
Loading…
Reference in a new issue