-
+
+
@@ -359,13 +461,14 @@
+
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/bemade_fsm/reports/worksheet_custom_reports.xml b/bemade_fsm/reports/worksheet_custom_reports.xml
index 70d099b..137e095 100644
--- a/bemade_fsm/reports/worksheet_custom_reports.xml
+++ b/bemade_fsm/reports/worksheet_custom_reports.xml
@@ -1,13 +1,16 @@
-
+
Work Order Report (PDF)
bemade_fsm.work_order
bemade_fsm.work_order
- '%s Work Order %s' % (
- time.strftime('%Y-%m-%d'), object.work_order_number)
+ '%s %s' % (
+ object.planned_date_begin.strftime('%Y-%m-%d') if object.planned_date_begin else time.strftime('%Y-%m-%d'),
+ object.name
+ )
+
qweb-pdf
-
\ No newline at end of file
+
diff --git a/bemade_fsm/reports/worksheet_templates.xml b/bemade_fsm/reports/worksheet_templates.xml
deleted file mode 100644
index 026f037..0000000
--- a/bemade_fsm/reports/worksheet_templates.xml
+++ /dev/null
@@ -1,146 +0,0 @@
-
-
-
-
- Complete Worksheet Report (PDF)
- project.task
- qweb-pdf
- bemade_fsm.worksheet_complete
-
- '%s Worksheet %s' % (time.strftime('%Y-%m-%d'), object.name)
-
-
- report
-
-
-
-
-
-
-
-
-
-
-
-
-
- Customer:
-
-
-
- Service Address:
-
-
-
-
-
- Work Order
-
-
-
-
-
-
- Your Reference:
-
-
-
- Site Contacts:
-
-
-
-
-
-
- Work order attn:
-
-
-
-
-
-
-
-
-
-
-
Interventions
-
-
-
-
-
-
-
-
Equipment:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/bemade_fsm/tests/test_equipment.py b/bemade_fsm/tests/test_equipment.py
index 16e06e2..879f129 100644
--- a/bemade_fsm/tests/test_equipment.py
+++ b/bemade_fsm/tests/test_equipment.py
@@ -19,3 +19,7 @@ class TestEquipment(BemadeFSMBaseTest):
partner_company.write({'equipment_ids': [Command.set([])]})
with self.assertRaises(MissingError):
equipment.name
+
+ def test_compute_complete_name_when_name_blank(self):
+ equipment = self._generate_equipment(name=False)
+ complete_name = equipment.complete_name
diff --git a/bemade_fsm/tests/test_task.py b/bemade_fsm/tests/test_task.py
index f5e7ae6..e04cffc 100644
--- a/bemade_fsm/tests/test_task.py
+++ b/bemade_fsm/tests/test_task.py
@@ -6,37 +6,51 @@ from odoo import Command
@tagged('post_install', '-at_install')
class TaskTest(BemadeFSMBaseTest):
+ @classmethod
+ def setUpClass(cls):
+ # Chose to set up all tests the same way since this code was becoming very redundant
+ super().setUpClass()
+ cls.so = cls._generate_sale_order()
+ cls.template = cls._generate_task_template(names=['Parent', 'Child', 'Grandchild'], structure=[2, 1])
+ cls.product = cls._generate_product(task_template=cls.template)
+ cls.sol = cls._generate_sale_order_line(sale_order=cls.so, product=cls.product)
+ cls.user = cls._generate_project_manager_user('Bob', 'Bob')
+ cls.so.action_confirm()
+ cls.task = cls.sol.task_id
+
def test_reassigning_assignment_propagating_task_changes_subtasks(self):
- # This creation step is a bit lazy - we use defaults to make tasks with a hierachy and settings we want
- so = self._generate_sale_order()
- template = self._generate_task_template(names=['Parent', 'Child'], structure=[2])
- product = self._generate_product(task_template=template)
- sol = self._generate_sale_order_line(sale_order=so, product=product)
- user = self._generate_project_manager_user('Bob', 'Bob')
- so.action_confirm()
- task = sol.task_id
+ task = self.task
+ task.propagate_assignment = True
task.write({
- 'user_ids': [Command.set([user.id])],
+ 'user_ids': [Command.set([self.user.id])],
'propagate_assignment': True,
})
- self.assertTrue(all([t.user_ids == user for t in task | task._get_all_subtasks()]))
-
- def test_reassigning_assignment_non_propagating_task_doesnt_change_subtasks(self):
- so = self._generate_sale_order()
- template = self._generate_task_template(names=['Parent', 'Child', 'Grandchild'], structure=[2, 1])
- product = self._generate_product(task_template=template)
- sol = self._generate_sale_order_line(sale_order=so, product=product)
- user = self._generate_project_manager_user('Bob', 'Bob')
- so.action_confirm()
- task = sol.task_id
- task.child_ids.write({'propagate_assignment': False}) # Stop propagation after the first level
+ self.assertTrue(all([t.user_ids == self.user for t in task | task._get_all_subtasks()]))
+ def test_reassigning_task_doesnt_propagate_by_default(self):
+ task = self.task
task.write({
- 'user_ids': [Command.set([user.id])],
+ 'user_ids': [Command.set([self.user.id])],
'propagate_assignment': True,
})
- self.assertTrue(all([t.user_ids == user for t in task | task.child_ids]))
self.assertFalse(any([t.user_ids for t in task.child_ids.child_ids]))
+
+ def test_unset_propagate_assignment_unsets_for_all_children(self):
+ task = self.task
+ # First, set propagation and assign
+ task.propagate_assignment = True
+ task.write({
+ 'user_ids': [Command.set([self.user.id])]
+ })
+ # Then, unset propagation for the children and re-set assignment
+ task.child_ids.write({'propagate_assignment': False})
+ self.assertFalse(any([t.propagate_assignment for t in task._get_all_subtasks()]))
+ # Then, test that assigning the parent only assigns its children, not its grandchildren
+ task.write({
+ 'user_ids': [Command.set([])]
+ })
+ self.assertTrue(all([not t.user_ids for t in task | task.child_ids]))
+ self.assertTrue(all([t.user_ids == self.user for t in task.child_ids.child_ids]))
diff --git a/bemade_open_project_details/__init__.py b/bemade_open_project_details/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/bemade_open_project_details/__manifest__.py b/bemade_open_project_details/__manifest__.py
deleted file mode 100644
index a8396a0..0000000
--- a/bemade_open_project_details/__manifest__.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Bemade Inc.
-#
-# Copyright (C) June 2023 Bemade Inc. (
).
-# Author: mdurepos (Contact : it@bemade.org)
-#
-# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
-# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
-# or modified copies of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-# DEALINGS IN THE SOFTWARE.
-#
-{
- 'name': 'Open Project Details',
- 'version': '17.0.0.0.1',
- 'summary': 'Open Project Details',
- 'description': """
- This module adds the ability to view project details from the project form view.
- """,
- 'category': 'Project',
- 'author': 'Bemade Inc.',
- 'website': 'https://www.bemade.org',
- 'license': 'OPL-1',
- 'depends': [
- 'project',
- ],
- 'data': [
- # 'views/project_project_views.xml'
- ],
- 'demo': [],
- 'installable': True,
- 'auto_install': False,
-}
diff --git a/bemade_open_project_details/views/project_project_views.xml b/bemade_open_project_details/views/project_project_views.xml
deleted file mode 100644
index 8458b5b..0000000
--- a/bemade_open_project_details/views/project_project_views.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
- project.view.project.kanban.inherit
- project.project
-
-
-
-
-
- Open
-
-
-
-
-
diff --git a/bemade_packing_wizard/wizard/choose_delivery_package.py b/bemade_packing_wizard/wizard/choose_delivery_package.py
index 55a0a9e..f7cfc01 100644
--- a/bemade_packing_wizard/wizard/choose_delivery_package.py
+++ b/bemade_packing_wizard/wizard/choose_delivery_package.py
@@ -59,7 +59,7 @@ class ChooseDeliveryPackage(models.TransientModel):
# if no package type found, create one
if not delivery_package_type:
delivery_package_type = delivery_package_type.create({
- 'name': f'Box {vals["width"]}x{vals["height"]}x{vals["length"]}',
+ 'name': f'Box {self.width}x{self.height}x{self.length}',
'width': self.width,
'height': self.height,
'packaging_length': self.length,
diff --git a/bemade_search_supplier_code/__manifest__.py b/bemade_search_supplier_code/__manifest__.py
index 7c1e0d7..7e43849 100644
--- a/bemade_search_supplier_code/__manifest__.py
+++ b/bemade_search_supplier_code/__manifest__.py
@@ -1,5 +1,4 @@
{
- 'name': 'Search Supplier Code',
'version': '17.0.0.1',
'summary': 'Search for products by supplier code',
'sequence': 10,
@@ -21,4 +20,4 @@
'application': False,
'auto_install': False,
'license': 'LGPL-3',
-}
\ No newline at end of file
+}
diff --git a/bemade_sports_clinic/__manifest__.py b/bemade_sports_clinic/__manifest__.py
index d9c1ade..96f75f6 100644
--- a/bemade_sports_clinic/__manifest__.py
+++ b/bemade_sports_clinic/__manifest__.py
@@ -42,8 +42,10 @@
'security/sports_clinic_groups.xml',
'security/ir.model.access.csv',
'security/sports_clinic_rules.xml',
+ 'data/sports_clinic_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/res_partner_views.xml',
diff --git a/bemade_sports_clinic/data/demo/sports_clinic_demo_data.xml b/bemade_sports_clinic/data/demo/sports_clinic_demo_data.xml
index c148dea..2b1dd30 100644
--- a/bemade_sports_clinic/data/demo/sports_clinic_demo_data.xml
+++ b/bemade_sports_clinic/data/demo/sports_clinic_demo_data.xml
@@ -186,4 +186,4 @@
-
\ No newline at end of file
+
diff --git a/bemade_sports_clinic/data/sports_clinic_data.xml b/bemade_sports_clinic/data/sports_clinic_data.xml
new file mode 100644
index 0000000..2f3edc5
--- /dev/null
+++ b/bemade_sports_clinic/data/sports_clinic_data.xml
@@ -0,0 +1,87 @@
+
+
+
+
+ Patient File Update (External)
+ sports.patient.injury
+
+
+
+
+
+
+
+ Patient File Update (Internal)
+ sports.patient.injury
+
+
+
+
+
+
+ Patient Status Update
+
+ Patient Injury Status Update for {{ object.patient_name }}
+
+ An update has been posted to the injury record for 's injurywith
+ the diagnosis of . Click
+ here to view the injury details.
+
+
+
+
+ Patient Status Update
+
+ Internal Note Updated for Patient {{ object.patient_name }}
+
+ A new internal note has been posted to the injury record for 's injurywith
+ the diagnosis of .
+
+
+
+
+
+ Patient File Update (External)
+ sports.patient
+
+
+
+
+
+
+
+ Patient File Update (Internal)
+ sports.patient
+
+
+
+
+
+
+ Patient Status Update
+
+ Patient Status Update for {{ object.name}}
+
+ An update has been posted to the record for 's. Click
+ here to view the details.
+
+
+
+
+ Patient Status Update
+
+ Internal Note Updated for Patient {{ object.name}}
+
+ A new internal note has been posted to the record for 's.
+
+
+
+
+
+
diff --git a/bemade_sports_clinic/i18n/fr_CA.po b/bemade_sports_clinic/i18n/fr_CA.po
index 138b7f6..6608832 100644
--- a/bemade_sports_clinic/i18n/fr_CA.po
+++ b/bemade_sports_clinic/i18n/fr_CA.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-11-07 20:03+0000\n"
-"PO-Revision-Date: 2023-11-07 20:03+0000\n"
+"POT-Creation-Date: 2024-02-21 00:52+0000\n"
+"PO-Revision-Date: 2024-02-21 00:52+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -25,11 +25,6 @@ msgstr ""
msgid "/my/teams"
msgstr ""
-#. module: bemade_sports_clinic
-#: model:ir.model,name:bemade_sports_clinic.model_sports_patient_injury
-msgid "A patient's injury."
-msgstr "La blessure d'un patient."
-
#. module: bemade_sports_clinic
#. odoo-python
#: code:addons/bemade_sports_clinic/models/sports_team.py:0
@@ -105,6 +100,11 @@ msgstr "Administrateur"
msgid "Age"
msgstr "Âge"
+#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__allergies
+msgid "Allergies"
+msgstr ""
+
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__message_attachment_count
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_injury__message_attachment_count
@@ -112,14 +112,9 @@ msgid "Attachment Count"
msgstr "Nombre de pièces jointes"
#. module: bemade_sports_clinic
-#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__stage__practice_ok
-msgid "Cleared for Practice"
-msgstr "Pratiques autorisées"
-
-#. module: bemade_sports_clinic
-#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__stage__healthy
-msgid "Cleared to Play"
-msgstr "Matchs autorisés"
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__city
+msgid "City"
+msgstr "Ville"
#. module: bemade_sports_clinic
#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_team_staff__role__coach
@@ -128,8 +123,9 @@ msgstr "Entraîneur"
#. module: bemade_sports_clinic
#: model:ir.model,name:bemade_sports_clinic.model_res_partner
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__partner_id
msgid "Contact"
-msgstr "Contact"
+msgstr ""
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_contact__contact_type
@@ -139,7 +135,12 @@ msgstr "Type de contact"
#. module: bemade_sports_clinic
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_form
msgid "Contacts"
-msgstr "Contacts"
+msgstr ""
+
+#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__country_id
+msgid "Country"
+msgstr "Pays"
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__create_uid
@@ -159,15 +160,20 @@ msgstr "Créé par"
msgid "Created on"
msgstr "Créé le"
+#. module: bemade_sports_clinic
+#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_kanban
+msgid "DOB:"
+msgstr "DDN :"
+
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__date_of_birth
msgid "Date Of Birth"
msgstr "Date de naissance"
#. module: bemade_sports_clinic
-#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_injury__injury_date_time
-msgid "Date and Time of Injury"
-msgstr "Date et heure de la blessure"
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_injury__injury_date
+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
@@ -189,6 +195,11 @@ msgstr "Diagnostique"
msgid "Display Name"
msgstr "Nom pour affichage"
+#. module: bemade_sports_clinic
+#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_team_staff__role__doctor
+msgid "Doctor"
+msgstr "Docteur"
+
#. module: bemade_sports_clinic
#: model:ir.model.constraint,message:bemade_sports_clinic.constraint_sports_team_staff_team_staff_unique
msgid "Each partner can only be related to a given team once."
@@ -301,7 +312,7 @@ msgstr "En santé :"
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_team__id
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_team_staff__id
msgid "ID"
-msgstr "ID"
+msgstr ""
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__activity_exception_icon
@@ -329,6 +340,13 @@ msgstr "Si coché, des nouveaux messages nécessitent votre attention."
msgid "If checked, some messages have a delivery error."
msgstr "Si coché, certains messages ont une erreur de livraison."
+#. module: bemade_sports_clinic
+#. odoo-python
+#: code:addons/bemade_sports_clinic/models/patient_injury.py:0
+#, python-format
+msgid "If injury date is not set, the N/A box must be checked."
+msgstr "Sa la date de la blessure n'est pas remplie, la case S/O doit être cochée."
+
#. module: bemade_sports_clinic
#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__stage__no_play
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.portal_my_teams
@@ -463,7 +481,14 @@ msgstr "Erreur de livraison du message"
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__message_ids
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_injury__message_ids
msgid "Messages"
-msgstr "Messages"
+msgstr ""
+
+#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__mobile
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_contact__mobile
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_team_staff__mobile
+msgid "Mobile"
+msgstr ""
#. module: bemade_sports_clinic
#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient_contact__contact_type__mother
@@ -476,6 +501,12 @@ msgstr "Mère"
msgid "My Activity Deadline"
msgstr "Date limite de mon activité"
+#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_injury__injury_date_na
+#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient_injury__parental_consent__na
+msgid "N/A"
+msgstr "S/O"
+
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__name
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_contact__name
@@ -508,13 +539,15 @@ msgstr "Type de la prochaine activité"
#. module: bemade_sports_clinic
#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__match_status__no
#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__practice_status__no
+#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient_injury__parental_consent__no
msgid "No"
msgstr "Non"
#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__team_info_notes
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.portal_my_player_injuries
msgid "Notes"
-msgstr "Notes"
+msgstr ""
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__message_needaction_counter
@@ -557,6 +590,11 @@ msgstr "Organisation"
msgid "Other"
msgstr "Autre"
+#. module: bemade_sports_clinic
+#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_form
+msgid "Other Contacts"
+msgstr "Autres contacts"
+
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_res_partner__owned_team_ids
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_res_users__owned_team_ids
@@ -571,55 +609,96 @@ msgid "Parent Organization"
msgstr "Organisation parente"
#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_injury__parental_consent
+msgid "Consent for Disclosure to Parent"
+msgstr "Consentement pour divulgation au parent"
+
+#. module: bemade_sports_clinic
+#: model:ir.model,name:bemade_sports_clinic.model_sports_patient
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_res_partner__patient_ids
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_res_users__patient_ids
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_contact__patient_id
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_injury__patient_id
msgid "Patient"
-msgstr "Patient(e)"
+msgstr "Patient dans une clinique de médecine sportive."
+
+#. module: bemade_sports_clinic
+#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_form
+msgid "Patient Address"
+msgstr "Adresse du patient"
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__contact_ids
msgid "Patient Contacts"
msgstr "Contacts du patient"
+#. module: bemade_sports_clinic
+#: model:mail.message.subtype,name:bemade_sports_clinic.subtype_patient_update
+msgid "Patient File Update"
+msgstr "Mise à jour du dossier du patient"
+
#. module: bemade_sports_clinic
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_form
msgid "Patient Information"
msgstr "Information du patient"
+#. module: bemade_sports_clinic
+#: model:ir.model,name:bemade_sports_clinic.model_sports_patient_injury
+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
msgid "Patient Injury History"
msgstr "Historique des blessures du patient"
+#. module: bemade_sports_clinic
+#: model:mail.message.subtype,name:bemade_sports_clinic.subtype_patient_injury_update
+msgid "Patient Injury Status Update"
+msgstr "Mise à jour du statut de la blessure d'un patient"
+
+#. module: bemade_sports_clinic
+#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_form
+msgid "Patient Phone & Email"
+msgstr "Téléphone et courriel du patient"
+
#. module: bemade_sports_clinic
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_form
msgid "Patient Record"
msgstr "Dossier du patient"
-#. module: bemade_sports_clinic
-#: model:ir.model,name:bemade_sports_clinic.model_sports_patient
-msgid "Patient at a sports medicine clinic."
-msgstr "Patient dans une clinique de médecine sportive."
-
#. module: bemade_sports_clinic
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_form
msgid "Patient's Contacts"
msgstr "Contacts du patient"
+#. module: bemade_sports_clinic
+#: model:mail.message.subtype,description:bemade_sports_clinic.subtype_patient_update
+msgid "Patient's file has been updated."
+msgstr "Le dossier du patient a été mis à jour."
+
+#. module: bemade_sports_clinic
+#: model:mail.message.subtype,description:bemade_sports_clinic.subtype_patient_injury_update
+msgid "Patient's injury was updated."
+msgstr "Le dossier de la blessure du patient a été mis à jour."
+
#. module: bemade_sports_clinic
#: model:ir.actions.act_window,name:bemade_sports_clinic.action_view_patient
#: model:ir.ui.menu,name:bemade_sports_clinic.sports_clinic_patients
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_list
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_list_embedded
msgid "Patients"
-msgstr "Patients"
+msgstr ""
#. module: bemade_sports_clinic
-#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__mobile
-#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_contact__mobile
-#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_team_staff__mobile
-msgid "Mobile"
-msgstr "Mobile"
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__phone
+msgid "Phone"
+msgstr "Téléphone"
+
+#. module: bemade_sports_clinic
+#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__stage__healthy
+msgid "Play OK"
+msgstr "Matchs autorisés"
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_team__player_count
@@ -635,6 +714,11 @@ msgstr "Nombre de joueurs"
msgid "Players"
msgstr "Joueurs"
+#. module: bemade_sports_clinic
+#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__stage__practice_ok
+msgid "Practice OK"
+msgstr "Pratiques autorisées"
+
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__practice_status
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.portal_my_players
@@ -652,11 +736,6 @@ msgstr "Date prévue de résolution"
msgid "Predicted Return Date"
msgstr "Date prévue de retour"
-#. module: bemade_sports_clinic
-#: model:ir.model,name:bemade_sports_clinic.model_sports_team_staff
-msgid "Relationship between staff members and their teams."
-msgstr "Relation entre les membres du personnel et leurs équipes."
-
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient_injury__resolution_date
msgid "Resolution Date"
@@ -720,6 +799,11 @@ msgstr "Gestion de clinique de médecine sportive"
msgid "Sports Team"
msgstr "Équipe sportive"
+#. module: bemade_sports_clinic
+#: model:ir.model,name:bemade_sports_clinic.model_sports_team_staff
+msgid "Sports Team Staff"
+msgstr "Relation entre les membres du personnel et leurs équipes."
+
#. module: bemade_sports_clinic
#: model:ir.actions.act_window,name:bemade_sports_clinic.action_view_team
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_team_view_list
@@ -744,6 +828,11 @@ msgstr "Membre du personnel"
msgid "Stage"
msgstr "Étape"
+#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__state_id
+msgid "State"
+msgstr "État"
+
#. module: bemade_sports_clinic
#: model:ir.model.fields,help:bemade_sports_clinic.field_sports_patient__activity_state
#: model:ir.model.fields,help:bemade_sports_clinic.field_sports_patient_injury__activity_state
@@ -758,6 +847,21 @@ msgstr ""
"Aujourd'hui: La date d'échéance est aujourd'hui\n"
"Planifiées: Activités futures."
+#. module: bemade_sports_clinic
+#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.sports_patient_view_kanban
+msgid "Status:"
+msgstr "Statut :"
+
+#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__street
+msgid "Street"
+msgstr "Rue"
+
+#. module: bemade_sports_clinic
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__street2
+msgid "Street2"
+msgstr "Rue2"
+
#. module: bemade_sports_clinic
#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_team_staff__team_id
msgid "Team"
@@ -804,6 +908,11 @@ msgstr "La date quand la blessure a été résolue."
msgid "The teams this person works for."
msgstr "Les équipes pour lesquelles cette personne travaille."
+#. module: bemade_sports_clinic
+#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_team_staff__role__therapist
+msgid "Therapist"
+msgstr "Thérapeute"
+
#. module: bemade_sports_clinic
#. odoo-python
#: code:addons/bemade_sports_clinic/controllers/team_staff_portal.py:0
@@ -818,21 +927,18 @@ msgstr "Ce joueur n'a pu être trouvé."
msgid "This team could not be found."
msgstr "Cette équipe n'a pu être trouvée."
+#. module: bemade_sports_clinic
+#. odoo-python
+#: code:addons/bemade_sports_clinic/models/res_partner.py:0
+#, python-format
+msgid "To change a patient's name, change it from the patient form."
+msgstr "Pour changer le nom d'un patient, changez le à partir du formulaire patient."
+
#. module: bemade_sports_clinic
#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.portal_my_teams
msgid "Total Players"
msgstr "Total des joueurs"
-#. module: bemade_sports_clinic
-#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_team_staff__role__therapist
-msgid "Therapist"
-msgstr "Thérapeute"
-
-#. module: bemade_sports_clinic
-#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_team_staff__role__doctor
-msgid "Doctor"
-msgstr "Docteur"
-
#. module: bemade_sports_clinic
#: model:res.groups,name:bemade_sports_clinic.group_sports_clinic_treatment_professional
msgid "Treatment Professional"
@@ -879,11 +985,22 @@ msgstr "Historique de communication du site web"
#. module: bemade_sports_clinic
#: model:ir.model.fields,help:bemade_sports_clinic.field_sports_patient__return_date
msgid "When the player was cleared by medical staff to return to match play."
-msgstr "Quand le joueur a été autorisé par le personnel médical à retourner au jeu."
+msgstr ""
+"Quand le joueur a été autorisé par le personnel médical à retourner au jeu."
+
+#. module: bemade_sports_clinic
+#: model:ir.model.fields,help:bemade_sports_clinic.field_sports_patient_injury__parental_consent
+msgid ""
+"Whether the patient has given their consent to share injury details with "
+"their parents."
+msgstr ""
+"Indique si le patient a donné son consentement pour que les détails de la blessure soient partagés avec "
+"ses parents."
#. module: bemade_sports_clinic
#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__match_status__yes
#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient__practice_status__yes
+#: model:ir.model.fields.selection,name:bemade_sports_clinic.selection__sports_patient_injury__parental_consent__yes
msgid "Yes"
msgstr "Oui"
@@ -903,11 +1020,6 @@ msgid "Your Teams"
msgstr "Vos équipes"
#. module: bemade_sports_clinic
-#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.portal_my_home
-msgid "players_count"
-msgstr ""
-
-#. module: bemade_sports_clinic
-#: model_terms:ir.ui.view,arch_db:bemade_sports_clinic.portal_my_home
-msgid "teams_count"
-msgstr ""
+#: model:ir.model.fields,field_description:bemade_sports_clinic.field_sports_patient__zip
+msgid "Zip"
+msgstr "Code postal"
diff --git a/bemade_sports_clinic/migrations/16.0.1.5.4/post-migrate.py b/bemade_sports_clinic/migrations/16.0.1.5.4/post-migrate.py
new file mode 100644
index 0000000..2323c5d
--- /dev/null
+++ b/bemade_sports_clinic/migrations/16.0.1.5.4/post-migrate.py
@@ -0,0 +1,21 @@
+from odoo import api, SUPERUSER_ID, Command
+
+def migrate(cr, version):
+ env = api.Environment(cr, SUPERUSER_ID, {})
+ patient_followers = env['mail.followers'].search([('res_model', '=',
+ 'sports.patient')])
+ injury_followers = env['mail.followers'].search([('res_model', '=',
+ 'sports.patient.injury')])
+ for f in patient_followers:
+ f.write(
+ {
+ 'subtype_ids':
+ [Command.link(env.ref('bemade_sports_clinic.subtype_patient_update').id)]
+ }
+ )
+ for f in injury_followers:
+ f.write(
+ {
+ 'subtype_ids':
+ [Command.link(env.ref('bemade_sports_clinic.subtype_patient_injury_update').id)]
+ })
diff --git a/bemade_sports_clinic/migrations/16.0.1.5.7/post-migrate.py b/bemade_sports_clinic/migrations/16.0.1.5.7/post-migrate.py
new file mode 100644
index 0000000..63f51c0
--- /dev/null
+++ b/bemade_sports_clinic/migrations/16.0.1.5.7/post-migrate.py
@@ -0,0 +1,22 @@
+from odoo import api, SUPERUSER_ID, Command
+
+
+def migrate(cr, version):
+ env = api.Environment(cr, SUPERUSER_ID, {})
+
+ patient_followers = env['mail.followers'].search([('res_model', '=',
+ 'sports.patient')])
+ injury_followers = env['mail.followers'].search([('res_model', '=',
+ 'sports.patient.injury')])
+ for f in patient_followers:
+ if f.partner_id.user_ids.has_group('base.group_user'):
+ subtype = env.ref('bemade_sports_clinic.subtype_patient_internal_update').id
+ else:
+ subtype = env.ref('bemade_sports_clinic.subtype_patient_external_update').id
+ f.write({'subtype_ids': [Command.link(subtype)]})
+ for f in injury_followers:
+ if f.partner_id.user_ids.has_group('base.group_user'):
+ subtype = env.ref('bemade_sports_clinic.subtype_patient_injury_internal_update').id
+ else:
+ subtype = env.ref('bemade_sports_clinic.subtype_patient_injury_external_update').id
+ f.write({'subtype_ids': [Command.link(subtype)]})
diff --git a/bemade_sports_clinic/models/__init__.py b/bemade_sports_clinic/models/__init__.py
index bd829d6..4664679 100644
--- a/bemade_sports_clinic/models/__init__.py
+++ b/bemade_sports_clinic/models/__init__.py
@@ -1,4 +1,7 @@
+from . import mail_followers
from . import patient
+from . import patient_injury
+from . import patient_contact
from . import res_partner
from . import sports_team
from . import res_users
diff --git a/bemade_sports_clinic/models/mail_followers.py b/bemade_sports_clinic/models/mail_followers.py
new file mode 100644
index 0000000..800cb67
--- /dev/null
+++ b/bemade_sports_clinic/models/mail_followers.py
@@ -0,0 +1,46 @@
+from odoo import models, fields, api, _
+
+
+class MailFollowers(models.Model):
+ _inherit = "mail.followers"
+
+ # This is a user quality of life modification, to avoid duplicated message subtype subscription for internal
+ # and external notifications (since both subtypes are default=True).
+
+ def write(self, vals):
+ super().write(vals)
+ subtypes_map = self.__subtypes_map()
+ if self.res_model in subtypes_map and 'subtype_ids' in vals:
+ internal_subtype, external_subtype = subtypes_map.get(self.res_model)
+ if external_subtype in self.subtype_ids and internal_subtype in self.subtype_ids:
+ self.subtype_ids = self.subtype_ids - external_subtype
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ recs = super().create(vals_list)
+ subtypes_map = self.__subtypes_map()
+ to_fix = {
+ model:
+ recs.filtered(
+ lambda rec: rec.res_model == model
+ and subtypes[0] in rec.subtype_ids
+ and subtypes[1] in rec.subtype_ids
+ ) for model, subtypes in subtypes_map.items()
+ }
+ for model, records in to_fix.items():
+ for rec in records:
+ rec.subtype_ids = rec.subtype_ids - subtypes_map[model][1]
+ return recs
+
+ def __subtypes_map(self):
+ xml_id_fmt_string = "bemade_sports_clinic.subtype_{0}_{1}_update"
+ return {
+ 'sports.patient': (
+ self.env.ref(xml_id_fmt_string.format('patient', 'internal')),
+ self.env.ref(xml_id_fmt_string.format('patient', 'external')),
+ ),
+ 'sports.patient.injury': (
+ self.env.ref(xml_id_fmt_string.format('patient_injury', 'internal')),
+ self.env.ref(xml_id_fmt_string.format('patient_injury', 'external')),
+ ),
+ }
diff --git a/bemade_sports_clinic/models/patient.py b/bemade_sports_clinic/models/patient.py
index 201bea2..f2296eb 100644
--- a/bemade_sports_clinic/models/patient.py
+++ b/bemade_sports_clinic/models/patient.py
@@ -3,11 +3,26 @@ from odoo.exceptions import ValidationError
from datetime import date
from dateutil.relativedelta import relativedelta
from odoo.addons.phone_validation.tools import phone_validation
+from typing import Set, Tuple
+
+external_tracking_fields = {
+ 'last_consultation_date',
+ 'match_status',
+ 'practice_status',
+ 'predicted_return_date',
+ 'return_date',
+}
+
+internal_tracking_fields = {
+ 'team_info_notes',
+ 'age',
+ 'date_of_birth',
+}
class Patient(models.Model):
_name = 'sports.patient'
- _description = "Patient at a sports medicine clinic."
+ _description = "Patient"
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'last_name, first_name'
@@ -30,43 +45,68 @@ class Patient(models.Model):
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)
- contact_ids = fields.One2many(comodel_name='sports.patient.contact',
- inverse_name='patient_id',
- string='Patient Contacts',
- groups="bemade_sports_clinic.group_sports_clinic_user")
- team_ids = fields.Many2many(comodel_name='sports.team',
- relation='sports_team_patient_rel',
- column1='patient_id',
- column2='team_id',
- string='Teams', )
- match_status = fields.Selection([ # Selection for easy expansion later
- ('yes', 'Yes'),
- ('no', 'No'),
- ], required=True, default='yes', tracking=True)
- practice_status = fields.Selection([
- ('yes', 'Yes'),
- ('no_contact', 'Yes, no contact'),
- ('no', 'No')], tracking=True, required=True, default='yes')
-
- injury_ids = fields.One2many(comodel_name='sports.patient.injury',
- inverse_name='patient_id',
- string='Injuries', )
+ age = fields.Integer(
+ compute='_compute_age',
+ groups="bemade_sports_clinic.group_sports_clinic_treatment_professional"
+ )
+ contact_ids = fields.One2many(
+ comodel_name='sports.patient.contact',
+ inverse_name='patient_id',
+ string='Patient Contacts',
+ groups="bemade_sports_clinic.group_sports_clinic_user"
+ )
+ team_ids = fields.Many2many(
+ comodel_name='sports.team',
+ relation='sports_team_patient_rel',
+ column1='patient_id',
+ column2='team_id',
+ string='Teams',
+ )
+ match_status = fields.Selection( # Selection rather than bool for easy expansion later
+ selection=[
+ ('yes', 'Yes'),
+ ('no', 'No'),
+ ],
+ required=True,
+ default='yes',
+ tracking=True)
+ practice_status = fields.Selection(
+ selection=[
+ ('yes', 'Yes'),
+ ('no_contact', 'Yes, no contact'),
+ ('no', 'No')
+ ],
+ tracking=True,
+ required=True,
+ default='yes',
+ )
+ injury_ids = fields.One2many(
+ comodel_name='sports.patient.injury',
+ inverse_name='patient_id',
+ string='Injuries',
+ )
injured_since = fields.Date(compute='_compute_is_injured')
predicted_return_date = fields.Date(tracking=True)
- return_date = fields.Date(tracking=True,
- help="When the player was cleared by medical staff to "
- "return to match play.")
+ return_date = fields.Date(
+ tracking=True,
+ help="When the player was cleared by medical staff to "
+ "return to match play."
+ )
is_injured = fields.Boolean(compute="_compute_is_injured")
stage = fields.Selection(
- selection=[('no_play', 'Injured'), ('practice_ok', 'Practice OK'), ('healthy', 'Play OK')],
+ selection=[
+ ('no_play', 'Injured'),
+ ('practice_ok', 'Practice OK'),
+ ('healthy', 'Play OK')
+ ],
compute='_compute_stage')
- last_consultation_date = fields.Date()
+ last_consultation_date = fields.Date(tracking=True)
active_injury_count = fields.Integer(compute='_compute_active_injury_count')
allergies = fields.Text()
- team_info_notes = fields.Html(string="Notes")
+ team_info_notes = fields.Html(
+ string="Notes",
+ tracking=True,
+ )
def default_get(self, fields_list):
res = super().default_get(fields_list)
@@ -187,116 +227,28 @@ class Patient(models.Model):
raise_exception=False
)
+ def _track_subtype(self, init_values):
+ return self.env.ref('mail.mt_note')
-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)
- contact_type = fields.Selection(selection=[
- ('mother', 'Mother'),
- ('father', 'Father'),
- ('other', 'Other'),
- ], required=True)
- 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'
- _description = "A patient's injury."
- _inherit = ['mail.thread', 'mail.activity.mixin']
- _rec_name = 'diagnosis'
-
- patient_id = fields.Many2one(comodel_name='sports.patient',
- string="Patient",
- readonly=True,
- required=True)
- patient_name = fields.Char(related="patient_id.name")
- diagnosis = fields.Char(tracking=True)
- injury_date = fields.Date(string='Date 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',
- domain=[
- ('is_treatment_professional', '=',
- True)], tracking=True)
- predicted_resolution_date = fields.Date(tracking=True)
- resolution_date = fields.Date(tracking=True,
- 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:
- if rec.resolution_date and rec.resolution_date <= date.today():
- rec.stage = 'resolved'
- else:
- rec.stage = 'active'
-
- def write(self, vals):
- super().write(vals)
- if 'treatment_professional_ids' in vals:
- to_subscribe = (self.treatment_professional_ids.mapped('partner_id')
- - self.message_follower_ids.mapped('partner_id'))
- self.message_subscribe(to_subscribe.ids)
-
- @api.model_create_multi
- def create(self, vals_list):
- res = super().create(vals_list)
- for rec in res:
- to_subscribe = (rec.treatment_professional_ids.mapped('partner_id')
- - rec.message_follower_ids.mapped('partner_id'))
- rec.message_subscribe(to_subscribe.ids)
+ def _track_template(self, changes):
+ res = super()._track_template(changes)
+ params = set(changes)
+ external = bool(external_tracking_fields & params)
+ if external:
+ first_external_field = (external_tracking_fields & params).pop()
+ res[first_external_field] = (
+ self.env.ref('bemade_sports_clinic.mail_template_patient_status_update'), {
+ 'auto_delete_message': False,
+ 'subtype_id': self.env.ref('bemade_sports_clinic.subtype_patient_external_update').id,
+ 'email_layout_xmlid': 'mail.mail_notification_light',
+ }
+ )
+ if 'team_info_notes' in changes:
+ res['team_info_notes'] = (
+ self.env.ref('bemade_sports_clinic.mail_template_patient_new_internal_note'), {
+ 'auto_delete_message': False,
+ 'subtype_id': self.env.ref('bemade_sports_clinic.subtype_patient_internal_update').id,
+ 'email_layout_xmlid': 'mail.mail_notification_light',
+ }
+ )
return res
-
- def action_view_injury_form(self):
- self.ensure_one()
- return {
- 'type': 'ir.actions.act_window',
- 'view_mode': 'form',
- 'res_model': 'sports.patient.injury',
- 'res_id': self.id,
- 'context': self._context,
- }
diff --git a/bemade_sports_clinic/models/patient_contact.py b/bemade_sports_clinic/models/patient_contact.py
new file mode 100644
index 0000000..36e70cc
--- /dev/null
+++ b/bemade_sports_clinic/models/patient_contact.py
@@ -0,0 +1,35 @@
+from odoo import models, fields, api
+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."
+
+ sequence = fields.Integer(required=True, default=0)
+ name = fields.Char(unaccent=False)
+ contact_type = fields.Selection(selection=[
+ ('mother', 'Mother'),
+ ('father', 'Father'),
+ ('other', 'Other'),
+ ], required=True)
+ mobile = fields.Char(unaccent=False, required=True)
+ # TODO: add email here and on views
+ 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
+ )
diff --git a/bemade_sports_clinic/models/patient_injury.py b/bemade_sports_clinic/models/patient_injury.py
new file mode 100644
index 0000000..f3c20c5
--- /dev/null
+++ b/bemade_sports_clinic/models/patient_injury.py
@@ -0,0 +1,153 @@
+from odoo import models, fields, api, _
+from datetime import datetime, date
+import pytz
+from odoo.exceptions import ValidationError
+from typing import Set, Tuple
+
+external_tracking_fields = {
+ 'diagnosis',
+ 'predicted_resolution_date',
+ 'resolution_date',
+ 'external_notes',
+}
+
+# Include only fields not already included in external_tracking_fields here
+internal_tracking_fields = {
+ 'internal_notes',
+ 'parental_consent',
+}
+
+
+class PatientInjury(models.Model):
+ _name = 'sports.patient.injury'
+ _description = "Patient Injury"
+ _inherit = ['mail.thread', 'mail.activity.mixin']
+ _rec_name = 'diagnosis'
+
+ @api.model
+ def _today(self):
+ """Get the current date in the user's time zone."""
+ return datetime.now(pytz.timezone(self.env.user.tz or 'GMT'))
+
+ # TODO: Find a way to improve notifications send about tracking injury details
+ # TODO: Add field consentement_parental = fields.Selection(oui, non, non-applicable)
+
+ patient_id = fields.Many2one(
+ comodel_name='sports.patient',
+ string="Patient",
+ readonly=True,
+ required=True
+ )
+ patient_name = fields.Char(related="patient_id.name")
+ diagnosis = fields.Char(tracking=True)
+
+ injury_date = fields.Date(
+ string='Date of Injury',
+ default=_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',
+ domain=[
+ ('is_treatment_professional', '=',
+ True)], tracking=True
+ )
+ predicted_resolution_date = fields.Date(tracking=True)
+ resolution_date = fields.Date(
+ tracking=True,
+ help="The date when the injury was actually resolved."
+ )
+ stage = fields.Selection(selection=[('active', 'Active'), ('resolved', 'Resolved')], compute='_compute_stage')
+ parental_consent = fields.Selection(
+ string="Consent for Disclosure to Parent",
+ selection=[
+ ('yes', 'Yes'),
+ ('no', 'No'),
+ ('na', 'N/A')
+ ],
+ help="Whether the patient has given their consent to share injury details with their parents.",
+ tracking=True,
+ )
+
+ @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:
+ if rec.resolution_date and rec.resolution_date <= date.today():
+ rec.stage = 'resolved'
+ else:
+ rec.stage = 'active'
+
+ def write(self, vals):
+ super().write(vals)
+ if 'treatment_professional_ids' in vals:
+ to_subscribe = (self.treatment_professional_ids.mapped('partner_id')
+ - self.message_follower_ids.mapped('partner_id'))
+ self.message_subscribe(to_subscribe.ids)
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ res = super().create(vals_list)
+ for rec in res:
+ to_subscribe = (rec.treatment_professional_ids.mapped('partner_id')
+ - rec.message_follower_ids.mapped('partner_id'))
+ rec.message_subscribe(to_subscribe.ids)
+ return res
+
+ def action_view_injury_form(self):
+ self.ensure_one()
+ return {
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'form',
+ 'res_model': 'sports.patient.injury',
+ 'res_id': self.id,
+ 'context': self._context,
+ }
+
+ def _track_subtype(self, init_values):
+ return self.env.ref('mail.mt_note')
+
+ def _track_template(self, changes):
+ res = super()._track_template(changes)
+ params = set(changes)
+ external = bool(external_tracking_fields & params)
+ if external:
+ first_external_field = (external_tracking_fields & params).pop()
+ res[first_external_field] = (
+ self.env.ref('bemade_sports_clinic.mail_template_patient_injury_status_update'), {
+ 'auto_delete_message': False,
+ 'subtype_id': self.env.ref('bemade_sports_clinic.subtype_patient_injury_external_update').id,
+ 'email_layout_xmlid': 'mail.mail_notification_light',
+ }
+ )
+ if 'internal_notes' in changes:
+ res['internal_notes'] = (
+ self.env.ref('bemade_sports_clinic.mail_template_patient_injury_new_internal_note'), {
+ 'auto_delete_message': False,
+ 'subtype_id': self.env.ref('bemade_sports_clinic.subtype_patient_injury_internal_update').id,
+ 'email_layout_xmlid': 'mail.mail_notification_light',
+ }
+ )
+ return res
diff --git a/bemade_sports_clinic/models/sports_team.py b/bemade_sports_clinic/models/sports_team.py
index b2f23bf..6f7d589 100644
--- a/bemade_sports_clinic/models/sports_team.py
+++ b/bemade_sports_clinic/models/sports_team.py
@@ -51,7 +51,7 @@ class SportsTeam(models.Model):
class TeamStaff(models.Model):
_name = "sports.team.staff"
- _description = "Relationship between staff members and their teams."
+ _description = "Sports Team Staff"
sequence = fields.Integer()
team_id = fields.Many2one(comodel_name='sports.team', string='Team', required=True)
diff --git a/bemade_sports_clinic/views/sports_patient_injury_views.xml b/bemade_sports_clinic/views/sports_patient_injury_views.xml
new file mode 100644
index 0000000..bb57cb5
--- /dev/null
+++ b/bemade_sports_clinic/views/sports_patient_injury_views.xml
@@ -0,0 +1,69 @@
+
+
+
+ sports.patient.injury.view.form
+ sports.patient.injury
+
+
+
+
+
+ sports.patient.injury.view.tree
+ sports.patient.injury
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bemade_sports_clinic/views/sports_patient_views.xml b/bemade_sports_clinic/views/sports_patient_views.xml
index 3b1fccf..156a0b3 100644
--- a/bemade_sports_clinic/views/sports_patient_views.xml
+++ b/bemade_sports_clinic/views/sports_patient_views.xml
@@ -184,69 +184,6 @@
-
- sports.patient.injury.view.form
- sports.patient.injury
-
-
-
-
-
- sports.patient.injury.view.tree
- sports.patient.injury
-
-
-
-
-
-
-
-
-
-
-
-
-
+>