changeset 4863:3a5171e5694f

task #16043: Migration to GNU Health 4.0: Migrate and cleanup health_reporting
author Luis Falcon <falcon@gnuhealth.org>
date Fri, 14 Jan 2022 22:38:45 +0000
parents bcdb9d00c7b3
children 96858aa3c1f3
files tryton/health_reporting/__init__.py tryton/health_reporting/report/epidemics_report.py tryton/health_reporting/report/female_symbol.png tryton/health_reporting/report/male_symbol.png tryton/health_reporting/report/summary_report.py tryton/health_reporting/tryton.cfg tryton/health_reporting/wizard/wizard_epidemics_report.py tryton/health_reporting/wizard/wizard_evaluations.py tryton/health_reporting/wizard/wizard_summary_report.py tryton/health_reporting/wizard/wizard_top_diseases.py
diffstat 10 files changed, 218 insertions(+), 237 deletions(-) [+]
line wrap: on
line diff
--- a/tryton/health_reporting/__init__.py
+++ b/tryton/health_reporting/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    GNU Health: The Free Health and Hospital Information System
@@ -20,29 +19,29 @@
 ##############################################################################
 
 from trytond.pool import Pool
-from .wizard import *
-from .report import *
+from . import wizard
+from . import report
+
 
 def register():
     Pool.register(
-        TopDiseases,
-        OpenTopDiseasesStart,
-        OpenEvaluationsStart,
-        SummaryReportStart,
-        EpidemicsReportStart,
-        EvaluationsDoctor,
-        EvaluationsSpecialty,
-        EvaluationsSector,
+        wizard.wizard_top_diseases.TopDiseases,
+        wizard.wizard_top_diseases.OpenTopDiseasesStart,
+        wizard.wizard_evaluations.OpenEvaluationsStart,
+        wizard.wizard_summary_report.SummaryReportStart,
+        wizard.wizard_evaluations.EvaluationsDoctor,
+        wizard.wizard_evaluations.EvaluationsSpecialty,
+        wizard.wizard_evaluations.EvaluationsSector,
+        wizard.wizard_epidemics_report.EpidemicsReportStart,
         module='health_reporting', type_='model')
     Pool.register(
-        OpenTopDiseases,
-        OpenEvaluations,
-        SummaryReport,
-        EpidemicsReport,
+        wizard.wizard_top_diseases.OpenTopDiseases,
+        wizard.wizard_evaluations.OpenEvaluations,
+        wizard.wizard_summary_report.SummaryReport,
+        wizard.wizard_epidemics_report.EpidemicsReport,
         module='health_reporting', type_='wizard')
 
     Pool.register(
-        InstitutionSummaryReport,
-        InstitutionEpidemicsReport,
+        report.summary_report.InstitutionSummaryReport,
+        report.epidemics_report.InstitutionEpidemicsReport,
         module='health_reporting', type_='report')
-
--- a/tryton/health_reporting/report/epidemics_report.py
+++ b/tryton/health_reporting/report/epidemics_report.py
@@ -24,23 +24,23 @@
 from trytond.pool import Pool
 from trytond.transaction import Transaction
 from dateutil.relativedelta import relativedelta
-import pytz
 
 from matplotlib import pyplot as plt
 from matplotlib.ticker import MaxNLocator
 
-from trytond.modules.health.health import convert_date_timezone
+from trytond.modules.health.core import convert_date_timezone
 
 import io
 
 __all__ = ['InstitutionEpidemicsReport']
 
+
 class InstitutionEpidemicsReport(Report):
     __name__ = 'gnuhealth.epidemics.report'
 
     @classmethod
     def get_population_with_no_dob(cls):
-        """ Return Total Number of living people in the system 
+        """ Return Total Number of living people in the system
         without a date of birth"""
         cursor = Transaction().connection.cursor()
 
@@ -54,22 +54,22 @@
         return(res)
 
     @classmethod
-    def get_population(cls,date1,date2,gender,total):
-        """ Return Total Number of living people in the system 
+    def get_population(cls, date1, date2, gender, total):
+        """ Return Total Number of living people in the system
         segmented by age group and gender"""
         cursor = Transaction().connection.cursor()
 
         if (total):
             cursor.execute("SELECT COUNT(id) \
                 FROM party_party WHERE \
-                gender = %s and deceased is not TRUE",(gender))
+                gender = %s and deceased is not TRUE", (gender))
 
         else:
             cursor.execute("SELECT COUNT(id) \
                 FROM party_party \
                 WHERE dob BETWEEN %s and %s AND \
                 gender = %s  \
-                and deceased is not TRUE" ,(date2, date1, gender))
+                and deceased is not TRUE", (date2, date1, gender))
 
         res = cursor.fetchone()[0]
 
@@ -86,7 +86,7 @@
         if (in_health_system):
             query = query + " and is_patient=True"
         cursor = Transaction().connection.cursor()
