Added a bunch of stuff for bemade_sports_clinic
This commit is contained in:
parent
f0034ac447
commit
a37acac519
11 changed files with 241 additions and 13 deletions
|
|
@ -38,7 +38,14 @@
|
|||
'website': 'https://www.bemade.org',
|
||||
'license': 'OPL-1',
|
||||
'depends': ['base', 'mail'],
|
||||
'data': [],
|
||||
'data': [
|
||||
'security/sports_clinic_groups.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'security/sports_clinic_rules.xml',
|
||||
'views/res_partner_views.xml',
|
||||
'views/sports_clinic_menus.xml',
|
||||
'views/patient_views.xml',
|
||||
],
|
||||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
from . import patient
|
||||
from . import sports_team
|
||||
from . import res_partner
|
||||
|
|
|
|||
|
|
@ -6,15 +6,21 @@ from dateutil import relativedelta
|
|||
|
||||
class Patient(models.Model):
|
||||
_name = 'sports.patient'
|
||||
_description = "Patient at a sports medicine clinic."
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
|
||||
first_name = fields.Char(required=True)
|
||||
last_name = fields.Char(required=True)
|
||||
date_of_birth = fields.Date()
|
||||
age = fields.Integer(compute='_compute_age')
|
||||
phone = fields.Char(unaccent=False)
|
||||
email = fields.Char()
|
||||
date_of_birth = fields.Date(
|
||||
groups="bemade_sports_clinic.group_sports_clinic_treatment_professional")
|
||||
age = fields.Integer(compute='_compute_age',
|
||||
groups="bemade_sports_clinic.group_sports_clinic_treatment_professional")
|
||||
phone = fields.Char(unaccent=False,
|
||||
groups="bemade_sports_clinic.group_sports_clinic_user")
|
||||
email = fields.Char(groups="bemade_sports_clinic.group_sports_clinic_user")
|
||||
contact_ids = fields.One2many(comodel_name='sports.patient.contact',
|
||||
inverse_name='patient_id', string='Patient Contacts', )
|
||||
inverse_name='patient_id', string='Patient Contacts',
|
||||
groups="bemade_sports_clinic.group_sports_clinic_user")
|
||||
team_ids = fields.Many2many(comodel_name='res.partner',
|
||||
relation='sports_team_patient_rel',
|
||||
column1='patient_id',
|
||||
|
|
@ -27,15 +33,27 @@ class Patient(models.Model):
|
|||
])
|
||||
injury_ids = fields.One2many(comodel_name='sports.patient.injury',
|
||||
inverse_name='patient_id',
|
||||
string='Injuries')
|
||||
predicted_return_date = fields.Date(compute='_compute_predicted_return_date')
|
||||
string='Injuries',
|
||||
groups='bemade_sports_clinic.group_sports_clinic_treatment_professional')
|
||||
predicted_return_date = fields.Date(compute='_compute_predicted_return_date', )
|
||||
# authorized_users = fields.One2many(compute='_compute_authorized_users', store=True)
|
||||
#
|
||||
# @api.depends('injury_ids.treatment_professional_ids', 'team_ids.staff_team_ids',
|
||||
# 'message_follower_ids')
|
||||
# def _compute_authorized_users(self):
|
||||
# for rec in self:
|
||||
# auth_users = self.env['res.users'].search(['|', ('partner_id', 'in',
|
||||
# rec.injury_ids.mapped('treatment_professional_ids').ids),
|
||||
# '|', ('partner_id', 'in', rec.team_ids.mapped('staff_team_ids').ids),
|
||||
# ('partner_id', 'in', rec.message_follower_ids.ids)])
|
||||
|
||||
@api.depends('date_of_birth')
|
||||
def _compute_age(self):
|
||||
for rec in self:
|
||||
if not rec.date_of_birth:
|
||||
rec.age = False
|
||||
rec.age = relativedelta(date.today() - rec.date_of_birth).years
|
||||
else:
|
||||
rec.age = relativedelta(date.today() - rec.date_of_birth).years
|
||||
|
||||
@api.depends('injury_ids.predicted_return_date')
|
||||
def _compute_predicted_return_date(self):
|
||||
|
|
@ -51,6 +69,7 @@ class Patient(models.Model):
|
|||
|
||||
class PatientContact(models.Model):
|
||||
_name = 'sports.patient.contact'
|
||||
_description = "Emergency or other contacts for a patient."
|
||||
|
||||
sequence = fields.Integer(required=True, default=0)
|
||||
name = fields.Char(unaccent=False)
|
||||
|
|
@ -65,7 +84,9 @@ class PatientContact(models.Model):
|
|||
|
||||
class PatientInjury(models.Model):
|
||||
_name = 'sports.patient.injury'
|
||||
_description = "A patient's injury."
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
|
||||
patient_id = fields.Many2one(comodel_name='sports.patient', string="Patient")
|
||||
diagnosis = fields.Char(tracking=True)
|
||||
injury_date_time = fields.Datetime(string='Date and Time of Injury')
|
||||
|
|
|
|||
|
|
@ -11,18 +11,25 @@ class Partner(models.Model):
|
|||
column2='patient_id',
|
||||
string='Players')
|
||||
type = fields.Selection(selection_add=[('team', 'Sports Team'),
|
||||
('treatment_pro', 'Treatment Professional'),])
|
||||
('treatment_pro', 'Treatment Professional'),
|
||||
])
|
||||
staff_partner_ids = fields.Many2many(comodel_name='res.partner',
|
||||
relation='sports_team_staff_partner_rel',
|
||||
column1='team_id',
|
||||
column2='staff_partner_id',
|
||||
string='Staff')
|
||||
staff_team_ids = fields.Many2many(comodel_name='res.partner',
|
||||
relation='sports_team_staff_partner_rel',
|
||||
column1='staff_partner_id',
|
||||
column2='team_id',
|
||||
string='Teams')
|
||||
|
||||
def write(self, vals):
|
||||
# Override to validate changes to the 'type' field
|
||||
treatment_pros = self.filtered(lambda r: r.type == 'treatment_pro')
|
||||
if treatment_pros and 'type' in vals and vals['type'] != 'treatment_pro':
|
||||
injuries = self.env['sports.patient.injury'].search_count([('treatment_professional_ids', 'in', treatment_pros.ids)])
|
||||
injuries = self.env['sports.patient.injury'].search_count(
|
||||
[('treatment_professional_ids', 'in', treatment_pros.ids)])
|
||||
if injuries:
|
||||
raise UserError(_('Partner type cannot be changed since this treatment '
|
||||
'professional appears on a patient injury record.'))
|
||||
|
|
@ -37,7 +44,8 @@ class Partner(models.Model):
|
|||
def unlink(self):
|
||||
treatment_pros = self.filtered(lambda r: r.type == 'treatment_pro')
|
||||
if treatment_pros:
|
||||
injuries = self.env['sports.patient.injury'].search_count([('treatment_professional_ids', 'in', treatment_pros.ids)])
|
||||
injuries = self.env['sports.patient.injury'].search_count(
|
||||
[('treatment_professional_ids', 'in', treatment_pros.ids)])
|
||||
if injuries:
|
||||
raise UserError(_('Treatment professional cannot be deleted since they '
|
||||
'appears on a patient injury record.'))
|
||||
|
|
|
|||
8
bemade_sports_clinic/security/ir.model.access.csv
Normal file
8
bemade_sports_clinic/security/ir.model.access.csv
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_patient_user,User Access for Patients,model_sports_patient,group_sports_clinic_user,1,1,1,0
|
||||
access_patient_treatment_pro,Treatment Professional Access for Patients,model_sports_patient,group_sports_clinic_treatment_professional,1,1,1,1
|
||||
access_patient_admin,Admin Access for Patients,model_sports_patient,group_sports_clinic_admin,1,1,1,1
|
||||
access_patient_portal,Portal Access for Patients,model_sports_patient,base.group_portal,1,1,1,0
|
||||
access_patient_contact_user,User Access for Patient Contacts,model_sports_patient_contact,group_sports_clinic_user,1,1,1,1
|
||||
access_injury_treatment_pro,Treatment Professional Access for Injuries,model_sports_patient_injury,group_sports_clinic_treatment_professional,1,1,1,1
|
||||
access_injury_portal,Portal Access for Injuries,model_sports_patient_injury,base.group_portal,1,0,0,0
|
||||
|
23
bemade_sports_clinic/security/sports_clinic_groups.xml
Normal file
23
bemade_sports_clinic/security/sports_clinic_groups.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="module_category_sports_clinic_management" model="ir.module.category">
|
||||
<field name="name">Sports Medicine Clinic Management</field>
|
||||
</record>
|
||||
<record id="group_sports_clinic_user" model="res.groups">
|
||||
<field name="name">Internal User</field>
|
||||
<field name="category_id" ref="module_category_sports_clinic_management"/>
|
||||
</record>
|
||||
<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="[(4, ref('group_sports_clinic_user'))]"/>
|
||||
</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="[(4, ref('group_sports_clinic_treatment_professional'))]"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
23
bemade_sports_clinic/security/sports_clinic_rules.xml
Normal file
23
bemade_sports_clinic/security/sports_clinic_rules.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<!-- Refuse access to patient records that are not part of staff user's teams -->
|
||||
<record id="restrict_team_access_to_team_players" model="ir.rule">
|
||||
<field name="name">Restrict Team Staff Access to Their Players Only</field>
|
||||
<field name="model_id" ref="model_sports_patient"/>
|
||||
<field name="groups" eval="[4, ref('base.group_portal')]"/>
|
||||
<field name="domain_force">
|
||||
[('id', 'in', user.partner_id.staff_team_ids.mapped('patient_ids').ids)]
|
||||
</field>
|
||||
</record>
|
||||
<!-- Patient injury records should be on invitation only for non-admins -->
|
||||
<record id="restrict_patient_access_to_treatment_professionals" model="ir.rule">
|
||||
<field name="name">Access patient injury records on invitation only</field>
|
||||
<field name="model_id" ref="model_sports_patient_injury"/>
|
||||
<field name="groups" eval="[(6, 0, [ref('group_sports_clinic_user'), ref('group_sports_clinic_treatment_professional')])]"/>
|
||||
<field name="domain_force">
|
||||
[('message_follower_ids', 'in', user.partner_id.ids)]
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
BIN
bemade_sports_clinic/static/description/icon.png
Normal file
BIN
bemade_sports_clinic/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
67
bemade_sports_clinic/views/patient_views.xml
Normal file
67
bemade_sports_clinic/views/patient_views.xml
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="sports_patient_view_search" model="ir.ui.view">
|
||||
<field name="name">sports.patient.view.search</field>
|
||||
<field name="model">sports.patient</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="first_name"/>
|
||||
<field name="last_name"/>
|
||||
<field name="team_ids"/>
|
||||
<field name="date_of_birth" widget="date"/>
|
||||
<field name="email" widget="email"/>
|
||||
<field name="phone" widget="phone"/>
|
||||
<filter name="groupby_team_ids" context="{'group_by': 'team_ids'}"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="sports_patient_view_list" model="ir.ui.view">
|
||||
<field name="name">sports.patient.view.list</field>
|
||||
<field name="model">sports.patient</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Patients">
|
||||
<field name="first_name"/>
|
||||
<field name="last_name"/>
|
||||
<field name="date_of_birth"/>
|
||||
<field name="age"/>
|
||||
<field name="team_ids" widget="many2many_tags"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="sports_patient_view_form" model="ir.ui.view">
|
||||
<field name="name">sports.patient.view.form</field>
|
||||
<field name="model">sports.patient</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header></header>
|
||||
<sheet>
|
||||
<div class="oe_button_box"></div>
|
||||
<div class="oe_title"><h1>Patient Record</h1></div>
|
||||
<group>
|
||||
<group>
|
||||
<separator string="Patient Information"/>
|
||||
<field name="first_name"/>
|
||||
<field name="last_name"/>
|
||||
<field name="date_of_birth"/>
|
||||
<field name="age"/>
|
||||
</group>
|
||||
<group>
|
||||
<separator string="Team Information"/>
|
||||
<field name="team_ids"
|
||||
widget="many2many_tags"/>
|
||||
<field name="player_status"/>
|
||||
<field name="predicted_return_date"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Injuries">
|
||||
<field name="injury_ids"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
16
bemade_sports_clinic/views/res_partner_views.xml
Normal file
16
bemade_sports_clinic/views/res_partner_views.xml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="teams_view_search" model="ir.ui.view">
|
||||
<field name="name">teams.view.search</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="parent_id" string="Parent Organization"/>
|
||||
<field name="staff_partner_ids"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
55
bemade_sports_clinic/views/sports_clinic_menus.xml
Normal file
55
bemade_sports_clinic/views/sports_clinic_menus.xml
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="action_view_team" model="ir.actions.act_window">
|
||||
<field name="name">Sports Teams</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="domain">[('type', '=', 'team')]</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="search_view_id" ref="teams_view_search"/>
|
||||
</record>
|
||||
<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">list,kanban,form</field>
|
||||
<field name="domain">[('is_company','=', True)]</field>
|
||||
</record>
|
||||
<record id="action_view_patient" model="ir.actions.act_window">
|
||||
<field name="name">Patients</field>
|
||||
<field name="res_model">sports.patient</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
</record>
|
||||
<record id="action_view_treatment_pros" model="ir.actions.act_window">
|
||||
<field name="name">Treatment Professionals</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="domain">[('type', '=', 'treatment_pro')]</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
</record>
|
||||
<menuitem id="sports_clinic_root"
|
||||
web_icon="bemade_sports_clinic,static/description/icon.png"
|
||||
name="Sports Clinic"
|
||||
groups="bemade_sports_clinic.group_sports_clinic_user"
|
||||
action="action_view_team">
|
||||
<menuitem id="sports_clinic_clients"
|
||||
name="Contacts"
|
||||
groups="bemade_sports_clinic.group_sports_clinic_user">
|
||||
<menuitem id="sports_clinic_organizations"
|
||||
name="Organizations"
|
||||
groups="bemade_sports_clinic.group_sports_clinic_user"
|
||||
action="action_view_organization"/>
|
||||
<menuitem id="sports_clinic_teams"
|
||||
name="Teams"
|
||||
groups="bemade_sports_clinic.group_sports_clinic_user"
|
||||
action="action_view_team"/>
|
||||
<menuitem id="sports_clinic_patients"
|
||||
name="Patients"
|
||||
groups="bemade_sports_clinic.group_sports_clinic_user"
|
||||
action="action_view_patient"/>
|
||||
</menuitem>
|
||||
<menuitem id="sports_clinic_treatment_pros"
|
||||
name="Treatment Professionals"
|
||||
groups="bemade_sports_clinic.group_sports_clinic_user"
|
||||
action="action_view_treatment_pros"/>
|
||||
</menuitem>
|
||||
</data>
|
||||
</odoo>
|
||||
Loading…
Reference in a new issue