Module Gnumed.business.gmGenericEMRItem
GNUmed clinical business object in generic form.
license: GPL v2 or later
Functions
def generic_item_type_str(table)-
Expand source code
def generic_item_type_str(table): try: return _MAP_generic_emr_item_table2type_str[table] except KeyError: return _('unmapped entry type from table [%s]') % table def get_generic_emr_items(encounters: list = None,
episodes: list = None,
issues: list = None,
patient=None,
soap_cats: str | list[str | None] | tuple[str | None] = None,
time_range=None,
order_by: str = None,
active_encounter: cEncounter = None,
return_pks: bool = False,
exclude_soap_cats: bool = False,
item_types2exclude: list[str] = None) ‑> list[cGenericEMRItem] | list[int]-
Expand source code
def get_generic_emr_items ( encounters:list=None, episodes:list=None, issues:list=None, patient=None, soap_cats:str | list[str|None] | tuple[str|None]=None, time_range=None, # in days order_by:str=None, active_encounter:cEncounter=None, return_pks:bool=False, exclude_soap_cats:bool=False, item_types2exclude:list[str]=None ) -> list[cGenericEMRItem] | list[int]: """Return generic EMR items. Args: timerange: number of days for going back in EMR """ faulty_args = ( (patient is None) and (encounters is None) and (episodes is None) and (issues is None) and (active_encounter is None) ) assert not faulty_args, 'one of <patient>, <episodes>, <issues>, <active_encounter> must not be None' if (patient is not None) and (active_encounter is not None): if patient != active_encounter['pk_patient']: raise AssertionError('<patient> (%s) and <active_encounter>["pk_patient"] (%s) must match, if both given', patient, active_encounter['pk_patient']) if order_by is None: order_by = 'ORDER BY clin_when, pk_episode, scr, modified_when, src_table' else: order_by = 'ORDER BY %s' % order_by if (patient is None) and (active_encounter is not None): patient = active_encounter['pk_patient'] where_parts = [] args = {} if patient is not None: where_parts.append('pk_patient = %(pat)s') args['pat'] = patient if soap_cats: cats = list(soap_cats) # work around bug in psycopg2 not being able to properly # adapt None to NULL inside tuples if None in cats: where_arg = '((c_vej.soap_cat = ANY(%(soap_cat)s)) OR (c_vej.soap_cat IS NULL))' cats.remove(None) else: where_arg = 'c_vej.soap_cat = ANY(%(soap_cat)s)' if exclude_soap_cats: where_arg = 'NOT (%s)' % where_arg where_parts.append(where_arg) args['soap_cat'] = cats if item_types2exclude: where_parts.append('NOT (src_table = ANY(%(item_types)s))') args['item_types'] = item_types2exclude if time_range is not None: where_parts.append("clin_when > (now() - '%s days'::interval)" % time_range) if encounters is not None: where_parts.append("pk_encounter = ANY(%(encs)s)") args['encs'] = encounters if episodes is not None: where_parts.append("pk_episode = ANY(%(epis)s)") args['epis'] = episodes if issues is not None: where_parts.append("pk_health_issue = ANY(%(issues)s)") args['issues'] = issues SQL_journal = _SQL_get_generic_emr_items if len(where_parts) > 0: SQL_journal += '\nWHERE\n\t' SQL_journal += '\n\t\tAND '.join(where_parts) SQL = SQL_journal + '\n' + order_by # if active_encounter is None: # cmd = SQL_journal + '\n' + order_by # else: # args['pk_enc'] = active_encounter['pk_encounter'] # args['enc_start'] = active_encounter['started'] # args['enc_last_affirmed'] = active_encounter['last_affirmed'] # args['enc_type'] = active_encounter['l10n_type'] # args['enc_pat'] = active_encounter['pk_patient'] # cmd = __SQL_union % ( # SQL_journal, # _SQL_get_hints_as_generic_emr_items # ) + '\n' + order_by rows = gmPG2.run_ro_query(sql = SQL, args = args) if return_pks: return [ { 'src_table': r['src_table'], 'src_pk': r['src_pk'] } for r in rows ] return [ cGenericEMRItem(row = { 'data': r, 'pk_obj': {'src_table': r['src_table'], 'src_pk': r['src_pk']} } ) for r in rows ]Return generic EMR items.
- Args
- -----=
timerange- number of days for going back in EMR
Classes
class cGenericEMRItem (aPK_obj: int | dict = None, row: dict = None, link_obj=None)-
Expand source code
class cGenericEMRItem(gmBusinessDBObject.cBusinessDBObject): """Represents an entry in clin.v_emr_journal.""" _cmd_fetch_payload:str = _SQL_get_generic_emr_items + "WHERE src_table = %(src_table)s AND src_pk = %(src_pk)s" _cmds_store_payload:list = [] _updatable_fields:list = [''] #-------------------------------------------------------- def format(self, eol=None): lines = self.formatted_header lines.append(gmTools.u_box_horiz_4dashes * 40) lines.extend(self._payload['narrative'].strip().split('\n')) if eol is None: return lines return eol.join(lines) #-------------------------------------------------------- def format_tech_info(self) -> list[str]: lines = [] lines.append('%s [%s]' % (self.item_type_str, self._payload['real_soap_cat'])) lines.append(' ' + _('Table: %s##tx: EMR item source (database table, mostly)') % self._payload['src_table']) lines.append(' ' + _('Version: %s (%s)') % ( self._payload['row_version'], _('Original##tx: ... of clinical record item') if (self._payload['row_version'] == 1) else _('Revision##tx: ... of clinical record entry') )) lines.append(' ' + _('Last modified:')) lines.append(' %s (%s)' % ( self._payload['modified_when'].timestamp(), _('UNIX timestamp') )) format = '%Y-%m-%d (%b, %a) %H:%M:%S:%f %Z' lines.append(' %s %s' % ( gmTools.u_arrow2right, self._payload['modified_when'].astimezone(tz = pydt.timezone.utc).strftime(format) )) lines.append(' %s %s (%s)' % ( gmTools.u_arrow2right, self._payload['modified_when'].strftime(format), _('local time') )) lines.append(' ' + _('Modified by: %s') % self._payload['modified_by']) lines.append(' %s PK: %s' % ( self._payload['src_table'], self._payload['src_pk'] )) lines.append(' ' + _('Encounter PK: %s') % self._payload['pk_encounter']) lines.append(' ' + _('Episode PK: %s') % self._payload['pk_episode']) lines.append(' ' + _('Health Issue PK: %s') % self._payload['pk_health_issue']) lines.append(' ' + _('Patient PK: %s') % self._payload['pk_patient']) return lines formatted_tech_info = property(fget = format_tech_info) #-------------------------------------------------------- def format_header(self, eol=None): lines = [] lines.append('%s (%s)' % (self.item_type_str, self.i18n_soap_cat)) lines.append('') if self._payload['health_issue'] is None: issue_info = gmTools.u_diameter else: issue_info = '%s%s' % ( self._payload['health_issue'], gmTools.bool2subst(self._payload['issue_active'], ' (' + _('active') + ')', ' (' + _('inactive') + ')', '') ) lines.append(_('Health issue: %s') % issue_info) if self._payload['episode'] is None: episode_info = gmTools.u_diameter else: episode_info = '%s%s' % ( self._payload['episode'], gmTools.bool2subst(self._payload['episode_open'], ' (' + _('open') + ')', ' (' + _('closed') + ')', '') ) lines.append(_('Episode: %s') % episode_info) if self._payload['encounter_started'] is None: enc_info = gmTools.u_diameter else: enc_info = '%s - %s (%s)' % ( self._payload['encounter_started'].strftime('%Y %b %d %H:%M'), self._payload['encounter_last_affirmed'].strftime('%H:%M'), self._payload['l10n_encounter_type'] ) lines.append(_('Encounter: %s') % enc_info) lines.append(_('Event: %s') % self._payload['clin_when'].strftime('%Y %b %d %H:%M')) if eol is None: return lines return eol.join(lines) formatted_header = property(format_header) #-------------------------------------------------------- def __get_item_type_str(self): try: tmp = _MAP_generic_emr_item_table2type_str[self._payload['src_table']] except KeyError: tmp = '[%s:%s]' % ( self._payload['src_table'], self._payload['src_pk'] ) return tmp item_type_str = property(__get_item_type_str) #-------------------------------------------------------- def __get_i18n_soap_cat(self): return gmSoapDefs.soap_cat2l10n[self._payload['soap_cat']] i18n_soap_cat = property(__get_i18n_soap_cat) #-------------------------------------------------------- def __get_specialized_item(self): item_class = _MAP_generic_emr_item_table2class[self._payload['src_table']] return item_class(aPK_obj = self._payload['src_pk']) specialized_item = property(__get_specialized_item) #-------------------------------------------------------- def get_revision_history(self, link_obj:gmPG2._TLnkObj=None): schema, table = self._payload['src_table'].split('.', 1) hx = gmPG2.get_row_history ( link_obj = link_obj, schema = schema, table = table, pk = self._payload['src_pk'] ) return hx #-------------------------------------------------------- def get_formatted_revision_history(self, link_obj:gmPG2._TLnkObj=None): hx = self.get_revision_history(link_obj = link_obj) if not hx: return ['%s (PK %s): %s' % ( self._payload['src_table'], self._payload['src_pk'], _('no previous versions') )] lines = ['%s, PK %s: %s version(s) before current state (= v%s)' % ( self._payload['src_table'], self._payload['src_pk'], len(hx), self._payload['row_version'] )] # loop over _all_ rows because the audit table can have chaged over time :( column_labels = [ 'v%s (%s)' % ( h['row_version'], h['version_logged_when'].strftime('%Y %b %d %H:%M') ) for h in hx ] lines.extend (gmTools.dicts2table_columns ( hx, left_margin = 1, eol = None, keys2ignore = ['src_row_pk_audit', 'version_logged_when', 'version_logged_why', 'version_logged_by', 'row_version', 'src_table_oid', 'pk_audit_trail'], show_only_changes = True, column_labels = column_labels, date_format = '%Y %b %d %H:%M', equality_value = gmTools.u_arrow2right )) return linesRepresents an entry in clin.v_emr_journal.
Call init from child classes like so:
super().__init__(aPK_obj = aPK_obj, row = row, link_obj = link_obj)- Args
- -----=
aPK_obj- retrieve data from backend
- an scalar value the ._cmd_fetch_payload WHERE condition must be a simple column: "… WHERE pk_col = %s"
- a dictionary of values the ._cmd_fetch_payload WHERE condition must consume the dictionary and produce a unique row
row- must hold the fields
- data: list of column values for the row selected by ._cmd_fetch_payload (as returned by cursor.fetchone() in the DB-API)
- pk_field: the name of the primary key column OR
- pk_obj: a dictionary suitable for being passed to cursor.execute and holding the primary key values, used for composite PKs
- for example:
row = { 'data': rows[0], 'pk_field': 'pk_XXX (the PK column name)', 'pk_obj': {'pk_col1': pk_col1_val, 'pk_col2': pk_col2_val} } rows = gmPG2.run_ro_queries(queries = [{'sql': cmd, 'args': args}]) objects = [ cChildClass(row = {'data': r, 'pk_field': 'the PK column name'}) for r in rows ]
Ancestors
Instance variables
prop formatted_header-
Expand source code
def format_header(self, eol=None): lines = [] lines.append('%s (%s)' % (self.item_type_str, self.i18n_soap_cat)) lines.append('') if self._payload['health_issue'] is None: issue_info = gmTools.u_diameter else: issue_info = '%s%s' % ( self._payload['health_issue'], gmTools.bool2subst(self._payload['issue_active'], ' (' + _('active') + ')', ' (' + _('inactive') + ')', '') ) lines.append(_('Health issue: %s') % issue_info) if self._payload['episode'] is None: episode_info = gmTools.u_diameter else: episode_info = '%s%s' % ( self._payload['episode'], gmTools.bool2subst(self._payload['episode_open'], ' (' + _('open') + ')', ' (' + _('closed') + ')', '') ) lines.append(_('Episode: %s') % episode_info) if self._payload['encounter_started'] is None: enc_info = gmTools.u_diameter else: enc_info = '%s - %s (%s)' % ( self._payload['encounter_started'].strftime('%Y %b %d %H:%M'), self._payload['encounter_last_affirmed'].strftime('%H:%M'), self._payload['l10n_encounter_type'] ) lines.append(_('Encounter: %s') % enc_info) lines.append(_('Event: %s') % self._payload['clin_when'].strftime('%Y %b %d %H:%M')) if eol is None: return lines return eol.join(lines) prop formatted_tech_info : list[str]-
Expand source code
def format_tech_info(self) -> list[str]: lines = [] lines.append('%s [%s]' % (self.item_type_str, self._payload['real_soap_cat'])) lines.append(' ' + _('Table: %s##tx: EMR item source (database table, mostly)') % self._payload['src_table']) lines.append(' ' + _('Version: %s (%s)') % ( self._payload['row_version'], _('Original##tx: ... of clinical record item') if (self._payload['row_version'] == 1) else _('Revision##tx: ... of clinical record entry') )) lines.append(' ' + _('Last modified:')) lines.append(' %s (%s)' % ( self._payload['modified_when'].timestamp(), _('UNIX timestamp') )) format = '%Y-%m-%d (%b, %a) %H:%M:%S:%f %Z' lines.append(' %s %s' % ( gmTools.u_arrow2right, self._payload['modified_when'].astimezone(tz = pydt.timezone.utc).strftime(format) )) lines.append(' %s %s (%s)' % ( gmTools.u_arrow2right, self._payload['modified_when'].strftime(format), _('local time') )) lines.append(' ' + _('Modified by: %s') % self._payload['modified_by']) lines.append(' %s PK: %s' % ( self._payload['src_table'], self._payload['src_pk'] )) lines.append(' ' + _('Encounter PK: %s') % self._payload['pk_encounter']) lines.append(' ' + _('Episode PK: %s') % self._payload['pk_episode']) lines.append(' ' + _('Health Issue PK: %s') % self._payload['pk_health_issue']) lines.append(' ' + _('Patient PK: %s') % self._payload['pk_patient']) return lines prop i18n_soap_cat-
Expand source code
def __get_i18n_soap_cat(self): return gmSoapDefs.soap_cat2l10n[self._payload['soap_cat']] prop item_type_str-
Expand source code
def __get_item_type_str(self): try: tmp = _MAP_generic_emr_item_table2type_str[self._payload['src_table']] except KeyError: tmp = '[%s:%s]' % ( self._payload['src_table'], self._payload['src_pk'] ) return tmp prop specialized_item-
Expand source code
def __get_specialized_item(self): item_class = _MAP_generic_emr_item_table2class[self._payload['src_table']] return item_class(aPK_obj = self._payload['src_pk'])
Methods
def format_header(self, eol=None)-
Expand source code
def format_header(self, eol=None): lines = [] lines.append('%s (%s)' % (self.item_type_str, self.i18n_soap_cat)) lines.append('') if self._payload['health_issue'] is None: issue_info = gmTools.u_diameter else: issue_info = '%s%s' % ( self._payload['health_issue'], gmTools.bool2subst(self._payload['issue_active'], ' (' + _('active') + ')', ' (' + _('inactive') + ')', '') ) lines.append(_('Health issue: %s') % issue_info) if self._payload['episode'] is None: episode_info = gmTools.u_diameter else: episode_info = '%s%s' % ( self._payload['episode'], gmTools.bool2subst(self._payload['episode_open'], ' (' + _('open') + ')', ' (' + _('closed') + ')', '') ) lines.append(_('Episode: %s') % episode_info) if self._payload['encounter_started'] is None: enc_info = gmTools.u_diameter else: enc_info = '%s - %s (%s)' % ( self._payload['encounter_started'].strftime('%Y %b %d %H:%M'), self._payload['encounter_last_affirmed'].strftime('%H:%M'), self._payload['l10n_encounter_type'] ) lines.append(_('Encounter: %s') % enc_info) lines.append(_('Event: %s') % self._payload['clin_when'].strftime('%Y %b %d %H:%M')) if eol is None: return lines return eol.join(lines) def format_tech_info(self) ‑> list[str]-
Expand source code
def format_tech_info(self) -> list[str]: lines = [] lines.append('%s [%s]' % (self.item_type_str, self._payload['real_soap_cat'])) lines.append(' ' + _('Table: %s##tx: EMR item source (database table, mostly)') % self._payload['src_table']) lines.append(' ' + _('Version: %s (%s)') % ( self._payload['row_version'], _('Original##tx: ... of clinical record item') if (self._payload['row_version'] == 1) else _('Revision##tx: ... of clinical record entry') )) lines.append(' ' + _('Last modified:')) lines.append(' %s (%s)' % ( self._payload['modified_when'].timestamp(), _('UNIX timestamp') )) format = '%Y-%m-%d (%b, %a) %H:%M:%S:%f %Z' lines.append(' %s %s' % ( gmTools.u_arrow2right, self._payload['modified_when'].astimezone(tz = pydt.timezone.utc).strftime(format) )) lines.append(' %s %s (%s)' % ( gmTools.u_arrow2right, self._payload['modified_when'].strftime(format), _('local time') )) lines.append(' ' + _('Modified by: %s') % self._payload['modified_by']) lines.append(' %s PK: %s' % ( self._payload['src_table'], self._payload['src_pk'] )) lines.append(' ' + _('Encounter PK: %s') % self._payload['pk_encounter']) lines.append(' ' + _('Episode PK: %s') % self._payload['pk_episode']) lines.append(' ' + _('Health Issue PK: %s') % self._payload['pk_health_issue']) lines.append(' ' + _('Patient PK: %s') % self._payload['pk_patient']) return lines def get_formatted_revision_history(self,
link_obj: psycopg2.extras.DictConnection | psycopg2.extras.DictCursor | None = None)-
Expand source code
def get_formatted_revision_history(self, link_obj:gmPG2._TLnkObj=None): hx = self.get_revision_history(link_obj = link_obj) if not hx: return ['%s (PK %s): %s' % ( self._payload['src_table'], self._payload['src_pk'], _('no previous versions') )] lines = ['%s, PK %s: %s version(s) before current state (= v%s)' % ( self._payload['src_table'], self._payload['src_pk'], len(hx), self._payload['row_version'] )] # loop over _all_ rows because the audit table can have chaged over time :( column_labels = [ 'v%s (%s)' % ( h['row_version'], h['version_logged_when'].strftime('%Y %b %d %H:%M') ) for h in hx ] lines.extend (gmTools.dicts2table_columns ( hx, left_margin = 1, eol = None, keys2ignore = ['src_row_pk_audit', 'version_logged_when', 'version_logged_why', 'version_logged_by', 'row_version', 'src_table_oid', 'pk_audit_trail'], show_only_changes = True, column_labels = column_labels, date_format = '%Y %b %d %H:%M', equality_value = gmTools.u_arrow2right )) return lines def get_revision_history(self,
link_obj: psycopg2.extras.DictConnection | psycopg2.extras.DictCursor | None = None)-
Expand source code
def get_revision_history(self, link_obj:gmPG2._TLnkObj=None): schema, table = self._payload['src_table'].split('.', 1) hx = gmPG2.get_row_history ( link_obj = link_obj, schema = schema, table = table, pk = self._payload['src_pk'] ) return hx
Inherited members