-        cursor.execute(query,(start_date, end_date))
+        cursor.execute(query, (start_date, end_date))
         res = cursor.fetchone()
         return(res)
 
@@ -100,7 +100,7 @@
             %s AND %s"
 
         cursor = Transaction().connection.cursor()
-        cursor.execute(query,(start_date, end_date))
+        cursor.execute(query, (start_date, end_date))
 
         res = cursor.fetchone()
         return(res)
@@ -115,8 +115,8 @@
             WHERE date_trunc('day', dod) BETWEEN \
             %s AND %s"
 
-        cursor = Transaction().connection.cursor() 
-        cursor.execute(query,(start_date, end_date))
+        cursor = Transaction().connection.cursor()
+        cursor.execute(query, (start_date, end_date))
 
         res = cursor.fetchone()
         return(res)
@@ -159,15 +159,14 @@
 
             res = Condition.search(clause)
             cases_day = len(res)
-            daily_data = {'date':current_day, 'cases':cases_day}
+            daily_data = {'date': current_day, 'cases': cases_day}
             aggr.append(daily_data)
         return(aggr)
 
-
     # Death Certificates by day
     @classmethod
     def get_deaths_by_day(cls, start_date, end_date, dx):
-        """ Return number of death related to the condition 
+        """ Return number of death related to the condition
             Includes both the ultimate case as well as those
             certificates that have the condition as a leading cause
         """
@@ -179,9 +178,9 @@
         while current_day <= end_date:
             cur_day_time = datetime.combine((current_day), datetime.min.time())
 
-            utc_from =  convert_date_timezone(cur_day_time, 'utc')
-            utc_to =  convert_date_timezone(cur_day_time +
-                                            relativedelta(days=1), 'utc')
+            utc_from = convert_date_timezone(cur_day_time, 'utc')
+            utc_to = convert_date_timezone(cur_day_time +
+                                           relativedelta(days=1), 'utc')
 
             clause = [
                 ('dod', '>=', utc_from),
@@ -204,34 +203,33 @@
                     if (underlying_condition.condition.id == dx):
                         as_underlying_condition = as_underlying_condition + 1
 
-            daily_data = {'date':current_day,
-                          'certs_day_ic':as_immediate_cause,
-                          'certs_day_uc':as_underlying_condition}
+            daily_data = {'date': current_day,
+                          'certs_day_ic': as_immediate_cause,
+                          'certs_day_uc': as_underlying_condition}
             aggr.append(daily_data)
             current_day = current_day + relativedelta(days=1)
 
         return(aggr)
 
-
     @classmethod
     def plot_cases_timeseries(cls, start_date, end_date,
-                             health_condition_id, hc):
+                              health_condition_id, hc):
 
         epi_series = cls.get_epi_by_day(start_date,
                                         end_date, health_condition_id)
 
-        days=[]
-        cases_day=[]
+        days = []
+        cases_day = []
         for day in epi_series:
             days.append(day['date'])
             # Confirmed cases by day
             cases_day.append(day['cases'])
 
-        fig = plt.figure(figsize=(6,3))
+        fig = plt.figure(figsize=(6, 3))
         cases_by_day = fig.add_subplot(1, 1, 1)
         title = 'New cases by day: ' + hc.rec_name
         cases_by_day.set_title(title)
-        cases_by_day.bar(days,cases_day)
+        cases_by_day.bar(days, cases_day)
         cases_by_day.yaxis.set_major_locator(MaxNLocator(integer=True))
         fig.autofmt_xdate()
 
@@ -242,17 +240,16 @@
         holder.close()
         return (image_png)
 
-
     @classmethod
     def plot_deaths_timeseries(cls, start_date,
-                              end_date, health_condition_id, hc):
+                               end_date, health_condition_id, hc):
 
         death_certs = cls.get_deaths_by_day(start_date,
                                             end_date, health_condition_id)
 
-        days=[]
-        certs_ic_day=[]
-        certs_uc_day=[]
+        days = []
+        certs_ic_day = []
+        certs_uc_day = []
         for day in death_certs:
             days.append(day['date'])
             # Death certificates as an immediate cause
@@ -261,11 +258,11 @@
             certs_uc_day.append(day['certs_day_uc'])
 
         title = "New deaths by day: " + hc.rec_name
-        fig = plt.figure(figsize=(6,3))
+        fig = plt.figure(figsize=(6, 3))
         deaths_by_day = fig.add_subplot(1, 1, 1)
         deaths_by_day.set_title(title)
-        deaths_by_day.plot(days,certs_ic_day, label="immediate cause")
-        deaths_by_day.plot(days,certs_uc_day, label="underlying condition")
+        deaths_by_day.plot(days, certs_ic_day, label="immediate cause")
+        deaths_by_day.plot(days, certs_uc_day, label="underlying condition")
         deaths_by_day.yaxis.set_major_locator(MaxNLocator(integer=True))
         deaths_by_day.legend()
 
@@ -278,17 +275,16 @@
         holder.close()
         return (image_png)
 
-
     @classmethod
-    def plot_cases_ethnicity(cls,start_date,end_date,ethnic_count, hc):
+    def plot_cases_ethnicity(cls, start_date, end_date, ethnic_count, hc):
 
         for k, v in list(ethnic_count.items()):
-            if (v==0):
+            if (v == 0):
                 # Remove ethnicities with zero cases from the plot
                 del(ethnic_count[k])
 
         title = "Cases by ethnic group: " + hc.rec_name
-        fig = plt.figure(figsize=(6,3))
+        fig = plt.figure(figsize=(6, 3))
         cases_by_ethnicity = fig.add_subplot(1, 1, 1)
         cases_by_ethnicity.set_title(title)
         cases_by_ethnicity.pie(ethnic_count.values(),
@@ -304,10 +300,9 @@
         holder.close()
         return (image_png)
 
-
     @classmethod
     def get_ethnic_groups(cls):
-        #Build a list with the ethnic groups
+        # Build a list with the ethnic groups
         Condition = Pool().get('gnuhealth.ethnicity')
         ethnic_groups = Condition.search([])
         ethnicities = []
@@ -315,22 +310,21 @@
             ethnicities.append(ethnic_group.name)
         return (ethnicities)
 
-
     @classmethod
-    def plot_cases_socioeconomics(cls,start_date,end_date,ses_count, hc):
+    def plot_cases_socioeconomics(cls, start_date, end_date, ses_count, hc):
 
         for k, v in list(ses_count.items()):
-            if (v==0):
+            if (v == 0):
                 # Remove socioeconomic groups with zero cases from the plot
                 del(ses_count[k])
 
         title = "Cases by Socioeconomic groups: " + hc.rec_name
-        fig = plt.figure(figsize=(6,3))
+        fig = plt.figure(figsize=(6, 3))
         cases_by_socioeconomics = fig.add_subplot(1, 1, 1)
         cases_by_socioeconomics.set_title(title)
         cases_by_socioeconomics.pie(ses_count.values(),
-                               autopct='%1.1f%%',
-                               labels=ses_count.keys())
+                                    autopct='%1,1f%%',
+                                    labels=ses_count.keys())
 
         fig.autofmt_xdate()
 
@@ -354,7 +348,8 @@
 
         ses_count = {}
 
-        ses_groups = ['lower','lower-middle','middle','upper-middle','upper']
+        ses_groups = ['lower', 'lower-middle', 'middle', 'upper-middle',
+                      'upper']
         for ses_group in ses_groups:
             ses_count[ses_group] = 0
 
@@ -367,7 +362,6 @@
         end_date = data['end_date']
         context['end_date'] = data['end_date']
 
-        demographics = data['demographics']
         context['demographics'] = data['demographics']
 
         health_condition_id = data['health_condition']
@@ -380,11 +374,11 @@
         # Demographics
         today = date.today()
 
-        context[''.join(['p','total_','f'])] = \
-            cls.get_population (None,None,'f', total=True)
+        context[''.join(['p', 'total_', 'f'])] = \
+            cls.get_population(None, None, 'f', total=True)
 
-        context[''.join(['p','total_','m'])] = \
-            cls.get_population (None,None,'m', total=True)
+        context[''.join(['p', 'total_', 'm'])] = \
+            cls.get_population(None, None, 'm', total=True)
 
         # Living people with NO date of birth
         context['no_dob'] = \
@@ -392,25 +386,23 @@
 
         # Build the Population Pyramid for registered people
 
-        for age_group in range (0,21):
+        for age_group in range(0, 21):
             date1 = today - relativedelta(years=(age_group*5))
             date2 = today - relativedelta(years=((age_group*5)+5), days=-1)
 
-            context[''.join(['p',str(age_group),'f'])] = \
-                cls.get_population (date1,date2,'f', total=False)
-            context[''.join(['p',str(age_group),'m'])] = \
-                cls.get_population (date1,date2,'m', total=False)
-
+            context[''.join(['p', str(age_group), 'f'])] = \
+                cls.get_population(date1, date2, 'f', total=False)
+            context[''.join(['p', str(age_group), 'm'])] = \
+                cls.get_population(date1, date2, 'm', total=False)
 
         # Count those lucky over 105 years old :)
         date1 = today - relativedelta(years=105)
         date2 = today - relativedelta(years=200)
 
         context['over105f'] = \
-            cls.get_population (date1,date2,'f', total=False)
+            cls.get_population(date1, date2, 'f', total=False)
         context['over105m'] = \
-            cls.get_population (date1,date2,'m', total=False)
-
+            cls.get_population(date1, date2, 'm', total=False)
 
         # Count registered people, and those within the system of health
         context['new_people'] = \
@@ -433,42 +425,41 @@
 
         context['confirmed_cases'] = confirmed_cases
 
-        epidemics_dx =[]
+        epidemics_dx = []
         non_age_cases = 0
         cases_f = 0
         cases_m = 0
 
-
         # Global Condition info
         for confirmed_case in confirmed_cases:
-            #Sex distribution
+            # Sex distribution
             if (confirmed_case.name.gender == 'f'):
-                cases_f +=1
+                cases_f += 1
             else:
-                cases_m +=1
+                cases_m += 1
 
-            #Ethnic groups distribution
+            # Ethnic groups distribution
             if (confirmed_case.name.name.ethnic_group):
                 ethnicity = confirmed_case.name.name.ethnic_group.name
                 if (ethnicity in ethnic_groups):
-                    ethnic_count[ethnicity] =  ethnic_count[ethnicity] + 1
+                    ethnic_count[ethnicity] = ethnic_count[ethnicity] + 1
 
-            #Socioeconomic groups distribution
+            # Socioeconomic groups distribution
             if (confirmed_case.name.ses):
                 ses_id = confirmed_case.name.ses
                 if (ses_id == '0'):
-                    ses_count['lower'] +=1
+                    ses_count['lower'] += 1
                 if (ses_id == '1'):
-                    ses_count['lower-middle'] +=1
+                    ses_count['lower-middle'] += 1
                 if (ses_id == '2'):
-                    ses_count['middle'] +=1
+                    ses_count['middle'] += 1
                 if (ses_id == '3'):
-                    ses_count['upper-middle'] +=1
+                    ses_count['upper-middle'] += 1
                 if (ses_id == '4'):
-                    ses_count['upper'] +=1
+                    ses_count['upper'] += 1
 
             if not confirmed_case.name.age:
-                non_age_cases +=1
+                non_age_cases += 1
 
         total_cases = len(confirmed_cases)
 
@@ -480,29 +471,27 @@
         group_1 = group_2 = group_3 = group_4 = group_5 = 0
         group_1f = group_2f = group_3f = group_4f = group_5f = 0
 
-
         for case in confirmed_cases:
 
             if (case.name.age):
 
-                #Strip to get the raw year
+                # Strip to get the raw year
                 age = int(case.name.age.split(' ')[0][:-1])
 
-
                 # Age groups in this diagnostic
                 if (age < 5):
                     group_1 += 1
                     if (case.name.gender == 'f'):
                         group_1f += 1
-                if (age in range(5,14)):
+                if (age in range(5, 14)):
                     group_2 += 1
                     if (case.name.gender == 'f'):
                         group_2f += 1
-                if (age in range(15,45)):
+                if (age in range(15, 45)):
                     group_3 += 1
                     if (case.name.gender == 'f'):
                         group_3f += 1
-                if (age in range(46,60)):
+                if (age in range(46, 60)):
                     group_4 += 1
                     if (case.name.gender == 'f'):
                         group_4f += 1
@@ -512,12 +501,12 @@
                         group_5f += 1
 
         cases = {'diagnosis': health_condition_id,
-            'age_group_1': group_1, 'age_group_1f': group_1f,
-            'age_group_2': group_2, 'age_group_2f': group_2f,
-            'age_group_3': group_3, 'age_group_3f': group_3f,
-            'age_group_4': group_4, 'age_group_4f': group_4f,
-            'age_group_5': group_5, 'age_group_5f': group_5f,
-            'total': total_cases,}
+                 'age_group_1': group_1, 'age_group_1f': group_1f,
+                 'age_group_2': group_2, 'age_group_2f': group_2f,
+                 'age_group_3': group_3, 'age_group_3f': group_3f,
+                 'age_group_4': group_4, 'age_group_4f': group_4f,
+                 'age_group_5': group_5, 'age_group_5f': group_5f,
+                 'total': total_cases, }
 
         # Append into the report list the resulting
         # dictionary entry
@@ -527,21 +516,25 @@
         context['epidemics_dx'] = epidemics_dx
 
         # New cases by day
-        context['cases_timeseries'] = cls.plot_cases_timeseries(start_date,
-                                                end_date,
-                                                health_condition_id, hc)
+        context['cases_timeseries'] = cls.plot_cases_timeseries(
+            start_date,
+            end_date,
+            health_condition_id, hc)
 
-        #Cases by ethnic groups
-        context['cases_ethnicity'] = cls.plot_cases_ethnicity(start_date,
-                                                end_date,ethnic_count, hc)
+        # Cases by ethnic groups
+        context['cases_ethnicity'] = cls.plot_cases_ethnicity(
+            start_date,
+            end_date, ethnic_count, hc)
 
-        #Cases by Socioeconomic groups
-        context['cases_ses'] = cls.plot_cases_socioeconomics(start_date,
-                                                end_date,ses_count, hc)
+        # Cases by Socioeconomic groups
+        context['cases_ses'] = cls.plot_cases_socioeconomics(
+            start_date,
+            end_date, ses_count, hc)
 
         # Death certificates by day
-        context['deaths_timeseries'] = cls.plot_deaths_timeseries(start_date,
-                                                end_date,
-                                                health_condition_id, hc)
+        context['deaths_timeseries'] = cls.plot_deaths_timeseries(
+            start_date,
+            end_date,
+            health_condition_id, hc)
 
         return context
deleted file mode 100644
index 517fc676bb9a5c7d18efbb3bc89d73005dda959b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 80b1cb07f4287cf337b9ef02c8fce566999f4c01..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/tryton/health_reporting/report/summary_report.py
+++ b/tryton/health_reporting/report/summary_report.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    GNU Health: The Free Health and Hospital Information System
@@ -27,13 +26,13 @@
 
 __all__ = ['InstitutionSummaryReport']
 
+
 class InstitutionSummaryReport(Report):
     __name__ = 'gnuhealth.summary.report'
 
-
     @classmethod
     def get_population_with_no_dob(cls):
-        """ Return Total Number of living people in the system 
+        """ Return Total Number of living people in the system
         without a date of birth"""
         cursor = Transaction().connection.cursor()
 
