changeset 1973:87be956933f9

task #12878: Move ECG class to core
author Chris Zimmerman <siv@riseup.net>
date Sun, 07 Jun 2015 15:58:02 -0700
parents 640138ebba3b
children bb56988563bd
files tryton/health/__init__.py tryton/health/health.py tryton/health/health_view.xml tryton/health/view/gnuhealth_patient_ecg_form.xml tryton/health/view/gnuhealth_patient_ecg_tree.xml tryton/health/view/gnuhealth_patient_form.xml tryton/health_icu/__init__.py tryton/health_icu/health_icu.py tryton/health_icu/health_icu_view.xml tryton/health_icu/view/gnuhealth_icu_ecg_form.xml tryton/health_icu/view/gnuhealth_icu_ecg_tree.xml tryton/health_inpatient/__init__.py tryton/health_inpatient/health_inpatient.py tryton/health_inpatient/health_inpatient_view.xml tryton/health_inpatient/view/ecg_registration.xml
diffstat 13 files changed, 184 insertions(+), 122 deletions(-) [+]
line wrap: on
line diff
--- a/tryton/health/__init__.py
+++ b/tryton/health/__init__.py
@@ -90,6 +90,7 @@
         SecondaryCondition,
         DiagnosticHypothesis,
         SignsAndSymptoms,
+        PatientECG,
         CheckImmunizationStatusInit,
         module='health', type_='model')
     Pool.register(
--- a/tryton/health/health.py
+++ b/tryton/health/health.py
@@ -56,7 +56,7 @@
     'PatientMedication', 'PatientVaccination',
     'PatientPrescriptionOrder', 'PrescriptionLine', 'PatientEvaluation',
     'Directions', 'SecondaryCondition', 'DiagnosticHypothesis',
-    'SignsAndSymptoms']
+    'SignsAndSymptoms', 'PatientECG']
 
 
 class DomiciliaryUnit(ModelSQL, ModelView):
@@ -2506,6 +2506,7 @@
 #        'Prescriptions')
 
     diseases = fields.One2Many('gnuhealth.patient.disease', 'name', 'Diseases')
