Module Gnumed.business.gmProblem

GNUmed problem related business object.

license: GPL v2 or later

Classes

class cProblem (aPK_obj=None, try_potential_problems: bool = False)
Expand source code
class cProblem(gmBusinessDBObject.cBusinessDBObject):
        """Represents one problem.

        problems are the aggregation of
                .clinically_relevant=True issues and
                .is_open=True episodes
        """
        _cmd_fetch_payload = ''                                 # will get programmatically defined in __init__
        _cmds_store_payload:list = ["select 1"]
        _updatable_fields:list = []

        #--------------------------------------------------------
        def __init__(self, aPK_obj=None, try_potential_problems:bool=False):
                """Initialize.

                aPK_obj must contain the keys
                        pk_patient
                        pk_episode
                        pk_health_issue
                """
                if aPK_obj is None:
                        raise gmExceptions.ConstructorError('cannot instatiate cProblem for PK: [%s]' % (aPK_obj))

                # As problems are rows from a view of different emr struct items,
                # the PK can't be a single field and, as some of the values of the
                # composed PK may be None, they must be queried using 'is null',
                # so we must programmatically construct the SQL query
                where_parts = []
                pk = {}
                for col_name in aPK_obj:
                        val = aPK_obj[col_name]
                        if val is None:
                                where_parts.append('%s IS NULL' % col_name)
                        else:
                                where_parts.append('%s = %%(%s)s' % (col_name, col_name))
                                pk[col_name] = val

                # try to instantiate from true problem view
                cProblem._cmd_fetch_payload = """
                        SELECT *, False as is_potential_problem
                        FROM clin.v_problem_list
                        WHERE %s""" % ' AND '.join(where_parts)

                try:
                        gmBusinessDBObject.cBusinessDBObject.__init__(self, aPK_obj = pk)
                        return

                except gmExceptions.ConstructorError:
                        _log.exception('actual problem not found, trying "potential" problems')
                        if try_potential_problems is False:
                                raise

                # try to instantiate from potential-problems view
                cProblem._cmd_fetch_payload = """
                        SELECT *, True as is_potential_problem
                        FROM clin.v_potential_problem_list
                        WHERE %s""" % ' AND '.join(where_parts)
                gmBusinessDBObject.cBusinessDBObject.__init__(self, aPK_obj=pk)

        #--------------------------------------------------------
        @classmethod
        def from_episode(cls, episode:'gmEpisode.cEpisode', allow_closed:bool=False) -> 'cProblem':
                """Initialize problem from episode"""
                return cls (
                        aPK_obj = {
                                'pk_patient': episode['pk_patient'],
                                'pk_health_issue': episode['pk_health_issue'],
                                'pk_episode': episode['pk_episode']
                        },
                        try_potential_problems = allow_closed
                )

        #--------------------------------------------------------
        @classmethod
        def from_health_issue(cls, health_issue, allow_irrelevant:bool=False) -> 'cProblem':
                """Initialize problem from health issue."""
                return cls (
                        aPK_obj = {
                                'pk_patient': health_issue['pk_patient'],
                                'pk_health_issue': health_issue['pk_health_issue'],
                                'pk_episode': None
                        },
                        try_potential_problems = allow_irrelevant
                )

        #--------------------------------------------------------
        @classmethod
        def from_issue_or_episode(cls, issue_or_episode, allow_all:bool=False) -> 'cProblem':
                if isinstance(issue_or_episode, cProblem):
                        return issue_or_episode

                pk_obj = {
                        'pk_patient': issue_or_episode['pk_patient'],
                        'pk_health_issue': issue_or_episode['pk_health_issue']
                }
                try:
                        pk_obj['pk_episode'] = issue_or_episode['pk_episode']
                except KeyError:
                        pk_obj['pk_episode'] = None
                return cls(aPK_obj = pk_obj, try_potential_problems = allow_all)

        #--------------------------------------------------------
        def __get_as_episode(self):
                """
                Retrieve the cEpisode instance equivalent to this problem.
                The problem's type attribute must be 'episode'
                """
                if self._payload['type'] != 'episode':
                        _log.error('cannot convert problem [%s] of type [%s] to episode' % (self._payload['problem'], self._payload['type']))
                        return None

                return gmEpisode.cEpisode(aPK_obj = self._payload['pk_episode'])

        as_episode = property(__get_as_episode)

        #--------------------------------------------------------
        def __get_as_health_issue(self):
                """
                Retrieve the cHealthIssue instance equivalent to this problem.
                The problem's type attribute must be 'issue'
                """
                if self._payload['type'] != 'issue':
                        _log.error('cannot convert problem [%s] of type [%s] to health issue' % (self._payload['problem'], self._payload['type']))
                        return None

                return gmHealthIssue.cHealthIssue(aPK_obj = self._payload['pk_health_issue'])

        as_health_issue = property(__get_as_health_issue)

        #--------------------------------------------------------
        def get_visual_progress_notes(self, encounter_id:int=None):
                if self._payload['type'] == 'issue':
                        latest = gmHealthIssue.cHealthIssue(aPK_obj = self._payload['pk_health_issue']).latest_episode
                        if latest is None:
                                return []

                        pk_episode = latest['pk_episode']
                else:
                        pk_episode = self._payload['pk_episode']
                doc_folder = gmDocuments.cDocumentFolder(aPKey = self._payload['pk_patient'])
                return doc_folder.get_visual_progress_notes(episodes = [pk_episode])

        #--------------------------------------------------------
        # properties
        #--------------------------------------------------------
        def get_diagnostic_certainty_description(self):
                from Gnumed.business.gmHealthIssue import diagnostic_certainty_classification2str
                return diagnostic_certainty_classification2str(self._payload['diagnostic_certainty_classification'])

        diagnostic_certainty_description = property(get_diagnostic_certainty_description)

        #--------------------------------------------------------
        def _get_generic_codes(self):
                if self._payload['type'] == 'issue':
                        cmd = """
                                SELECT * FROM clin.v_linked_codes WHERE
                                        item_table = 'clin.lnk_code2h_issue'::regclass
                                                AND
                                        pk_item = %(item)s
                        """
                        args = {'item': self._payload['pk_health_issue']}
                else:
                        cmd = """
                                SELECT * FROM clin.v_linked_codes WHERE
                                        item_table = 'clin.lnk_code2episode'::regclass
                                                AND
                                        pk_item = %(item)s
                        """
                        args = {'item': self._payload['pk_episode']}

                rows = gmPG2.run_ro_queries(queries = [{'sql': cmd, 'args': args}])
                return [ gmCoding.cGenericLinkedCode(row = {'data': r, 'pk_field': 'pk_lnk_code2item'}) for r in rows ]

        generic_codes = property(_get_generic_codes)