@@ -43,62 +42,61 @@
             deceased is not TRUE and dob is null")
 
         res = cursor.fetchone()[0]
-    
+
         return(res)
 
     @classmethod
-    def get_population(cls,date1,date2,gender,total):
-        """ Return Total Number of living people in the system 
+    def get_population(cls, date1, date2, gender, total):
+        """ Return Total Number of living people in the system
         segmented by age group and gender"""
         cursor = Transaction().connection.cursor()
 
         if (total):
             cursor.execute("SELECT COUNT(id) \
                 FROM party_party WHERE \
-                gender = %s and deceased is not TRUE",(gender))
+                gender = %s and deceased is not TRUE", (gender))
 
         else:
             cursor.execute("SELECT COUNT(id) \
                 FROM party_party \
                 WHERE dob BETWEEN %s and %s AND \
                 gender = %s  \
-                and deceased is not TRUE" ,(date2, date1, gender))
+                and deceased is not TRUE", (date2, date1, gender))
 
-       
         res = cursor.fetchone()[0]
-    
+
         return(res)
 
     @classmethod
     def get_new_people(cls, start_date, end_date, in_health_system):
         """ Return Total Number of new registered persons alive """
-        
+
         query = "SELECT COUNT(activation_date) \
             FROM party_party \
             WHERE activation_date BETWEEN \
             %s AND %s and is_person=True and deceased is not TRUE"
-         
+
         if (in_health_system):
             query = query + " and is_patient=True"
-            
+
         cursor = Transaction().connection.cursor()
-        cursor.execute(query,(start_date, end_date))
-       
+        cursor.execute(query, (start_date, end_date))
+
         res = cursor.fetchone()
         return(res)
 
     @classmethod
     def get_new_births(cls, start_date, end_date):
         """ Return birth certificates within that period """
-        
+
         query = "SELECT COUNT(dob) \
             FROM gnuhealth_birth_certificate \
             WHERE dob BETWEEN \
             %s AND %s"
-            
+
         cursor = Transaction().connection.cursor()
-        cursor.execute(query,(start_date, end_date))
-       
+        cursor.execute(query, (start_date, end_date))
+
         res = cursor.fetchone()
         return(res)
 
@@ -106,48 +104,48 @@
     def get_new_deaths(cls, start_date, end_date):
         """ Return death certificates within that period """
         """ Truncate the timestamp of DoD to match a whole day"""
-    
+
         query = "SELECT COUNT(dod) \
             FROM gnuhealth_death_certificate \
             WHERE date_trunc('day', dod) BETWEEN \
             %s AND %s"
-            
-        cursor = Transaction().connection.cursor() 
-        cursor.execute(query,(start_date, end_date))
-       
+
+        cursor = Transaction().connection.cursor()
+        cursor.execute(query, (start_date, end_date))
+
         res = cursor.fetchone()
         return(res)
 
     @classmethod
     def get_evaluations(cls, start_date, end_date, dx):
         """ Return evaluation info """
-        
+
         Evaluation = Pool().get('gnuhealth.patient.evaluation')
         start_date = datetime.strptime(str(start_date), '%Y-%m-%d')
         end_date = datetime.strptime(str(end_date), '%Y-%m-%d')
-        end_date += relativedelta(hours=+23,minutes=+59,seconds=+59)
-        
+        end_date += relativedelta(hours=+23, minutes=+59, seconds=+59)
+
         clause = [
             ('evaluation_start', '>=', start_date),
             ('evaluation_start', '<=', end_date),
             ]
-                
+
         if dx:
             clause.append(('diagnosis', '=', dx))
-            
+
         res = Evaluation.search(clause)
-        
+
         return(res)
 
     @classmethod
     def count_evaluations(cls, start_date, end_date, dx):
         """ count diagnoses by groups """
-        
+
         Evaluation = Pool().get('gnuhealth.patient.evaluation')
         start_date = datetime.strptime(str(start_date), '%Y-%m-%d')
         end_date = datetime.strptime(str(end_date), '%Y-%m-%d')
-        end_date += relativedelta(hours=+23,minutes=+59,seconds=+59)
-        
+        end_date += relativedelta(hours=+23, minutes=+59, seconds=+59)
+
         clause = [
             ('evaluation_start', '>=', start_date),
             ('evaluation_start', '<=', end_date),
@@ -155,64 +153,55 @@
             ]
 
         res = Evaluation.search_count(clause)
-        
+
         return(res)
 
-
     @classmethod
     def get_context(cls, records, data):
-        Patient = Pool().get('gnuhealth.patient')
-        Evaluation = Pool().get('gnuhealth.patient.evaluation')
-
-        context = super(InstitutionSummaryReport, cls).get_context(records, data)
+        context = super(
+            InstitutionSummaryReport, cls).get_context(records, data)
 
         start_date = data['start_date']
         end_date = data['end_date']
 
-        demographics = data['demographics']
         context['demographics'] = data['demographics']
+        context['patient_evaluations'] = data['patient_evaluations']
 
-        patient_evaluations = data['patient_evaluations']
-        context['patient_evaluations'] = data['patient_evaluations']
-        
         context['start_date'] = data['start_date']
         context['end_date'] = data['end_date']
 
         # Demographics
         today = date.today()
 
-        context[''.join(['p','total_','f'])] = \
-            cls.get_population (None,None,'f', total=True)
+        context[''.join(['p', 'total_', 'f'])] = \
+            cls.get_population(None, None, 'f', total=True)
 
-        context[''.join(['p','total_','m'])] = \
-            cls.get_population (None,None,'m', total=True)
-        
+        context[''.join(['p', 'total_', 'm'])] = \
+            cls.get_population(None, None, 'm', total=True)
+
         # Living people with NO date of birth
         context['no_dob'] = \
             cls.get_population_with_no_dob()
 
         # Build the Population Pyramid for registered people
-
-        for age_group in range (0,21):
+        for age_group in range(0, 21):
             date1 = today - relativedelta(years=(age_group*5))
             date2 = today - relativedelta(years=((age_group*5)+5), days=-1)
-            
-            context[''.join(['p',str(age_group),'f'])] = \
-                cls.get_population (date1,date2,'f', total=False)
-            context[''.join(['p',str(age_group),'m'])] = \
-                cls.get_population (date1,date2,'m', total=False)
 
+            context[''.join(['p', str(age_group), 'f'])] = \
+                cls.get_population(date1, date2, 'f', total=False)
+            context[''.join(['p', str(age_group), 'm'])] = \
+                cls.get_population(date1, date2, 'm', total=False)
 
         # Count those lucky over 105 years old :)
         date1 = today - relativedelta(years=105)
         date2 = today - relativedelta(years=200)
 
         context['over105f'] = \
-            cls.get_population (date1,date2,'f', total=False)
+            cls.get_population(date1, date2, 'f', total=False)
         context['over105m'] = \
-            cls.get_population (date1,date2,'m', total=False)
+            cls.get_population(date1, date2, 'm', total=False)
 
-        
         # Count registered people, and those within the system of health
         context['new_people'] = \
             cls.get_new_people(start_date, end_date, False)
@@ -222,24 +211,24 @@
         # New births
         context['new_births'] = \
             cls.get_new_births(start_date, end_date)
-        
+
         # New deaths
         context['new_deaths'] = \
             cls.get_new_deaths(start_date, end_date)
 
         # Get evaluations within the specified date range
-        
+
         context['evaluations'] = \
             cls.get_evaluations(start_date, end_date, None)
-        
+
         evaluations = cls.get_evaluations(start_date, end_date, None)
-        
-        eval_dx =[]
+
+        eval_dx = []
         non_dx_eval = 0
         non_age_eval = 0
         eval_f = 0
         eval_m = 0
-        
+
         # Global Evaluation info
         for evaluation in evaluations:
             if evaluation.diagnosis:
@@ -248,24 +237,24 @@
                 # Increase the evaluations without Dx counter
                 non_dx_eval += 1
             if (evaluation.gender == 'f'):
-                eval_f +=1
+                eval_f += 1
             else:
-                eval_m +=1
+                eval_m += 1
 
             if not evaluation.computed_age:
-                non_age_eval +=1
-        
+                non_age_eval += 1
+
         context['non_dx_eval'] = non_dx_eval
         context['eval_num'] = len(evaluations)
         context['eval_f'] = eval_f
         context['eval_m'] = eval_m
         context['non_age_eval'] = non_age_eval
-        
+
         # Create a set to work with single diagnoses
         # removing duplicate entries from eval_dx
-        
+
         unique_dx = set(eval_dx)
-        
+
         summary_dx = []
         # Traverse the evaluations with Dx to get the key values
         for dx in unique_dx:
@@ -277,31 +266,30 @@
             group_1f = group_2f = group_3f = group_4f = group_5f = 0
 
             total_evals = len(unique_evaluations)
-            
+
             new_conditions = 0
-            
+
             for unique_eval in unique_evaluations:
-                
+
                 if (unique_eval.computed_age):
-                    
-                    #Strip to get the raw year
+
+                    # Strip to get the raw year
                     age = int(unique_eval.computed_age.split(' ')[0][:-1])
-                    
-                    
+
                     # Age groups in this diagnostic
                     if (age < 5):
                         group_1 += 1
                         if (unique_eval.gender == 'f'):
                             group_1f += 1
-                    if (age in range(5,14)):
+                    if (age in range(5, 14)):
                         group_2 += 1
                         if (unique_eval.gender == 'f'):
                             group_2f += 1
-                    if (age in range(15,45)):
+                    if (age in range(15, 45)):
                         group_3 += 1
                         if (unique_eval.gender == 'f'):
                             group_3f += 1
-                    if (age in range(46,60)):
+                    if (age in range(46, 60)):
                         group_4 += 1
                         if (unique_eval.gender == 'f'):
                             group_4f += 1
@@ -310,26 +298,27 @@
                         if (unique_eval.gender == 'f'):
                             group_5f += 1
 
-                # Check for new conditions vs followup / chronic checkups 
+                # Check for new conditions vs followup / chronic checkups
                 # in the evaluation with a particular diagnosis
-                
+
                 if (unique_eval.visit_type == 'new'):
                     new_conditions += 1
-                    
-            eval_dx = {'diagnosis': unique_eval.diagnosis.rec_name,
+
+            eval_dx = {
+                'diagnosis': unique_eval.diagnosis.rec_name,
                 'age_group_1': group_1, 'age_group_1f': group_1f,
                 'age_group_2': group_2, 'age_group_2f': group_2f,
                 'age_group_3': group_3, 'age_group_3f': group_3f,
                 'age_group_4': group_4, 'age_group_4f': group_4f,
                 'age_group_5': group_5, 'age_group_5f': group_5f,
-                'total': total_evals, 'new_conditions' : new_conditions,
+                'total': total_evals, 'new_conditions': new_conditions,
                 }
-                
+
             # Append into the report list the resulting
             # dictionary entry
-            
+
             summary_dx.append(eval_dx)
-        
+
         context['summary_dx'] = summary_dx
 
         return context
--- a/tryton/health_reporting/tryton.cfg
+++ b/tryton/health_reporting/tryton.cfg
@@ -1,5 +1,5 @@
 [tryton]
-version=3.8.0
+version=3.9.0
 depends:
     health
 xml:
--- a/tryton/health_reporting/wizard/wizard_epidemics_report.py
+++ b/tryton/health_reporting/wizard/wizard_epidemics_report.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    GNU Health: The Free Health and Hospital Information System
@@ -20,14 +19,12 @@
 #
 ##############################################################################
 
-from datetime import datetime, timedelta, date
+from datetime import date
 from trytond.model import ModelView, fields
-from trytond.wizard import Wizard, StateView, StateAction, StateTransition, \
-    Button
-from trytond.transaction import Transaction
+from trytond.wizard import Wizard, StateView, StateAction, Button
 from dateutil.relativedelta import relativedelta
 
-__all__ = ['EpidemicsReportStart','EpidemicsReport']
+__all__ = ['EpidemicsReportStart', 'EpidemicsReport']
 
 
 class EpidemicsReportStart(ModelView):
@@ -54,11 +51,13 @@
     def default_demographics():
         return True
 
+
 class EpidemicsReport(Wizard):
     'Open Institution Epidemics Report'
     __name__ = 'gnuhealth.epidemics.report.open'
 
-    start = StateView('gnuhealth.epidemics.report.open.start',
+    start = StateView(
+        'gnuhealth.epidemics.report.open.start',
         'health_reporting.epidemics_report_open_start_view_form', [
             Button('Cancel', 'end', 'tryton-cancel'),
             Button('Open', 'open_', 'tryton-ok', default=True),
@@ -68,8 +67,9 @@
 
     def fill_data(self):
         return {
-            'health_condition': (self.start.health_condition.id
-                    if self.start.health_condition else None),
+            'health_condition': (
+                self.start.health_condition.id
+                if self.start.health_condition else None),
             'start_date': self.start.start_date,
             'end_date': self.start.end_date,
             'demographics': self.start.demographics,
--- a/tryton/health_reporting/wizard/wizard_evaluations.py
+++ b/tryton/health_reporting/wizard/wizard_evaluations.py
@@ -4,7 +4,7 @@
 #
 #
 #    Copyright (C) 2012-2014  Sebastian Marro <smarro@gnusolidario.org>
-#    Copyright (C) 2013-2017 Luis Falcon <lfalcon@gnusolidario.org>
+#    Copyright (C) 2013-2022 Luis Falcon <lfalcon@gnusolidario.org>
 #    Copyright (C) 2011-2022 GNU Solidario <health@gnusolidario.org>
 #
 #
@@ -33,7 +33,7 @@
 
 
 __all__ = ['OpenEvaluationsStart', 'OpenEvaluations', 'EvaluationsDoctor',
-    'EvaluationsSpecialty', 'EvaluationsSector']
+           'EvaluationsSpecialty', 'EvaluationsSector']
 
 
 class OpenEvaluationsStart(ModelView):
@@ -53,7 +53,8 @@
     'Open Evaluations'
     __name__ = 'gnuhealth.evaluations.open'
 
-    start = StateView('gnuhealth.evaluations.open.start',
+    start = StateView(
+        'gnuhealth.evaluations.open.start',
         'health_reporting.evaluations_open_start_view_form', [
             Button('Cancel', 'end', 'tryton-cancel'),
             Button('Open', 'select', 'tryton-ok', default=True),
@@ -141,7 +142,7 @@
         pool = Pool()
         Evaluation = pool.get('gnuhealth.patient.evaluation')
         evaluation = Evaluation.__table__()
-        where = evaluation.specialty != None
+        where = evaluation.specialty is not None
         if Transaction().context.get('start_date'):
             where &= evaluation.evaluation_start >= \
                 Transaction().context['start_date']
@@ -202,4 +203,3 @@
             Count(join4.right.id).as_('evaluations'),
             where=where,
             group_by=join4.right.id)
-
--- a/tryton/health_reporting/wizard/wizard_summary_report.py
+++ b/tryton/health_reporting/wizard/wizard_summary_report.py
@@ -20,13 +20,11 @@
 #
 ##############################################################################
 
-from datetime import datetime, timedelta, date
+from datetime import date
 from trytond.model import ModelView, fields
-from trytond.wizard import Wizard, StateView, StateAction, StateTransition, \
-    Button
-from trytond.transaction import Transaction
+from trytond.wizard import Wizard, StateView, StateAction, Button
 
-__all__ = ['SummaryReportStart','SummaryReport']
+__all__ = ['SummaryReportStart', 'SummaryReport']
 
 
 class SummaryReportStart(ModelView):
@@ -54,30 +52,32 @@
     def default_demographics():
         return True
 
+
 class SummaryReport(Wizard):
     'Open Institution Summary Report'
     __name__ = 'gnuhealth.summary.report.open'
 
-    start = StateView('gnuhealth.summary.report.open.start',
+    start = StateView(
+        'gnuhealth.summary.report.open.start',
         'health_reporting.summary_report_open_start_view_form', [
             Button('Cancel', 'end', 'tryton-cancel'),
             Button('Open', 'open_', 'tryton-ok', default=True),
             ])
-    
+
     open_ = StateAction('health_reporting.report_summary_information')
 
     def fill_data(self):
         return {
             'institution': (self.start.institution.id
-                    if self.start.institution else None),
+                            if self.start.institution else None),
             'start_date': self.start.start_date,
             'end_date': self.start.end_date,
             'demographics': self.start.demographics,
             'patient_evaluations': self.start.patient_evaluations,
         }
-    
+
     def do_open_(self, action):
         return action, self.fill_data()
-            
+
     def transition_open_(self):
         return 'end'
--- a/tryton/health_reporting/wizard/wizard_top_diseases.py
+++ b/tryton/health_reporting/wizard/wizard_top_diseases.py
@@ -4,7 +4,7 @@
 #
 #
 #    Copyright (C) 2012-2014  Sebastian Marro <smarro@gnusolidario.org>
-#    Copyright (C) 2013-2017 Luis Falcon <lfalcon@gnusolidario.org>
+#    Copyright (C) 2013-2022 Luis Falcon <lfalcon@gnusolidario.org>
 #    Copyright (C) 2011-2022 GNU Solidario <health@gnusolidario.org>
 #
 #
@@ -22,11 +22,10 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
-from sql import Literal, Join
+from sql import Join
 from sql.aggregate import Max, Count
 from trytond.model import ModelView, ModelSQL, fields
-from trytond.wizard import Wizard, StateView, StateAction, StateTransition, \
-    Button
+from trytond.wizard import Wizard, StateView, StateAction, Button
 from trytond.pyson import PYSONEncoder
 from trytond.pool import Pool
 from trytond.transaction import Transaction
@@ -53,7 +52,7 @@
         Evaluation = pool.get('gnuhealth.patient.evaluation')
         evaluation = Evaluation.__table__()
         source = evaluation
-        where = evaluation.diagnosis != None
+        where = evaluation.diagnosis is not None
         if Transaction().context.get('start_date'):
             where &= evaluation.evaluation_start >= \
                 Transaction().context['start_date']
@@ -103,7 +102,8 @@
     'Open Top Diseases'
     __name__ = 'gnuhealth.top_diseases.open'
 
-    start = StateView('gnuhealth.top_diseases.open.start',
+    start = StateView(
+        'gnuhealth.top_diseases.open.start',
         'health_reporting.top_diseases_open_start_view_form', [
             Button('Cancel', 'end', 'tryton-cancel'),
             Button('Open', 'open_', 'tryton-ok', default=True),