Merge branch '16.0' of github.com:Dur-Pro/bemade-addons into 16.0

This commit is contained in:
Benoît Vézina 2023-11-20 09:34:03 -05:00
commit b2555b6bca
6 changed files with 148 additions and 37 deletions

View file

@ -28,14 +28,14 @@ class TeamStaffPortal(CustomerPortal):
('team_ids', 'in', team_ids),
]
@http.route(route=['/my/teams'], type='http', auth='user', website=True)
@http.route(route=['/my/teams', '/my/teams/page/<int:page>'], type='http', auth='user', website=True)
def view_teams(self, page=0, **kw):
""" Display the list of teams that a portal user has access to """
Teams = http.request.env['sports.team']
domain = self._prepare_teams_domain()
teams_count = Teams.search_count(domain)
pgr = pager(url='/my/teams', total=teams_count,
page=page, step=10, scope=10)
page=page, step=10, scope=5)
teams = http.request.env['sports.team'].search(self._prepare_teams_domain(),
offset=pgr['offset'],
limit=teams_count)
@ -47,7 +47,7 @@ class TeamStaffPortal(CustomerPortal):
'page_name': 'my_teams',
})
@http.route(route=['/my/team/<int:team_id>'], type='http', auth='user', website=True)
@http.route(route=['/my/team/<int:team_id>', '/my/team/<int:team_id>/page/<int:page>'], type='http', auth='user', website=True)
def view_team(self, team_id, page=0, **kw):
""" Display the information for a team including its list of players """
team = http.request.env['sports.team'].browse(team_id)
@ -55,7 +55,7 @@ class TeamStaffPortal(CustomerPortal):
raise UserError(_('This team could not be found.'))
players_count = team.player_count
pgr = pager(url=f'/my/team/{team_id}', total=players_count, page=page, step=10,
scope=10)
scope=5)
players = http.request.env['sports.patient'].search([
('team_ids', 'in', team_id),
], offset=pgr['offset'], limit=players_count)
@ -70,13 +70,13 @@ class TeamStaffPortal(CustomerPortal):
}
)
@http.route(route=['/my/players'], type='http', auth='user', website=True)
@http.route(route=['/my/players', '/my/players/page/<int:page>'], type='http', auth='user', website=True)
def view_players(self, page=0, **kw):
""" Display the list of players that the portal user has access to """
teams_domain = self._prepare_teams_domain()
players_domain = self._prepare_players_domain(teams_domain)
players_count = http.request.env['sports.patient'].search_count(players_domain)
pgr = pager(url='/my/players', total=players_count, page=page, step=10, scope=10)
pgr = pager(url='/my/players', total=players_count, page=page, step=10, scope=5)
players = http.request.env['sports.patient'].search(players_domain,
offset=pgr['offset'],
limit=players_count)

View file

@ -130,7 +130,7 @@
<field name="practice_status">yes</field>
</record>
<record id="injury_1" model="sports.patient.injury">
<field name="injury_date_time">2023-05-17 18:53:00</field>
<field name="injury_date">2023-05-17</field>
<field name="diagnosis">Fracture du fémur</field>
<field name="predicted_resolution_date">2024-02-01</field>
<field name="patient_id" ref="patient_1"/>
@ -138,7 +138,7 @@
eval="[Command.set([ref('base.user_admin')])]"/>
</record>
<record id="injury_2" model="sports.patient.injury">
<field name="injury_date_time">2022-03-17 19:13:00</field>
<field name="injury_date">2022-03-17</field>
<field name="diagnosis">Entorse cheville droite</field>
<field name="predicted_resolution_date">2022-03-23</field>
<field name="patient_id" ref="patient_1"/>
@ -146,7 +146,7 @@
eval="[Command.set([ref('base.user_admin')])]"/>
</record>
<record id="injury_3" model="sports.patient.injury">
<field name="injury_date_time">2023-10-15 19:55:00</field>
<field name="injury_date">2023-10-15</field>
<field name="diagnosis">Commotion cérébrale mineure</field>
<field name="predicted_resolution_date">2023-11-01</field>
<field name="patient_id" ref="patient_3"/>

View file