+    ecgs = fields.One2Many('gnuhealth.patient.ecg', 'name', 'ECGs')
     critical_summary = fields.Function(fields.Text(
         'Important disease about patient allergies or procedures',
         help='Automated summary of patient allergies and '
@@ -4663,3 +4664,119 @@
         domain=[('code', 'like', 'R%')], required=True)
 
     comments = fields.Char('Comments')
+
+# ECG
+class PatientECG(ModelSQL, ModelView):
+    'Patient ECG'
+    __name__ = 'gnuhealth.patient.ecg'
+
+    name = fields.Many2One('gnuhealth.patient',
+        'Patient', required=True)
+
+    ecg_date = fields.DateTime('Date', required=True)
+    lead = fields.Selection([
+        (None, ''),
+        ('i', 'I'),
+        ('ii', 'II'),
+        ('iii', 'III'),
+        ('avf', 'aVF'),
+        ('avr', 'aVR'),
+        ('avl', 'aVL'),
+        ('v1', 'V1'),
+        ('v2', 'V2'),
+        ('v3', 'V3'),
+        ('v4', 'V4'),
+        ('v5', 'V5'),
+        ('v6', 'V6')],
+        'Lead', sort=False)
+
+    axis = fields.Selection([
+        ('normal', 'Normal Axis'),
+        ('left', 'Left deviation'),
+        ('right', 'Right deviation'),
+        ('extreme_right', 'Extreme right deviation')],
+        'Axis', sort=False, required=True)
+
+    rate = fields.Integer('Rate', required=True)
+
+    rhythm = fields.Selection([
+        ('regular', 'Regular'),
+        ('irregular', 'Irregular')],
+        'Rhythm', sort=False, required=True)
+
+    pacemaker = fields.Selection([
+        ('sa', 'Sinus Node'),
+        ('av', 'Atrioventricular'),
+        ('pk', 'Purkinje')
+        ],
+        'Pacemaker', sort=False, required=True)
+
+    pr = fields.Integer('PR', help="Duration of PR interval in milliseconds")
+    qrs = fields.Integer('QRS',
+        help="Duration of QRS interval in milliseconds")
+    qt = fields.Integer('QT', help="Duration of QT interval in milliseconds")
+    st_segment = fields.Selection([
+        ('normal', 'Normal'),
+        ('depressed', 'Depressed'),
+        ('elevated', 'Elevated')],
+        'ST Segment', sort=False, required=True)
+
+    twave_inversion = fields.Boolean('T wave inversion')
+
+    interpretation = fields.Char('Interpretation', required=True)
+    ecg_strip = fields.Binary('ECG Strip')
+
+    # Default ECG date
+    @staticmethod
+    def default_ecg_date():
+        return datetime.now()
+
+    # Return the ECG Interpretation with main components
+    def get_rec_name(self, name):
+        if self.name:
+            res = str(self.interpretation) + ' // Rate ' + str(self.rate)
+        return res
+
+    @classmethod
+    def __register__(cls, module_name):
+
+        cursor = Transaction().cursor
+        TableHandler = backend.get('TableHandler')
+
+        # Rename table to gnuhealth.patient.ecg from gnuhealth_icu_ecg
+        if TableHandler.table_exist(cursor, 'gnuhealth_icu_ecg'):
+            TableHandler.table_rename(cursor, 'gnuhealth_icu_ecg', 'gnuhealth_patient_ecg')
+
+            table = TableHandler(cursor, cls, module_name)
+
+            # Since ECG used to rely on health_icu module
+            # we should try to keep the inpatient registration
+            # information by renaming the column to 
+            # inpatient_registration_code (the new field defined in
+            # the health_inpatient module)
+            table.column_rename('name', 'inpatient_registration_code')
+
+            # Add name column to link to patient
+            # but we'll let the models handle the foreign keys
+            cursor.execute('ALTER TABLE gnuhealth_patient_ecg \
+                            ADD COLUMN name integer')
+
+            # Update the name column with the patient id, not
+            # inpatient registration id
+            cursor.execute('UPDATE gnuhealth_patient_ecg SET name = b.patient \
+                            FROM gnuhealth_inpatient_registration b \
+                            WHERE gnuhealth_patient_ecg.inpatient_registration_code = b.id')
+
+            # Drop the old foreign key(s) (hopefully the correct ones
+            # will be recreated with the correct names by the models)
+            cursor.execute("ALTER TABLE gnuhealth_patient_ecg DROP \
+                    CONSTRAINT IF EXISTS \
+                    gnuhealth_icu_ecg_name_fkey;")
+            cursor.execute("ALTER TABLE gnuhealth_patient_ecg DROP \
+                    CONSTRAINT IF EXISTS \
+                    gnuhealth_icu_ecg_create_uid_fkey;")
+            cursor.execute("ALTER TABLE gnuhealth_patient_ecg DROP \
+                    CONSTRAINT IF EXISTS \
+                    gnuhealth_icu_ecg_write_uid_fkey;")
+
+        super(PatientECG, cls).__register__(module_name)
--- a/tryton/health/health_view.xml
+++ b/tryton/health/health_view.xml
@@ -1438,6 +1438,19 @@
             <field name="name">gnuhealth_signs_and_symptoms_tree</field>
         </record>
 
+<!-- PATIENT ECGS -->
+        <record model="ir.ui.view" id="gnuhealth_patient_ecg_form">
+            <field name="model">gnuhealth.patient.ecg</field>
+            <field name="type">form</field>
+            <field name="name">gnuhealth_patient_ecg_form</field>
+        </record>
+
+        <record model="ir.ui.view" id="gnuhealth_patient_ecg_tree">
+            <field name="model">gnuhealth.patient.ecg</field>
+            <field name="type">tree</field>
+            <field name="name">gnuhealth_patient_ecg_tree</field>
+        </record>
+
 <!-- PATIENT DISEASES -->
 
         <record model="ir.ui.view" id="gnuhealth_patient_diseases_view_form">
rename from tryton/health_icu/view/gnuhealth_icu_ecg_form.xml
rename to tryton/health/view/gnuhealth_patient_ecg_form.xml
rename from tryton/health_icu/view/gnuhealth_icu_ecg_tree.xml
rename to tryton/health/view/gnuhealth_patient_ecg_tree.xml
--- a/tryton/health_icu/view/gnuhealth_icu_ecg_tree.xml
+++ b/tryton/health/view/gnuhealth_patient_ecg_tree.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<tree editable="top" string="Patient ECG Assesment">
+<tree string="Patient ECG Assesment">
     <field name="ecg_date"/>
     <field name="name"/>
     <field name="lead"/>
--- a/tryton/health/view/gnuhealth_patient_form.xml
+++ b/tryton/health/view/gnuhealth_patient_form.xml
@@ -84,6 +84,11 @@
             <field name="medications"/>
             <field name="vaccinations"/>
         </page>
+        <!-- ECGs -->
+        <page string="ECGs" id="patient_ecgs">
+            <field name="ecgs" colspan="4"/>
+        </page>
+
         <!-- Patient Diseases -->
         <page string="Diseases" id="patient_diseases">
             <field name="diseases" colspan="4"/>
--- a/tryton/health_icu/__init__.py
+++ b/tryton/health_icu/__init__.py
@@ -27,12 +27,11 @@
 
 def register():
     Pool.register(
-		InpatientRegistration,
-		InpatientIcu,
-		Glasgow,
-		ApacheII,
-		MechanicalVentilation,
+        InpatientRegistration,
+        InpatientIcu,
+        Glasgow,
+        ApacheII,
+        MechanicalVentilation,
         ChestDrainageAssessment,
-        ECG,
-		PatientRounding,
+        PatientRounding,
         module='health_icu', type_='model')
--- a/tryton/health_icu/health_icu.py
+++ b/tryton/health_icu/health_icu.py
@@ -28,7 +28,7 @@
 
 
 __all__ = ['InpatientRegistration', 'InpatientIcu', 'Glasgow', 'ApacheII',
-            'MechanicalVentilation', 'ChestDrainageAssessment', 'ECG',
+            'MechanicalVentilation', 'ChestDrainageAssessment',
             'PatientRounding']
 
 
@@ -526,78 +526,6 @@
     remarks = fields.Char('Remarks')
 
 
-class ECG(ModelSQL, ModelView):
-    'ECG'
-    __name__ = 'gnuhealth.icu.ecg'
-
-    name = fields.Many2One('gnuhealth.inpatient.registration',
-        'Registration Code', required=True)
-
-    ecg_date = fields.DateTime('Date', required=True)
-    lead = fields.Selection([
-        (None, ''),
-        ('i', 'I'),
-        ('ii', 'II'),
-        ('iii', 'III'),
-        ('avf', 'aVF'),
-        ('avr', 'aVR'),
-        ('avl', 'aVL'),
-        ('v1', 'V1'),
-        ('v2', 'V2'),
-        ('v3', 'V3'),
-        ('v4', 'V4'),
-        ('v5', 'V5'),
-        ('v6', 'V6')],
-        'Lead', sort=False)
-
-    axis = fields.Selection([
-        ('normal', 'Normal Axis'),
-        ('left', 'Left deviation'),
-        ('right', 'Right deviation'),
-        ('extreme_right', 'Extreme right deviation')],
-        'Axis', sort=False, required=True)
-
-    rate = fields.Integer('Rate', required=True)
-
-    rhythm = fields.Selection([
-        ('regular', 'Regular'),
-        ('irregular', 'Irregular')],
-        'Rhythm', sort=False, required=True)
-
-    pacemaker = fields.Selection([
-        ('sa', 'Sinus Node'),
-        ('av', 'Atrioventricular'),
-        ('pk', 'Purkinje')
-        ],
-        'Pacemaker', sort=False, required=True)
-
-    pr = fields.Integer('PR', help="Duration of PR interval in milliseconds")
-    qrs = fields.Integer('QRS',
-        help="Duration of QRS interval in milliseconds")
-    qt = fields.Integer('QT', help="Duration of QT interval in milliseconds")
-    st_segment = fields.Selection([
-        ('normal', 'Normal'),
-        ('depressed', 'Depressed'),
-        ('elevated', 'Elevated')],
-        'ST Segment', sort=False, required=True)
-
-    twave_inversion = fields.Boolean('T wave inversion')
-
-    interpretation = fields.Char('Interpretation', required=True)
-    ecg_strip = fields.Binary('ECG Strip')
-
-    # Default ECG date
-    @staticmethod
-    def default_ecg_date():
-        return datetime.now()
-
-    # Return the ECG Interpretation with main components
-    def get_rec_name(self, name):
-        if self.name:
-            res = str(self.interpretation) + ' // Rate ' + str(self.rate)
-        return res
-
-
 class PatientRounding(ModelSQL, ModelView):
     # Nursing Rounding for ICU
     # Inherit and append to the existing model the new functionality for ICU
@@ -686,8 +614,9 @@
 
     # Cardiovascular assessment
 
-    ecg = fields.Many2One('gnuhealth.icu.ecg', 'ECG',
-        domain=[('name', '=', Eval('name'))], depends=['name'],)
+    ecg = fields.Many2One('gnuhealth.patient.ecg', 'Inpatient ECG',
+        domain=[('inpatient_registration_code', '=', Eval('name'))],
+        depends=['name'],)
 
     venous_access = fields.Selection([
         (None, ''),
--- a/tryton/health_icu/health_icu_view.xml
+++ b/tryton/health_icu/health_icu_view.xml
@@ -55,7 +55,7 @@
         <record model="ir.action.act_window" id="act_glasgow_form1">
             <field name="name">Glasgow Coma Scale</field>
             <field name="res_model">gnuhealth.icu.glasgow</field>
-            <field name="domain">[('name', '=', Eval('active_id'))]</field>
+            <field name="domain">[('name.icu_admissions', '=', Eval('active_id'))]</field>
         </record>
         <record model="ir.action.keyword"
                 id="act_open_glasgow_keyword1">
@@ -108,7 +108,7 @@
         <record model="ir.action.act_window" id="act_apache_form1">
             <field name="name">APACHE II</field>
             <field name="res_model">gnuhealth.icu.apache2</field>
-            <field name="domain">[('name', '=', Eval('active_id'))]</field>
+            <field name="domain">[('name.icu_admissions', '=', Eval('active_id'))]</field>
         </record>
         <record model="ir.action.keyword"
                 id="act_open_apache_keyword1">
@@ -167,51 +167,24 @@
             <field name="type">tree</field>
             <field name="name">gnuhealth_icu_chest_drainage_tree</field>
         </record>
-                
 
-<!-- ECG -->
 
-        <record model="ir.ui.view" id="gnuhealth_icu_ecg_form">
-            <field name="model">gnuhealth.icu.ecg</field>
-            <field name="type">form</field>
-            <field name="name">gnuhealth_icu_ecg_form</field>
-        </record>
-
-
-        <record model="ir.ui.view" id="gnuhealth_icu_ecg_tree">
-            <field name="model">gnuhealth.icu.ecg</field>
-            <field name="type">tree</field>
-            <field name="name">gnuhealth_icu_ecg_tree</field>
-        </record>
-                
+<!-- Add explicit ECG menu item to ICU -->
 
         <record model="ir.action.act_window" id="action_gnuhealth_icu_ecg_form">
-            <field name="name">ECG</field>
-            <field name="res_model">gnuhealth.icu.ecg</field>
-        </record>
-
-        <record model="ir.action.act_window.view" id="act_gnuhealth_icu_ecg_tree">
-            <field name="sequence" eval="10"/>
-            <field name="view" ref="gnuhealth_icu_ecg_tree"/>
-            <field name="act_window" ref="action_gnuhealth_icu_ecg_form"/>
-        </record>
-
-        <record model="ir.action.act_window.view" id="act_gnuhealth_icu_ecg_form">
-            <field name="sequence" eval="20"/>
-            <field name="view" ref="gnuhealth_icu_ecg_form"/>
-            <field name="act_window" ref="action_gnuhealth_icu_ecg_form"/>
+            <field name="name">ECGs</field>
+            <field name="res_model">gnuhealth.patient.ecg</field>
         </record>
 
         <menuitem action="action_gnuhealth_icu_ecg_form"
-            id="menu_gnuhealth_icu_ecg_list" icon="gnuhealth-list"
+            id="menu_gnuhealth_icu_ecgs_list1" icon="gnuhealth-list"
             parent="gnuhealth_icu_menu"/>
-					
 
-<!-- Shortcut to the ECG from the Inpatient ICU section -->
+<!-- Shortcut to the inpatient ECG from the inpatient ICU section -->
         <record model="ir.action.act_window" id="act_ecg_form1">
-            <field name="name">ECG</field>
-            <field name="res_model">gnuhealth.icu.ecg</field>
-            <field name="domain">[('name', '=', Eval('active_id'))]</field>
+            <field name="name">Inpatient ECGs</field>
+            <field name="res_model">gnuhealth.patient.ecg</field>
+            <field name="domain">[('inpatient_registration_code.icu_admissions', '=', Eval('active_id'))]</field>
         </record>
         <record model="ir.action.keyword"
                 id="act_open_ecg_keyword1">
--- a/tryton/health_inpatient/__init__.py
+++ b/tryton/health_inpatient/__init__.py
@@ -33,6 +33,7 @@
         InpatientRegistration,
         BedTransfer,
         Appointment,
+        ECG,
         PatientData,
         InpatientMedication,
         InpatientMedicationAdminTimes,
--- a/tryton/health_inpatient/health_inpatient.py
+++ b/tryton/health_inpatient/health_inpatient.py
@@ -32,7 +32,7 @@
     'BedTransfer', 'Appointment', 'PatientData',
     'InpatientMedication', 'InpatientMedicationAdminTimes',
     'InpatientMedicationLog', 'InpatientDiet', 'InpatientMeal',
-    'InpatientMealOrder','InpatientMealOrderItem']
+    'InpatientMealOrder','InpatientMealOrderItem', 'ECG']
 
 
 class InpatientSequences(ModelSingleton, ModelSQL, ModelView):
@@ -330,6 +330,14 @@
         'gnuhealth.inpatient.registration', 'Inpatient Registration',
         help="Enter the patient hospitalization code")
 
