changeset 4806:2c318d8123f1

task #16043: Migration to GNU Health 4.0. Initial migration of health_surgery package
author Luis Falcon <falcon@gnuhealth.org>
date Sat, 04 Dec 2021 20:07:19 +0000
parents 32b3669a34d7
children 17e5570588cc
files tryton/health_surgery/__init__.py tryton/health_surgery/data/health_surgery_sequence.xml tryton/health_surgery/data/messages/messages.xml tryton/health_surgery/exceptions.py tryton/health_surgery/health_surgery.py tryton/health_surgery/sequences.py tryton/health_surgery/tryton.cfg tryton/health_surgery/view/gnuhealth_operation_tree.xml tryton/health_surgery/view/gnuhealth_procedure_tree.xml tryton/health_surgery/view/gnuhealth_surgery_supply_tree.xml tryton/health_surgery/view/gnuhealth_surgery_team_tree.xml
diffstat 11 files changed, 189 insertions(+), 121 deletions(-) [+]
line wrap: on
line diff
--- a/tryton/health_surgery/__init__.py
+++ b/tryton/health_surgery/__init__.py
@@ -22,21 +22,23 @@
 ##############################################################################
 
 from trytond.pool import Pool
-from .health_surgery import *
-from .report import *
+from . import health_surgery
+from . import report
+from . import sequences
+from . import exceptions
 
 def register():
     Pool.register(
-		GnuHealthSequences,
-        GnuHealthSequenceSetup,
-        RCRI,
-        Surgery,
-        Operation,
-        SurgeryMainProcedure,
-        SurgerySupply,
-        PatientData,
-        SurgeryTeam,
+		sequences.GnuHealthSequences,
+        sequences.SurgeryCodeSequence,
+        health_surgery.RCRI,
+        health_surgery.Surgery,
+        health_surgery.Operation,
+        health_surgery.SurgeryMainProcedure,
+        health_surgery.SurgerySupply,
+        health_surgery.PatientData,
+        health_surgery.SurgeryTeam,
         module='health_surgery', type_='model')
     Pool.register(
-        SurgeryReport,
+        report.SurgeryReport,
         module='health_surgery', type_='report')
--- a/tryton/health_surgery/data/health_surgery_sequence.xml
+++ b/tryton/health_surgery/data/health_surgery_sequence.xml
@@ -6,12 +6,11 @@
 
         <record id="seq_type_gnuhealth_surgery_code" model="ir.sequence.type">
             <field name="name">Surgery</field>
-            <field name="code">gnuhealth.surgery</field>
         </record>
 
         <record id="seq_gnuhealth_surgery_code" model="ir.sequence">
             <field name="name">Surgery</field>
-            <field name="code">gnuhealth.surgery</field>
+            <field name="sequence_type" ref="seq_type_gnuhealth_surgery_code"></field>
             <field name="prefix">SRG-${year}-</field>
             <field name="padding">5</field>
         </record>
new file mode 100644
--- /dev/null
+++ b/tryton/health_surgery/data/messages/messages.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!-- This file is part of GNU Health.  The COPYRIGHT file at the top level of
+this repository contains the full copyright notices and license terms. -->
+<tryton>
+    <data grouped="1">
+        <record model="ir.message" id="msg_end_date_before_start">
+            <field name="text">End time "%(end_date)s" BEFORE surgery date "%(surgery_date)s"</field>
+        </record>
+        <record model="ir.message" id="msg_or_is_not_available">
+            <field name="text">Operating Room is not available</field>
+        </record>
+        <record model="ir.message" id="msg_or_and_time_needed">
+            <field name="text">Operating Room and estimated end time are needed in order to confirm the surgery</field>
+        </record>
+        <record model="ir.message" id="msg_surgery_is_done">
+            <field name="text">This surgery is at state Done and has been signed. You can no longer modify it.</field>
+        </record>
+    </data>
+</tryton>
new file mode 100644
--- /dev/null
+++ b/tryton/health_surgery/exceptions.py
@@ -0,0 +1,18 @@
+# This file is part of GNU Health.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.exceptions import UserError, UserWarning
+from trytond.model.exceptions import ValidationError
+
+
+class EndDateBeforeStart(ValidationError):
+    pass
+
+
+class ORNotAvailable(ValidationError):
+    pass
+
+class OperatingRoomAndDateRequired(UserError):
+    pass
+
+class SurgeryDone(UserError):
+    pass
--- a/tryton/health_surgery/health_surgery.py
+++ b/tryton/health_surgery/health_surgery.py
@@ -1,11 +1,12 @@
-# -*- coding: utf-8 -*-
 ##############################################################################
 #
