Package Gnumed :: Package business :: Module gmAutoHints
[frames] | no frames]

Source Code for Module Gnumed.business.gmAutoHints

  1  # -*- coding: utf-8 -*- 
  2  """GNUmed auto hints middleware. 
  3   
  4  This should eventually end up in a class cPractice. 
  5  """ 
  6  #============================================================ 
  7  __license__ = "GPL" 
  8  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>" 
  9   
 10   
 11  import sys 
 12  import logging 
 13   
 14   
 15  if __name__ == '__main__': 
 16          sys.path.insert(0, '../../') 
 17  from Gnumed.pycommon import gmPG2 
 18  from Gnumed.pycommon import gmBusinessDBObject 
 19  from Gnumed.pycommon import gmTools 
 20  from Gnumed.pycommon import gmDateTime 
 21   
 22  from Gnumed.business import gmStaff 
 23   
 24  _log = logging.getLogger('gm.hints') 
 25   
 26  #============================================================ 
 27  # dynamic hints API 
 28  #------------------------------------------------------------ 
 29  _SQL_get_dynamic_hints = "SELECT * FROM ref.v_auto_hints WHERE %s" 
 30   
31 -class cDynamicHint(gmBusinessDBObject.cBusinessDBObject):
32 """Represents dynamic hints to be run against the database.""" 33 34 _cmd_fetch_payload = _SQL_get_dynamic_hints % "pk_auto_hint = %s" 35 _cmds_store_payload = [ 36 """UPDATE ref.auto_hint SET 37 query = gm.nullify_empty_string(%(query)s), 38 recommendation_query = gm.nullify_empty_string(%(recommendation_query)s), 39 title = gm.nullify_empty_string(%(title)s), 40 hint = gm.nullify_empty_string(%(hint)s), 41 url = gm.nullify_empty_string(%(url)s), 42 source = gm.nullify_empty_string(%(source)s), 43 is_active = %(is_active)s, 44 popup_type = %(popup_type)s, 45 highlight_as_priority = %(highlight_as_priority)s 46 WHERE 47 pk = %(pk_auto_hint)s 48 AND 49 xmin = %(xmin_auto_hint)s 50 RETURNING 51 xmin AS xmin_auto_hint 52 """ 53 ] 54 _updatable_fields = [ 55 'query', 56 'recommendation_query', 57 'title', 58 'hint', 59 'url', 60 'source', 61 'is_active', 62 'popup_type', 63 'highlight_as_priority' 64 ] 65 #--------------------------------------------------------
66 - def format_maximum_information(self, patient):
67 return self.format(include_sql = True).split('\n')
68 69 #--------------------------------------------------------
70 - def format(self, include_sql=False):
71 txt = '%s [#%s]\n' % ( 72 gmTools.bool2subst(self._payload[self._idx['is_active']], _('Active clinical hint'), _('Inactive clinical hint')), 73 self._payload[self._idx['pk_auto_hint']] 74 ) 75 txt += '\n' 76 txt += self._payload[self._idx['title']] 77 txt += '\n' 78 txt += '\n' 79 txt += _('Source: %s\n') % self._payload[self._idx['source']] 80 txt += _('Language: %s\n') % self._payload[self._idx['lang']] 81 txt += '\n' 82 txt += gmTools.wrap(self._payload[self._idx['hint']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 83 txt += '\n' 84 txt += '\n' 85 if self._payload[self._idx['recommendation']] is not None: 86 txt += gmTools.wrap(self._payload[self._idx['recommendation']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 87 txt += '\n' 88 txt += '\n' 89 txt += gmTools.wrap ( 90 gmTools.coalesce(self._payload[self._idx['url']], ''), 91 width = 50, 92 initial_indent = ' ', 93 subsequent_indent = ' ' 94 ) 95 txt += '\n' 96 if include_sql: 97 txt += '\n' 98 txt += gmTools.wrap(self._payload[self._idx['query']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 99 txt += '\n' 100 if self._payload[self._idx['recommendation_query']] is not None: 101 txt += '\n' 102 txt += gmTools.wrap(self._payload[self._idx['recommendation_query']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 103 txt += '\n' 104 if self._payload[self._idx['rationale4suppression']] is not None: 105 txt += '\n' 106 txt += _('Rationale for suppression:') 107 txt += '\n' 108 txt += gmTools.wrap(self._payload[self._idx['rationale4suppression']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 109 txt += '\n' 110 return txt
111 112 #--------------------------------------------------------
113 - def suppress(self, rationale=None, pk_encounter=None):
114 return suppress_dynamic_hint ( 115 pk_hint = self._payload[self._idx['pk_auto_hint']], 116 pk_encounter = pk_encounter, 117 rationale = rationale 118 )
119 #--------------------------------------------------------
120 - def invalidate_suppression(self, pk_encounter=None):
121 return invalidate_hint_suppression ( 122 pk_hint = self._payload[self._idx['pk_auto_hint']], 123 pk_encounter = pk_encounter 124 )
125 126 #------------------------------------------------------------
127 -def get_dynamic_hints(order_by=None, link_obj=None):
128 if order_by is None: 129 order_by = 'TRUE' 130 else: 131 order_by = 'TRUE ORDER BY %s' % order_by 132 cmd = _SQL_get_dynamic_hints % order_by 133 rows, idx = gmPG2.run_ro_queries(link_obj = link_obj, queries = [{'cmd': cmd}], get_col_idx = True) 134 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_auto_hint'}) for r in rows ]
135 136 #------------------------------------------------------------
137 -def create_dynamic_hint(link_obj=None, query=None, title=None, hint=None, source=None):
138 args = { 139 'query': query, 140 'title': title, 141 'hint': hint, 142 'source': source, 143 'usr': gmStaff.gmCurrentProvider()['db_user'] 144 } 145 cmd = """ 146 INSERT INTO ref.auto_hint ( 147 query, 148 title, 149 hint, 150 source, 151 lang 152 ) VALUES ( 153 gm.nullify_empty_string(%(query)s), 154 gm.nullify_empty_string(%(title)s), 155 gm.nullify_empty_string(%(hint)s), 156 gm.nullify_empty_string(%(source)s), 157 i18n.get_curr_lang(%(usr)s) 158 ) 159 RETURNING pk 160 """ 161 rows, idx = gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = True) 162 return cDynamicHint(aPK_obj = rows[0]['pk'], link_obj = link_obj)
163 164 #------------------------------------------------------------
165 -def delete_dynamic_hint(link_obj=None, pk_hint=None):
166 args = {'pk': pk_hint} 167 cmd = "DELETE FROM ref.auto_hint WHERE pk = %(pk)s" 168 gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}]) 169 return True
170 171 #------------------------------------------------------------
172 -def get_hints_for_patient(pk_identity=None, pk_encounter=None):
173 conn = gmPG2.get_connection() 174 curs = conn.cursor() 175 curs.callproc('clin.get_hints_for_patient', [pk_identity]) 176 rows = curs.fetchall() 177 idx = gmPG2.get_col_indices(curs) 178 curs.close() 179 conn.rollback() 180 181 applying_rows = [] 182 for row in rows: 183 if row['rationale4suppression'] is None: 184 applying_rows.append(row) 185 continue 186 if row['rationale4suppression'].startswith('magic_tag::'): 187 _log.debug('hint with magic tag: %s', row['rationale4suppression']) 188 if 'suppression_needs_invalidation' in row['rationale4suppression']: 189 _log.debug('database asks for invalidation of suppression of hint [%s]', row) 190 if pk_encounter is not None: 191 invalidate_hint_suppression(pk_hint = row['pk_auto_hint'], pk_encounter = pk_encounter) 192 if 'does_not_apply' in row['rationale4suppression']: 193 continue 194 # we would need to reload the relevant hint at this time, 195 # however currently, only hints which do not apply ask 196 # for invalidation of suppression 197 applying_rows.append(row) 198 199 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_auto_hint'}) for r in applying_rows ]
200 201 #------------------------------------------------------------
202 -def suppress_dynamic_hint(pk_hint=None, rationale=None, pk_encounter=None):
203 args = { 204 'hint': pk_hint, 205 'rationale': rationale, 206 'enc': pk_encounter 207 } 208 cmd = """ 209 DELETE FROM clin.suppressed_hint 210 WHERE 211 fk_hint = %(hint)s 212 AND 213 fk_encounter IN ( 214 SELECT pk FROM clin.encounter WHERE fk_patient = ( 215 SELECT fk_patient FROM clin.encounter WHERE pk = %(enc)s 216 ) 217 ) 218 """ 219 queries = [{'cmd': cmd, 'args': args}] 220 cmd = """ 221 INSERT INTO clin.suppressed_hint ( 222 fk_encounter, 223 fk_hint, 224 rationale, 225 md5_sum 226 ) VALUES ( 227 %(enc)s, 228 %(hint)s, 229 %(rationale)s, 230 (SELECT r_vah.md5_sum FROM ref.v_auto_hints r_vah WHERE r_vah.pk_auto_hint = %(hint)s) 231 ) 232 """ 233 queries.append({'cmd': cmd, 'args': args}) 234 gmPG2.run_rw_queries(queries = queries) 235 return True
236 237 #------------------------------------------------------------ 238 # suppressed dynamic hints 239 #------------------------------------------------------------ 240 _SQL_get_suppressed_hints = "SELECT * FROM clin.v_suppressed_hints WHERE %s" 241
242 -class cSuppressedHint(gmBusinessDBObject.cBusinessDBObject):
243 """Represents suppressed dynamic hints per patient.""" 244 245 _cmd_fetch_payload = _SQL_get_suppressed_hints % "pk_suppressed_hint = %s" 246 _cmds_store_payload = [] 247 _updatable_fields = [] 248 #--------------------------------------------------------
249 - def format(self):
250 txt = '%s [#%s]\n' % ( 251 gmTools.bool2subst(self._payload[self._idx['is_active']], _('Suppressed active dynamic hint'), _('Suppressed inactive dynamic hint')), 252 self._payload[self._idx['pk_suppressed_hint']] 253 ) 254 txt += '\n' 255 txt += '%s\n\n' % self._payload[self._idx['title']] 256 txt += _('Suppressed by: %s\n') % self._payload[self._idx['suppressed_by']] 257 txt += _('Suppressed at: %s\n') % gmDateTime.pydt_strftime(self._payload[self._idx['suppressed_when']], '%Y %b %d') 258 txt += _('Hint #: %s\n') % self._payload[self._idx['pk_hint']] 259 txt += _('Patient #: %s\n') % self._payload[self._idx['pk_identity']] 260 txt += _('MD5 (currently): %s\n') % self._payload[self._idx['md5_hint']] 261 txt += _('MD5 (at suppression): %s\n') % self._payload[self._idx['md5_suppressed']] 262 txt += _('Source: %s\n') % self._payload[self._idx['source']] 263 txt += _('Language: %s\n') % self._payload[self._idx['lang']] 264 txt += '\n' 265 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['hint']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 266 txt += '\n' 267 if self._payload[self._idx['recommendation']] is not None: 268 txt += '\n' 269 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['recommendation']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 270 txt += '\n' 271 txt += '%s\n' % gmTools.wrap ( 272 gmTools.coalesce(self._payload[self._idx['url']], ''), 273 width = 50, 274 initial_indent = ' ', 275 subsequent_indent = ' ' 276 ) 277 txt += '\n' 278 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['query']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 279 return txt
280 281 #------------------------------------------------------------
282 -def get_suppressed_hints(pk_identity=None, order_by=None):
283 args = {'pat': pk_identity} 284 if pk_identity is None: 285 where = 'true' 286 else: 287 where = "pk_identity = %(pat)s" 288 if order_by is None: 289 order_by = '' 290 else: 291 order_by = ' ORDER BY %s' % order_by 292 cmd = (_SQL_get_suppressed_hints % where) + order_by 293 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 294 return [ cSuppressedHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_suppressed_hint'}) for r in rows ]
295 296 #------------------------------------------------------------
297 -def delete_suppressed_hint(pk_suppressed_hint=None):
298 args = {'pk': pk_suppressed_hint} 299 cmd = "DELETE FROM clin.suppressed_hint WHERE pk = %(pk)s" 300 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 301 return True
302 303 #------------------------------------------------------------
304 -def invalidate_hint_suppression(pk_hint=None, pk_encounter=None):
305 _log.debug('invalidating suppression of hint #%s', pk_hint) 306 args = { 307 'pk_hint': pk_hint, 308 'enc': pk_encounter, 309 'fake_md5': '***INVALIDATED***' # only needs to NOT match ANY md5 sum 310 } 311 cmd = """ 312 UPDATE clin.suppressed_hint SET 313 fk_encounter = %(enc)s, 314 md5_sum = %(fake_md5)s 315 WHERE 316 pk = ( 317 SELECT pk_suppressed_hint 318 FROM clin.v_suppressed_hints 319 WHERE 320 pk_hint = %(pk_hint)s 321 AND 322 pk_identity = ( 323 SELECT fk_patient FROM clin.encounter WHERE pk = %(enc)s 324 ) 325 ) 326 """ 327 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 328 return True
329 330 #============================================================ 331 if __name__ == '__main__': 332 333 if len(sys.argv) < 2: 334 sys.exit() 335 336 if sys.argv[1] != 'test': 337 sys.exit() 338 339 from Gnumed.pycommon import gmI18N 340 341 gmI18N.activate_locale() 342 gmI18N.install_domain() 343 344 #---------------------------------------
345 - def test_auto_hints():
346 # for row in get_dynamic_hints(): 347 # print row 348 for row in get_hints_for_patient(pk_identity = 12): 349 print(row)
350 #--------------------------------------- 351 test_auto_hints() 352