@ -1,7 +1,8 @@
from odoo import models, fields, _, api, Command
from odoo.exceptions import ValidationError
from datetime import date, datetime
from datetime import date
from dateutil.relativedelta import relativedelta
from odoo.addons.phone_validation.tools import phone_validation
class Patient(models.Model):
@ -10,20 +11,28 @@ class Patient(models.Model):
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'last_name, first_name'
# res.partner fields
partner_id = fields.Many2one(comodel_name='res.partner', string='Contact', ondelete='restrict', compute_sudo=True)
first_name = fields.Char(required=True, tracking=True)
last_name = fields.Char(required=True, tracking=True)
name = fields.Char(compute="_compute_name")
name = fields.Char(related='partner_id.name', compute="_compute_name", compute_sudo=True)
phone = fields.Char(related='partner_id.phone', readonly=False)
mobile = fields.Char(related='partner_id.mobile', readonly=False)
street = fields.Char(related='partner_id.street', readonly=False)
street2 = fields.Char(related='partner_id.street2', readonly=False)
city = fields.Char(related='partner_id.city', readonly=False)
state_id = fields.Many2one(related='partner_id.state_id', readonly=False)
zip = fields.Char(related='partner_id.zip', readonly=False)
country_id = fields.Many2one(related='partner_id.country_id', readonly=False)
email = fields.Char(related='partner_id.email', readonly=False)
# Patient fields
date_of_birth = fields.Date(
groups="bemade_sports_clinic.group_sports_clinic_treatment_professional",
tracking=True)
age = fields.Integer(compute='_compute_age',
groups="bemade_sports_clinic.group_sports_clinic_treatment_professional",
tracking=True)
mobile = fields.Char(unaccent=False,
groups="bemade_sports_clinic.group_sports_clinic_user",
tracking=True)
email = fields.Char(groups="bemade_sports_clinic.group_sports_clinic_user",
tracking=True)
contact_ids = fields.One2many(comodel_name='sports.patient.contact',
inverse_name='patient_id',
string='Patient Contacts',
@ -56,6 +65,8 @@ class Patient(models.Model):
compute='_compute_stage')
last_consultation_date = fields.Date()
active_injury_count = fields.Integer(compute='_compute_active_injury_count')
allergies = fields.Text()
team_info_notes = fields.Html(string="Notes")
def default_get(self, fields_list):
res = super().default_get(fields_list)
@ -67,6 +78,15 @@ class Patient(models.Model):
res.update({'team_ids': team_ids})
return res
@api.model_create_multi
def create(self, vals_list):
for row in vals_list:
if 'partner_id' not in row:
row['partner_id'] = self.env['res.partner'].create({
'name': self._get_name_from_first_and_last(row['first_name'], row['last_name'])
}).id
return super().create(vals_list)
@api.constrains('match_status', 'practice_status')
def constrain_match_and_practice_status(self):
""" Avoid invalid combinations of match and practice status:
@ -109,16 +129,19 @@ class Patient(models.Model):
@api.depends('first_name', 'last_name')
def _compute_name(self):
for rec in self:
rec.name = ((rec.first_name or "") + " " + (rec.last_name or
"")).strip()
rec.name = self._get_name_from_first_and_last(rec.first_name, rec.last_name)
@api.depends('practice_status', 'match_status', 'injury_ids.injury_date_time')
@api.model
def _get_name_from_first_and_last(self, first_name, last_name):
return ((first_name or "") + " " + (last_name or "")).strip()
@api.depends('practice_status', 'match_status', 'injury_ids.injury_date')
def _compute_is_injured(self):
for rec in self:
rec.is_injured = rec.practice_status != 'yes' or rec.match_status != 'yes'
if rec.is_injured:
unresolved_injuries = rec.injury_ids.filtered(lambda r: not r.stage == 'resolved')
rec.injured_since = unresolved_injuries and unresolved_injuries[0].injury_date_time
rec.injured_since = unresolved_injuries and unresolved_injuries[0].injury_date
else:
rec.injured_since = False
@ -142,6 +165,28 @@ class Patient(models.Model):
'res_id': self.id,
}
@api.onchange('mobile', 'country_id')
def _onchange_mobile_validation(self):
if self.mobile:
self.mobile = self._phone_format(self.mobile, force_format="INTERNATIONAL")
@api.onchange('phone', 'country_id')
def _onchange_phone_validation(self):
if self.phone:
self.phone = self._phone_format(self.phone, force_format="INTERNATIONAL")
def _phone_format(self, number, force_format='E164'):
country = self.country_id or self.env.company.country_id
if not country or not number:
return number
return phone_validation.phone_format(
number,
country.code if country else None,
country.phone_code if country else None,
force_format=force_format,
raise_exception=False
)
class PatientContact(models.Model):
_name = 'sports.patient.contact'
@ -157,6 +202,23 @@ class PatientContact(models.Model):
mobile = fields.Char(unaccent=False, required=True)
patient_id = fields.Many2one(comodel_name='sports.patient', string='Patient')
@api.onchange('mobile')
def _onchange_mobile_validation(self):
if self.mobile:
self.mobile = self._phone_format(self.mobile, force_format="INTERNATIONAL")
def _phone_format(self, number, force_format='E164'):
country = self.patient_id.country_id or self.env.company.country_id
if not country or not number:
return number
return phone_validation.phone_format(
number,
country.code if country else None,
country.phone_code if country else None,
force_format=force_format,
raise_exception=False
)
class PatientInjury(models.Model):
_name = 'sports.patient.injury'
@ -170,15 +232,15 @@ class PatientInjury(models.Model):
required=True)
patient_name = fields.Char(related="patient_id.name")
diagnosis = fields.Char(tracking=True)
injury_date_time = fields.Datetime(string='Date and Time of Injury', required=True,
default=datetime.now())
injury_date = fields.Date(string='Date and Time of Injury',
default=date.today())
injury_date_na = fields.Boolean(string="N/A", default=False)
internal_notes = fields.Html(tracking=True)
external_notes = fields.Html(tracking=True)
treatment_professional_ids = fields.Many2many(comodel_name='res.users',
relation='patient_injury_treatment_pro_rel',
column1='patient_injury_id',
column2='treatment_pro_id',
string='Treatment Professionals',
column2='treatment_pro_id', string='Treatment Professionals',
domain=[
('is_treatment_professional', '=',
True)], tracking=True)
@ -187,6 +249,24 @@ class PatientInjury(models.Model):
help="The date when the injury was actually resolved.")
stage = fields.Selection(selection=[('active', 'Active'), ('resolved', 'Resolved')], compute='_compute_stage')
@api.constrains('injury_date_na', 'injury_date')
def constrain_date_blank_only_if_na(self):
for rec in self:
if not rec.injury_date_na and not rec.injury_date:
raise ValidationError(_("If injury date is not set, the N/A box must be checked."))
@api.onchange('injury_date_na')
def _onchange_injury_date_na(self):
for rec in self:
if rec.injury_date_na:
rec.injury_date = None
@api.onchange('injury_date')
def _onchange_injury_date(self):
for rec in self:
if rec.injury_date:
rec.injury_date_na = False
@api.depends('resolution_date')
def _compute_stage(self):
for rec in self:

View file

@ -1,5 +1,6 @@
from odoo import models, fields, api, _
from odoo.exceptions import UserError
from odoo.exceptions import ValidationError
class Partner(models.Model):
@ -14,6 +15,12 @@ class Partner(models.Model):
string='Teams Served',
help='The teams this person works for.')
teams_served_ids = fields.One2many(comodel_name='sports.team', compute='_compute_teams_served')
patient_ids = fields.One2many(comodel_name='sports.patient', inverse_name='partner_id')
def write(self, vals):
if self.patient_ids and 'name' in vals:
raise ValidationError(_("To change a patient's name, change it from the patient form."))
return super().write(vals)
@api.depends('team_staff_rel_ids.team_id')
def _compute_teams_served(self):

View file

@ -75,6 +75,7 @@ class TeamStaff(models.Model):
_sql_constraints = [('team_staff_unique', 'unique(team_id, partner_id)',
'Each partner can only be related to a given team once.')]
@api.constrains('role')
def _constrain_role(self):
teams = self.mapped('team_id')

View file

@ -82,11 +82,11 @@
<field name="age" colspan="3"/>
<label for="last_consultation_date" colspan="1"/>
<span colspan="2">
<field name="last_consultation_date" widget="date" class="oe_inline"/>
<field name="last_consultation_date" widget="date" class="oe_inline"/>
<button type="object" name="action_consulted_today"
class="fa fa-refresh" title="Set to Today's Date"/>
</span>
<field name="allergies"/>
</group>
<group>
<separator string="Team Information"/>
@ -96,21 +96,39 @@
<field name="practice_status"/>
<field name="predicted_return_date"/>
<field name="return_date"/>
<field name="team_info_notes"/>
</group>
<notebook>
<page string="Injuries">
<field name="injury_ids"/>
</page>
<page string="Contacts">
<field name="contact_ids">
<tree string="Patient's Contacts"
multi_edit="1" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="contact_type"/>
<group>
<group string="Patient Phone &amp; Email">
<field name="phone" widget="phone"/>
<field name="mobile" widget="phone"/>
</tree>
</field>
<field name="email" widget="email"/>
</group>
<group string="Patient Address">
<field name="street"/>
<field name="street2"/>
<field name="city"/>
<field name="state_id"/>
<field name="country_id"/>
<field name="zip"/>
</group>
</group>
<group string="Other Contacts">
<field name="contact_ids">
<tree string="Patient's Contacts"
multi_edit="1" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="contact_type"/>
<field name="mobile" widget="phone"/>
</tree>
</field>
</group>
</page>
</notebook>
</group>
@ -139,9 +157,14 @@
</h1>
</div>
<group>
<group>
<group col="2">
<field name="patient_id" invisible="1"/>
<field name="injury_date_time"/>
<span colspan="2">
<label for="injury_date"/>
<field name="injury_date" widget="date" class="oe_inline"/>
<field name="injury_date_na" class="oe_inline"/>
<label for="injury_date_na"/>
</span>
<field name="diagnosis"/>
<field name="predicted_resolution_date"/>
<field name="resolution_date"/>
@ -169,7 +192,7 @@
<tree string="Patient Injury History" editable="bottom"
multi_edit="True">
<field name="patient_id" invisible="1"/>
<field name="injury_date_time" widget="datetime"/>
<field name="injury_date" widget="date"/>
<field name="diagnosis"/>
<field name="predicted_resolution_date" widget="date"/>
<field name="resolution_date" widget="date"/>