-#    GNU Health: The Free Health and Hospital Information System
+#    GNU Health HMIS: The Free Health and Hospital Information System
 #    Copyright (C) 2008-2021 Luis Falcon <lfalcon@gnusolidario.org>
 #    Copyright (C) 2011-2021 GNU Solidario <health@gnusolidario.org>
 #
-#
+#    The GNU Health HMIS component is part of the GNU Health project
+#    www.gnuhealth.org
+
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
@@ -32,71 +33,19 @@
 from trytond import backend
 from trytond.tools.multivalue import migrate_property
 
+from trytond.i18n import gettext
+from trytond.pyson import Id
 
-__all__ = ['GnuHealthSequences', 'GnuHealthSequenceSetup','RCRI', 
-    'Surgery', 'Operation', 'SurgeryMainProcedure','SurgerySupply',
-    'PatientData', 'SurgeryTeam']
+from .exceptions import (
+    EndDateBeforeStart, ORNotAvailable, OperatingRoomAndDateRequired,
+    SurgeryDone
+    )
 
-sequences = ['surgery_code_sequence']
+from trytond.modules.health.core import get_health_professional, \
+    get_institution
 
-
-class GnuHealthSequences(ModelSingleton, ModelSQL, ModelView):
-    __name__ = "gnuhealth.sequences"
-
-    surgery_code_sequence = fields.MultiValue(fields.Many2One(
-        'ir.sequence', 'Surgery Sequence', required=True,
-        domain=[('code', '=', 'gnuhealth.surgery')]))
-
-    @classmethod
-    def multivalue_model(cls, field):
-        pool = Pool()
-
-        if field in sequences:
-            return pool.get('gnuhealth.sequence.setup')
-        return super(GnuHealthSequences, cls).multivalue_model(field)
-
-
-    @classmethod
-    def default_surgery_code_sequence(cls):
-        return cls.multivalue_model(
-            'surgery_code_sequence').default_surgery_code_sequence()
-
-
-# SEQUENCE SETUP
-class GnuHealthSequenceSetup(ModelSQL, ValueMixin):
-    'GNU Health Sequences Setup'
-    __name__ = 'gnuhealth.sequence.setup'
-
-    surgery_code_sequence = fields.Many2One('ir.sequence', 
-        'Surgery Code Sequence', required=True,
-        domain=[('code', '=', 'gnuhealth.surgery')])
-  
-    @classmethod
-    def __register__(cls, module_name):
-        TableHandler = backend.get('TableHandler')
-        exist = TableHandler.table_exist(cls._table)
-
-        super(GnuHealthSequenceSetup, cls).__register__(module_name)
-
-        if not exist:
-            cls._migrate_MultiValue([], [], [])
-
-    @classmethod
-    def _migrate_property(cls, field_names, value_names, fields):
-        field_names.extend(sequences)
-        value_names.extend(sequences)
-        migrate_property(
-            'gnuhealth.sequences', field_names, cls, value_names,
-            fields=fields)
-
-    @classmethod
-    def default_surgery_code_sequence(cls):
-        pool = Pool()
-        ModelData = pool.get('ir.model.data')
-        return ModelData.get_id(
-            'health_surgery', 'seq_gnuhealth_surgery_code')
-    
-# END SEQUENCE SETUP , MIGRATION FROM FIELDS.MultiValue
+__all__ = ['RCRI', 'Surgery', 'Operation', 'SurgeryMainProcedure',
+           'SurgerySupply', 'PatientData', 'SurgeryTeam']
 
 class RCRI(ModelSQL, ModelView):
     'Revised Cardiac Risk Index'
@@ -438,9 +387,7 @@
 
     @staticmethod
     def default_institution():
-        HealthInst = Pool().get('gnuhealth.institution')
-        institution = HealthInst.get_institution()
-        return institution
+        return get_institution()
 
     @staticmethod
     def default_surgery_date():
@@ -448,9 +395,7 @@
 
     @staticmethod
     def default_surgeon():