+class ECG(ModelSQL, ModelView):
+    'Add Inpatient Registration field to the ECG model.'
+    __name__ = 'gnuhealth.patient.ecg'
+
+    inpatient_registration_code = fields.Many2One(
+        'gnuhealth.inpatient.registration', 'Inpatient Registration',
+        help="Enter the patient hospitalization code")
+
 
 class PatientData(ModelSQL, ModelView):
     'Inherit patient model and add the patient status to the patient.'
--- a/tryton/health_inpatient/health_inpatient_view.xml
+++ b/tryton/health_inpatient/health_inpatient_view.xml
@@ -99,6 +99,15 @@
             <field name="name">gnuhealth_patient_extd_tree</field>
         </record>
 
+<!-- Add the patient hospitalization registration code to the ecg view -->
+
+        <record model="ir.ui.view" id="view_ecg_registration_form1">
+            <field name="model">gnuhealth.patient.ecg</field>
+            <field name="inherit" ref="health.gnuhealth_patient_ecg_form" />
+            <field name="type">form</field>
+            <field name="name">ecg_registration</field>
+        </record>
+
 <!-- Inpatient Medication -->
 
 
new file mode 100644
--- /dev/null
+++ b/tryton/health_inpatient/view/ecg_registration.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<data>
+    <xpath expr="/form/field[@name=&quot;name&quot;]" position="after">
+        <label name="inpatient_registration_code"/>
+        <field name="inpatient_registration_code"/>
+    </xpath>
+</data>