changeset 4814:e159b19e21c2

task #16043: Migration to GNU Health 4.0: Initial migration of health_nursing package
author Luis Falcon <falcon@gnuhealth.org>
date Tue, 21 Dec 2021 00:15:45 +0000
parents 0b12c281e834
children 3e49997e14fa
files tryton/health_nursing/__init__.py tryton/health_nursing/data/health_nursing_sequences.xml tryton/health_nursing/data/messages/messages.xml tryton/health_nursing/exceptions.py tryton/health_nursing/health_nursing.py tryton/health_nursing/sequences.py tryton/health_nursing/tryton.cfg
diffstat 7 files changed, 187 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/tryton/health_nursing/__init__.py
+++ b/tryton/health_nursing/__init__.py
@@ -22,15 +22,16 @@
 ##############################################################################
 
 from trytond.pool import Pool
-from .health_nursing import *
-
+from . import health_nursing
+from . import sequences
 
 def register():
     Pool.register(
-        GnuHealthSequences,
-        GnuHealthSequenceSetup,
-        PatientRounding,
-        RoundingProcedure,
-        PatientAmbulatoryCare,
-        AmbulatoryCareProcedure,
+        health_nursing.PatientRounding,
+        health_nursing.RoundingProcedure,
+        health_nursing.PatientAmbulatoryCare,
+        health_nursing.AmbulatoryCareProcedure,
+        sequences.GnuHealthSequences,
+        sequences.AmbulatoryCareSequence,
+        sequences.PatientRoundingSequence,
         module='health_nursing', type_='model')
--- a/tryton/health_nursing/data/health_nursing_sequences.xml
+++ b/tryton/health_nursing/data/health_nursing_sequences.xml
@@ -5,11 +5,10 @@
         <!-- Sequences for ambulatory_care -->
         <record id="seq_type_gnuhealth_ambulatory_care" model="ir.sequence.type">
             <field name="name">Ambulatory Care</field>
-            <field name="code">gnuhealth.ambulatory_care</field>
         </record>
         <record id="seq_gnuhealth_ambulatory_care" model="ir.sequence">
             <field name="name">Ambulatory Care</field>
-            <field name="code">gnuhealth.ambulatory_care</field>
+            <field name="sequence_type" ref="seq_type_gnuhealth_ambulatory_care"></field>
             <field name="prefix">AC ${year}/</field>
             <field name="padding">3</field>
         </record>
@@ -17,11 +16,10 @@
         <!-- Sequences for patient_rounding -->
         <record id="seq_type_gnuhealth_patient_rounding" model="ir.sequence.type">
             <field name="name">Patient Rounding</field>
-            <field name="code">gnuhealth.patient_rounding</field>
         </record>
         <record id="seq_gnuhealth_patient_rounding" model="ir.sequence">
             <field name="name">Patient Rounding</field>
-            <field name="code">gnuhealth.patient_rounding</field>
+            <field name="sequence_type" ref="seq_type_gnuhealth_patient_rounding"></field>
             <field name="prefix">ROUND ${year}/</field>
             <field name="padding">4</field>
         </record>
new file mode 100644
--- /dev/null
+++ b/tryton/health_nursing/data/messages/messages.xml
@@ -0,0 +1,10 @@
+<?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_no_associated_health_professional">
+            <field name="text">There is no health professional associated to this user</field>
+        </record>
+    </data>
+</tryton>
new file mode 100644
--- /dev/null
+++ b/tryton/health_nursing/exceptions.py
@@ -0,0 +1,9 @@
+# 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 NoAssociatedHealthProfessional(ValidationError):
+    pass
+
--- a/tryton/health_nursing/health_nursing.py
+++ b/tryton/health_nursing/health_nursing.py
@@ -29,95 +29,18 @@
 from trytond.pyson import Eval, Not, Bool, PYSONEncoder, Equal, And, Or, If
 from trytond import backend
 from trytond.tools.multivalue import migrate_property
+from trytond.i18n import gettext
+from trytond.pyson import Id
+from trytond.modules.health.core import get_health_professional
 
+from .exceptions import (
+    NoAssociatedHealthProfessional
+    )
 