-        pool = Pool()
-        HealthProf= pool.get('gnuhealth.healthprofessional')
-        surgeon = HealthProf.get_health_professional()
+        surgeon = get_health_professional()
         return surgeon
 
     @staticmethod
@@ -478,27 +423,29 @@
         self.computed_age = self.patient.age
 
 
+
+
+    @classmethod
+    def generate_code(cls, **pattern):
+        Config = Pool().get('gnuhealth.sequences')
+        config = Config(1)
+        sequence = config.get_multivalue(
+            'surgery_code_sequence', **pattern)
+        if sequence:
+            return sequence.get()
+
     @classmethod
     def create(cls, vlist):
-        Sequence = Pool().get('ir.sequence')
-        Config = Pool().get('gnuhealth.sequences')
-
         vlist = [x.copy() for x in vlist]
         for values in vlist:
             if not values.get('code'):
-                config = Config(1)
-                values['code'] = Sequence.get_id(
-                    config.surgery_code_sequence.id)
+                values['code'] = cls.generate_code()
         return super(Surgery, cls).create(vlist)
 
 
     @classmethod
     def __setup__(cls):
         super(Surgery, cls).__setup__()
-        cls._error_messages.update({
-            'end_date_before_start': 'End time "%(end_date)s" BEFORE '
-                'surgery date "%(surgery_date)s"',
-            'or_is_not_available': 'Operating Room is not available'})
 
         cls._order.insert(0, ('surgery_date', 'DESC'))
 
@@ -536,23 +483,15 @@
             ])
         if (self.surgery_end_date and self.surgery_date):
             if (self.surgery_end_date < self.surgery_date):
-                self.raise_user_error('end_date_before_start', {
-                        'surgery_date': Lang.strftime(self.surgery_date,
-                            language.code,
-                            language.date),
-                        'end_date': Lang.strftime(self.surgery_end_date,
-                            language.code,
-                            language.date),
-                        })
-
+                raise EndDateBeforeStart(
+                    gettext('health_surgery.msg_end_date_before_start'))
 
     @classmethod
     def write(cls, surgeries, vals):
         # Don't allow to write the record if the surgery has been signed
         if surgeries[0].state == 'signed':
-            cls.raise_user_error(
-                "This surgery is at state Done and has been signed\n"
-                "You can no longer modify it.")
+            raise EndDateBeforeStart(
+                gettext('health_surgery.msg_surgery_is_done'))
         return super(Surgery, cls).write(surgeries, vals)
 
     ## Method to check for availability and make the Operating Room reservation
@@ -567,8 +506,8 @@
 
         # Operating Room and end surgery time check
         if (not surgery_id.operating_room or not surgery_id.surgery_end_date):