Represents one problem.

problems are the aggregation of .clinically_relevant=True issues and .is_open=True episodes

Initialize.

aPK_obj must contain the keys pk_patient pk_episode pk_health_issue

Ancestors

Static methods

def from_episode(episode: gmEpisode.cEpisode, allow_closed: bool = False) ‑> cProblem

Initialize problem from episode

def from_health_issue(health_issue, allow_irrelevant: bool = False) ‑> cProblem

Initialize problem from health issue.

def from_issue_or_episode(issue_or_episode, allow_all: bool = False) ‑> cProblem

Instance variables

prop as_episode
Expand source code
def __get_as_episode(self):
        """
        Retrieve the cEpisode instance equivalent to this problem.
        The problem's type attribute must be 'episode'
        """
        if self._payload['type'] != 'episode':
                _log.error('cannot convert problem [%s] of type [%s] to episode' % (self._payload['problem'], self._payload['type']))
                return None

        return gmEpisode.cEpisode(aPK_obj = self._payload['pk_episode'])

Retrieve the cEpisode instance equivalent to this problem. The problem's type attribute must be 'episode'

prop as_health_issue
Expand source code
def __get_as_health_issue(self):
        """
        Retrieve the cHealthIssue instance equivalent to this problem.
        The problem's type attribute must be 'issue'
        """
        if self._payload['type'] != 'issue':
                _log.error('cannot convert problem [%s] of type [%s] to health issue' % (self._payload['problem'], self._payload['type']))
                return None

        return gmHealthIssue.cHealthIssue(aPK_obj = self._payload['pk_health_issue'])

Retrieve the cHealthIssue instance equivalent to this problem. The problem's type attribute must be 'issue'

prop diagnostic_certainty_description
Expand source code
def get_diagnostic_certainty_description(self):
        from Gnumed.business.gmHealthIssue import diagnostic_certainty_classification2str
        return diagnostic_certainty_classification2str(self._payload['diagnostic_certainty_classification'])
prop generic_codes
Expand source code
def _get_generic_codes(self):
        if self._payload['type'] == 'issue':
                cmd = """
                        SELECT * FROM clin.v_linked_codes WHERE
                                item_table = 'clin.lnk_code2h_issue'::regclass
                                        AND
                                pk_item = %(item)s
                """
                args = {'item': self._payload['pk_health_issue']}
        else:
                cmd = """
                        SELECT * FROM clin.v_linked_codes WHERE
                                item_table = 'clin.lnk_code2episode'::regclass
                                        AND
                                pk_item = %(item)s
                """
                args = {'item': self._payload['pk_episode']}

        rows = gmPG2.run_ro_queries(queries = [{'sql': cmd, 'args': args}])
        return [ gmCoding.cGenericLinkedCode(row = {'data': r, 'pk_field': 'pk_lnk_code2item'}) for r in rows ]

Methods

def get_diagnostic_certainty_description(self)
Expand source code
def get_diagnostic_certainty_description(self):
        from Gnumed.business.gmHealthIssue import diagnostic_certainty_classification2str
        return diagnostic_certainty_classification2str(self._payload['diagnostic_certainty_classification'])
def get_visual_progress_notes(self, encounter_id: int = None)
Expand source code
def get_visual_progress_notes(self, encounter_id:int=None):
        if self._payload['type'] == 'issue':
                latest = gmHealthIssue.cHealthIssue(aPK_obj = self._payload['pk_health_issue']).latest_episode
                if latest is None:
                        return []

                pk_episode = latest['pk_episode']
        else:
                pk_episode = self._payload['pk_episode']
        doc_folder = gmDocuments.cDocumentFolder(aPKey = self._payload['pk_patient'])
        return doc_folder.get_visual_progress_notes(episodes = [pk_episode])

Inherited members