-__all__ = ['GnuHealthSequences', 'GnuHealthSequenceSetup',
+__all__ = [
     'PatientRounding', 'RoundingProcedure',
     'PatientAmbulatoryCare', 'AmbulatoryCareProcedure']
 
-sequences = ['ambulatory_care_sequence', 'patient_rounding_sequence']
-
-class GnuHealthSequences(ModelSingleton, ModelSQL, ModelView):
-    "Standard Sequences for GNU Health"
-    __name__ = "gnuhealth.sequences"
-
-    ambulatory_care_sequence = fields.MultiValue(fields.Many2One('ir.sequence',
-        'Health Ambulatory Care', domain=[
-            ('code', '=', 'gnuhealth.ambulatory_care')
-        ]))
-
-    patient_rounding_sequence = fields.MultiValue(fields.Many2One('ir.sequence',
-        'Health Rounding', domain=[
-            ('code', '=', 'gnuhealth.patient.rounding')
-        ]))
-
-    @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_patient_rounding_sequence(cls):
-        return cls.multivalue_model(
-            'patient_rounding_sequence').default_patient_rounding_sequence()
-
-    @classmethod
-    def default_ambulatory_care_sequence(cls):
-        return cls.multivalue_model(
-            'ambulatory_care_sequence').default_ambulatory_care_sequence()
-
-
-# SEQUENCE SETUP
-class GnuHealthSequenceSetup(ModelSQL, ValueMixin):
-    'GNU Health Sequences Setup'
-    __name__ = 'gnuhealth.sequence.setup'
-
-    patient_rounding_sequence = fields.Many2One('ir.sequence', 
-        'Patient Rounding Sequence', required=True,
-        domain=[('code', '=', 'gnuhealth.patient.rounding')])
-
-
-    ambulatory_care_sequence = fields.Many2One('ir.sequence', 
-        'Ambulatory Care Sequence', required=True,
-        domain=[('code', '=', 'gnuhealth.patient.ambulatory_care')])
-  
-    @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_patient_rounding_sequence(cls):
-        pool = Pool()
-        ModelData = pool.get('ir.model.data')
-        return ModelData.get_id(
-            'health_nursing', 'seq_gnuhealth_patient_rounding')
-
-    @classmethod
-    def default_ambulatory_care_sequence(cls):
-        pool = Pool()
-        ModelData = pool.get('ir.model.data')
-        return ModelData.get_id(
-            'health_nursing', 'seq_gnuhealth_ambulatory_care')
-    
-# END SEQUENCE SETUP , MIGRATION FROM FIELDS.MultiValue
-
 
 # Class : PatientRounding
 # Assess the patient and evironment periodically
@@ -223,10 +146,7 @@
 
     @staticmethod
     def default_health_professional():
-        pool = Pool()
-        HealthProf= pool.get('gnuhealth.healthprofessional')
-        healthprof = HealthProf.get_health_professional()
-        return healthprof
+        return get_health_professional()
 
     @staticmethod
     def default_evaluation_start():
@@ -239,10 +159,6 @@
     @classmethod
     def __setup__(cls):
         super(PatientRounding, cls).__setup__()
-        cls._error_messages.update({
-            'health_professional_warning':
-                    'No health professional associated to this user',
-        })
         cls._buttons.update({
             'end_rounding': {
                 'invisible': ~Eval('state').in_(['draft']),
@@ -266,17 +182,22 @@
             'evaluation_end': datetime.now()
             })
 
+
+    @classmethod
+    def generate_code(cls, **pattern):
+        Config = Pool().get('gnuhealth.sequences')
+        config = Config(1)
+        sequence = config.get_multivalue(
+            'patient_rounding_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.patient_rounding_sequence.id)
+                values['code'] = cls.generate_code()
         return super(PatientRounding, cls).create(vlist)
 
 
@@ -288,7 +209,8 @@
 
     def check_health_professional(self):
         if not self.health_professional:
-            self.raise_user_error('health_professional_warning')
+            raise NoAssociatedHealthProfessional(
+                gettext('health.msg_no_associated_health_professional'))
 
     def get_report_start_date(self, name):
         Company = Pool().get('company.company')
@@ -448,10 +370,6 @@
     @classmethod
     def __setup__(cls):
         super(PatientAmbulatoryCare, cls).__setup__()
-        cls._error_messages.update({
-            'health_professional_warning':
-                    'No health professional associated to this user',
-        })
         cls._buttons.update({
             'end_session': {
                 'invisible': ~Eval('state').in_(['draft']),
@@ -483,21 +401,28 @@
 
     def check_health_professional(self):
         if not self.health_professional:
-            self.raise_user_error('health_professional_warning')
+            raise NoAssociatedHealthProfessional(
+                gettext('health.msg_no_associated_health_professional'))
+
+
+    @classmethod
+    def generate_code(cls, **pattern):
+        Config = Pool().get('gnuhealth.sequences')
+        config = Config(1)
+        sequence = config.get_multivalue(
+            'ambulatory_care_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('name'):
-                config = Config(1)
-                values['name'] = Sequence.get_id(
-                    config.ambulatory_care_sequence.id)
+                values['name'] = cls.generate_code()
         return super(PatientAmbulatoryCare, cls).create(vlist)
 
+
     @classmethod
     def copy(cls, ambulatorycares, default=None):
         if default is None:
new file mode 100644
--- /dev/null
+++ b/tryton/health_nursing/sequences.py
@@ -0,0 +1,120 @@
+##############################################################################
+#
+#    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
+ambulatory_care_sequence = fields.Many2One(
+    'ir.sequence', 'Ambulatory Sequence', required=True,
+    domain=[('sequence_type', '=', Id(
+        'health', 'seq_type_gnuhealth_ambulatory_care'))])
+
+patient_rounding_sequence = fields.Many2One(
+    'ir.sequence', 'Patient Rounding Sequence', required=True,
+    domain=[('sequence_type', '=', Id(
+        'health', 'seq_type_gnuhealth_patient_rounding'))])
+
+
+
+# GNU HEALTH SEQUENCES
+class GnuHealthSequences(ModelSingleton, ModelSQL, ModelView, MultiValueMixin):
+    'Standard Sequences for GNU Health'
+    __name__ = 'gnuhealth.sequences'
+
+    ambulatory_care_sequence = fields.MultiValue(
+        ambulatory_care_sequence)
+
+    patient_rounding_sequence = fields.MultiValue(
+        patient_rounding_sequence)
+
+
+    @classmethod
+    def default_ambulatory_care_sequence(cls, **pattern):
+        pool = Pool()
+        ModelData = pool.get('ir.model.data')
+        try:
+            return ModelData.get_id('health',
+                                    'seq_gnuhealth_ambulatory_care')
+        except KeyError:
+            return None
+
+    @classmethod
+    def default_patient_rounding_sequence(cls, **pattern):
+        pool = Pool()
+        ModelData = pool.get('ir.model.data')
+        try:
+            return ModelData.get_id('health',
+                                    'seq_gnuhealth_patient_rounding')
+        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 AmbulatoryCareSequence(_ConfigurationValue, ModelSQL, ValueMixin):
+    'Ambulatory Care Sequences setup'
+    __name__ = 'gnuhealth.sequences.ambulatory_care_sequence'
+    ambulatory_care_sequence = ambulatory_care_sequence
+    _configuration_value_field = 'ambulatory_care_sequence'
+
+    @classmethod
+    def check_xml_record(cls, records, values):
+        return True
+
+
+class PatientRoundingSequence(_ConfigurationValue, ModelSQL, ValueMixin):
+    'Patient Evaluation Sequence setup'
+    __name__ = 'gnuhealth.sequences.patient_rounding_sequence'
+    patient_rounding_sequence = patient_rounding_sequence
+    _configuration_value_field = 'patient_rounding_sequence'
+
+    @classmethod
+    def check_xml_record(cls, records, values):
+        return True
--- a/tryton/health_nursing/tryton.cfg
+++ b/tryton/health_nursing/tryton.cfg
@@ -1,5 +1,5 @@
 [tryton]
-version=3.8.0
+version=3.9.0
 depends:
     health
     health_inpatient
@@ -7,4 +7,5 @@
     health_nursing_view.xml
     health_nursing_report.xml
     data/health_nursing_sequences.xml
+    data/messages/messages.xml
     security/access_rights.xml