diff --git a/bemade_sports_clinic/__manifest__.py b/bemade_sports_clinic/__manifest__.py index cc6348f..84cb080 100644 --- a/bemade_sports_clinic/__manifest__.py +++ b/bemade_sports_clinic/__manifest__.py @@ -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, diff --git a/bemade_sports_clinic/models/__init__.py b/bemade_sports_clinic/models/__init__.py index 977ec36..06a6a51 100644 --- a/bemade_sports_clinic/models/__init__.py +++ b/bemade_sports_clinic/models/__init__.py @@ -1,2 +1,2 @@ from . import patient -from . import sports_team +from . import res_partner diff --git a/bemade_sports_clinic/models/patient.py b/bemade_sports_clinic/models/patient.py index b129111..ef5e0b7 100644 --- a/bemade_sports_clinic/models/patient.py +++ b/bemade_sports_clinic/models/patient.py @@ -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') diff --git a/bemade_sports_clinic/models/res_partner.py b/bemade_sports_clinic/models/res_partner.py index 6dbe4d1..6549207 100644 --- a/bemade_sports_clinic/models/res_partner.py +++ b/bemade_sports_clinic/models/res_partner.py @@ -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.')) diff --git a/bemade_sports_clinic/security/ir.model.access.csv b/bemade_sports_clinic/security/ir.model.access.csv new file mode 100644 index 0000000..2b76d10 --- /dev/null +++ b/bemade_sports_clinic/security/ir.model.access.csv @@ -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 \ No newline at end of file diff --git a/bemade_sports_clinic/security/sports_clinic_groups.xml b/bemade_sports_clinic/security/sports_clinic_groups.xml new file mode 100644 index 0000000..700c2d0 --- /dev/null +++ b/bemade_sports_clinic/security/sports_clinic_groups.xml @@ -0,0 +1,23 @@ + + + + + Sports Medicine Clinic Management + + + Internal User + + + + Treatment Professional + + + + + Administrator + + + + + diff --git a/bemade_sports_clinic/security/sports_clinic_rules.xml b/bemade_sports_clinic/security/sports_clinic_rules.xml new file mode 100644 index 0000000..5c4e9c6 --- /dev/null +++ b/bemade_sports_clinic/security/sports_clinic_rules.xml @@ -0,0 +1,23 @@ + + + + + + Restrict Team Staff Access to Their Players Only + + + + [('id', 'in', user.partner_id.staff_team_ids.mapped('patient_ids').ids)] + + + + + Access patient injury records on invitation only + + + + [('message_follower_ids', 'in', user.partner_id.ids)] + + + + \ No newline at end of file diff --git a/bemade_sports_clinic/static/description/icon.png b/bemade_sports_clinic/static/description/icon.png new file mode 100644 index 0000000..9c0d5b9 Binary files /dev/null and b/bemade_sports_clinic/static/description/icon.png differ diff --git a/bemade_sports_clinic/views/patient_views.xml b/bemade_sports_clinic/views/patient_views.xml new file mode 100644 index 0000000..9293c22 --- /dev/null +++ b/bemade_sports_clinic/views/patient_views.xml @@ -0,0 +1,67 @@ + + + + + sports.patient.view.search + sports.patient + + + + + + + + + + + + + + sports.patient.view.list + sports.patient + + + + + + + + + + + + sports.patient.view.form + sports.patient + +
+
+ +
+

Patient Record

+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/bemade_sports_clinic/views/res_partner_views.xml b/bemade_sports_clinic/views/res_partner_views.xml new file mode 100644 index 0000000..85758ad --- /dev/null +++ b/bemade_sports_clinic/views/res_partner_views.xml @@ -0,0 +1,16 @@ + + + + + teams.view.search + res.partner + + + + + + + + + + \ No newline at end of file diff --git a/bemade_sports_clinic/views/sports_clinic_menus.xml b/bemade_sports_clinic/views/sports_clinic_menus.xml new file mode 100644 index 0000000..765f2f3 --- /dev/null +++ b/bemade_sports_clinic/views/sports_clinic_menus.xml @@ -0,0 +1,55 @@ + + + + + Sports Teams + res.partner + [('type', '=', 'team')] + list,form + + + + Organizations + res.partner + list,kanban,form + [('is_company','=', True)] + + + Patients + sports.patient + list,kanban,form + + + Treatment Professionals + res.partner + [('type', '=', 'treatment_pro')] + list,kanban,form + + + + + + + + + + + \ No newline at end of file