-            cls.raise_user_error("Operating Room and estimated end time  "
-            "are needed in order to confirm the surgery")
+            raise OperatingRoomAndDateRequired(
+                    gettext('health_surgery.msg_or_and_time_needed'))
 
         or_id = surgery_id.operating_room.id
         cursor.execute("SELECT COUNT(*) \
@@ -583,10 +522,12 @@
         res = cursor.fetchone()
         if (surgery_id.surgery_end_date <
             surgery_id.surgery_date):
-            cls.raise_user_error("The Surgery end date must later than the \
-                Start")
+                raise EndDateBeforeStart(
+                    gettext('health_surgery.msg_end_date_before_start'))
         if res[0] > 0:
-            cls.raise_user_error('or_is_not_available')
+            raise ORNotAvailable(
+                    gettext('health_surgery.msg_or_is_not_available'))
+
         else:
             cls.write(surgeries, {'state': 'confirmed'})
  
@@ -641,10 +582,7 @@
         # Sign, change the state of the Surgery to "Signed"
         # and write the name of the signing health professional
 
-        signing_hp = Pool().get('gnuhealth.healthprofessional').get_health_professional()
-        if not signing_hp:
-            cls.raise_user_error(
-                "No health professional associated to this user !")
+        signing_hp = get_health_professional()
 
         cls.write(surgeries, {
             'state': 'signed',
new file mode 100644
--- /dev/null
+++ b/tryton/health_surgery/sequences.py
@@ -0,0 +1,91 @@
+##############################################################################
+#
+#    GNU Health HMIS: The Free Health and Hospital Information System
+#    Copyright (C) 2008-2021 Luis Falcon <falcon@gnuhealth.org>
+#    Copyright (C) 2011-2021 GNU Solidario <health@gnusolidario.org>
+#
+#    The GNU Health HMIS component is part of the GNU Health project
+#    www.gnuhealth.org
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+# GNU Health HMIS sequences for this package
+
+from trytond.model import (ModelView, ModelSingleton, ModelSQL,
+                           ValueMixin, MultiValueMixin, fields)
+from trytond import backend
+from trytond.pyson import Id
+from trytond.pool import Pool
+from trytond.tools.multivalue import migrate_property
+
+# Sequences
+surgery_code_sequence = fields.Many2One(
+    'ir.sequence', 'Surgery code sequence', required=True,
+    domain=[('sequence_type', '=', Id(
+        'health', 'seq_type_gnuhealth_surgery_code'))])
+
+
+# GNU HEALTH SEQUENCES
+class GnuHealthSequences(ModelSingleton, ModelSQL, ModelView, MultiValueMixin):
+    'Standard Sequences for GNU Health'
+    __name__ = 'gnuhealth.sequences'
+
+    surgery_code_sequence = fields.MultiValue(
+        surgery_code_sequence)
+
+
+    @classmethod
+    def default_surgery_code_sequence(cls, **pattern):
+        pool = Pool()
+        ModelData = pool.get('ir.model.data')
+        try:
+            return ModelData.get_id('health_surgery',
+                                    'seq_gnuhealth_surgery_code')
+        except KeyError:
+            return None
+
+class _ConfigurationValue(ModelSQL):
+
+    _configuration_value_field = None
+
+    @classmethod
+    def __register__(cls, module_name):
+        exist = backend.TableHandler.table_exist(cls._table)
+
+        super(_ConfigurationValue, cls).__register__(module_name)
+
+        if not exist:
+            cls._migrate_property([], [], [])
+
+    @classmethod
+    def _migrate_property(cls, field_names, value_names, fields):
+        field_names.append(cls._configuration_value_field)
+        value_names.append(cls._configuration_value_field)
+        migrate_property(
+            'gnuhealth.sequences', field_names, cls, value_names,
+            fields=fields)
+
+
+class SurgeryCodeSequence(_ConfigurationValue, ModelSQL, ValueMixin):
+    'Health Service Request Sequence setup'
+    __name__ = 'gnuhealth.sequences.surgery_code_sequence'
+    surgery_code_sequence = surgery_code_sequence
+    _configuration_value_field = 'surgery_code_sequence'
+
+    @classmethod
+    def check_xml_record(cls, records, values):
+        return True
+
--- a/tryton/health_surgery/tryton.cfg
+++ b/tryton/health_surgery/tryton.cfg
@@ -1,5 +1,5 @@
 [tryton]
-version=3.8.0
+version=3.9.0
 depends:
     health
 xml:
@@ -7,4 +7,5 @@
     health_surgery_report.xml
     data/health_surgery_sequence.xml
     data/gnuhealth_commands.xml
+    data/messages/messages.xml
     security/access_rights.xml
--- a/tryton/health_surgery/view/gnuhealth_operation_tree.xml
+++ b/tryton/health_surgery/view/gnuhealth_operation_tree.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<tree editable="top">
+<tree editable="1">
     <field name="procedure" expand="1"/>
     <field name="notes" expand="1"/>
 </tree>
--- a/tryton/health_surgery/view/gnuhealth_procedure_tree.xml
+++ b/tryton/health_surgery/view/gnuhealth_procedure_tree.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<tree editable="top">
+<tree editable="1">
     <field name="name"/>
     <field name="description" expand="1"/>
 </tree>
--- a/tryton/health_surgery/view/gnuhealth_surgery_supply_tree.xml
+++ b/tryton/health_surgery/view/gnuhealth_surgery_supply_tree.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<tree editable="top">
+<tree editable="1">
     <field name="qty"/>
     <field name="supply" expand="1"/>
     <field name="qty_used"/>
--- a/tryton/health_surgery/view/gnuhealth_surgery_team_tree.xml
+++ b/tryton/health_surgery/view/gnuhealth_surgery_team_tree.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<tree editable="top">
+<tree editable="1">
     <field name="team_member" expand="1"/>
     <field name="role" expand="1"/>
     <field name="notes"/>