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, return_pks=False):
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 if return_pks: 135 return [ r['pk_auto_hint'] for r in rows ] 136 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_auto_hint'}) for r in rows ]
137 138 #------------------------------------------------------------
139 -def create_dynamic_hint(link_obj=None, query=None, title=None, hint=None, source=None):
140 args = { 141 'query': query, 142 'title': title, 143 'hint': hint, 144 'source': source, 145 'usr': gmStaff.gmCurrentProvider()['db_user'] 146 } 147 cmd = """ 148 INSERT INTO ref.auto_hint ( 149 query, 150 title, 151 hint, 152 source, 153 lang 154 ) VALUES ( 155 gm.nullify_empty_string(%(query)s), 156 gm.nullify_empty_string(%(title)s), 157 gm.nullify_empty_string(%(hint)s), 158 gm.nullify_empty_string(%(source)s), 159 i18n.get_curr_lang(%(usr)s) 160 ) 161 RETURNING pk 162 """ 163 rows, idx = gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = True) 164 return cDynamicHint(aPK_obj = rows[0]['pk'], link_obj = link_obj)
165 166 #------------------------------------------------------------
167 -def delete_dynamic_hint(link_obj=None, pk_hint=None):
168 args = {'pk': pk_hint} 169 cmd = "DELETE FROM ref.auto_hint WHERE pk = %(pk)s" 170 gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}]) 171 return True
172 173 #------------------------------------------------------------
174 -def get_hints_for_patient(pk_identity=None, pk_encounter=None):
175 conn = gmPG2.get_connection() 176 curs = conn.cursor() 177 curs.callproc('clin.get_hints_for_patient', [pk_identity]) 178 rows = curs.fetchall() 179 idx = gmPG2.get_col_indices(curs) 180 curs.close() 181 conn.rollback() 182 183 applying_rows = [] 184 for row in rows: 185 if row['rationale4suppression'] is None: 186 applying_rows.append(row) 187 continue 188 if row['rationale4suppression'].startswith('magic_tag::'): 189 _log.debug('hint with magic tag: %s', row['rationale4suppression']) 190 if 'suppression_needs_invalidation' in row['rationale4suppression']: 191 _log.debug('database asks for invalidation of suppression of hint [%s]', row) 192 if pk_encounter is not None: 193 invalidate_hint_suppression(pk_hint = row['pk_auto_hint'], pk_encounter = pk_encounter) 194 if 'does_not_apply' in row['rationale4suppression']: 195 continue 196 # we would need to reload the relevant hint at this time, 197 # however currently, only hints which do not apply ask 198 # for invalidation of suppression 199 applying_rows.append(row) 200 201 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_auto_hint'}) for r in applying_rows ]
202 203 #------------------------------------------------------------
204 -def suppress_dynamic_hint(pk_hint=None, rationale=None, pk_encounter=None):
205 args = { 206 'hint': pk_hint, 207 'rationale': rationale, 208 'enc': pk_encounter 209 } 210 cmd = """ 211 DELETE FROM clin.suppressed_hint 212 WHERE 213 fk_hint = %(hint)s 214 AND 215 fk_encounter IN ( 216 SELECT pk FROM clin.encounter WHERE fk_patient = ( 217 SELECT fk_patient FROM clin.encounter WHERE pk = %(enc)s 218 ) 219 ) 220 """ 221 queries = [{'cmd': cmd, 'args': args}] 222 cmd = """ 223 INSERT INTO clin.suppressed_hint ( 224 fk_encounter, 225 fk_hint, 226 rationale, 227 md5_sum 228 ) VALUES ( 229 %(enc)s, 230 %(hint)s, 231 %(rationale)s, 232 (SELECT r_vah.md5_sum FROM ref.v_auto_hints r_vah WHERE r_vah.pk_auto_hint = %(hint)s) 233 ) 234 """ 235 queries.append({'cmd': cmd, 'args': args}) 236 gmPG2.run_rw_queries(queries = queries) 237 return True
238 239 #------------------------------------------------------------ 240 # suppressed dynamic hints 241 #------------------------------------------------------------ 242 _SQL_get_suppressed_hints = "SELECT * FROM clin.v_suppressed_hints WHERE %s" 243
244 -class cSuppressedHint(gmBusinessDBObject.cBusinessDBObject):
245 """Represents suppressed dynamic hints per patient.""" 246 247 _cmd_fetch_payload = _SQL_get_suppressed_hints % "pk_suppressed_hint = %s" 248 _cmds_store_payload = [] 249 _updatable_fields = [] 250 #--------------------------------------------------------
251 - def format(self):
252 txt = '%s [#%s]\n' % ( 253 gmTools.bool2subst(self._payload[self._idx['is_active']], _('Suppressed active dynamic hint'), _('Suppressed inactive dynamic hint')), 254 self._payload[self._idx['pk_suppressed_hint']] 255 ) 256 txt += '\n' 257 txt += '%s\n\n' % self._payload[self._idx['title']] 258 txt += _('Suppressed by: %s\n') % self._payload[self._idx['suppressed_by']] 259 txt += _('Suppressed at: %s\n') % gmDateTime.pydt_strftime(self._payload[self._idx['suppressed_when']], '%Y %b %d') 260 txt += _('Hint #: %s\n') % self._payload[self._idx['pk_hint']] 261 txt += _('Patient #: %s\n') % self._payload[self._idx['pk_identity']] 262 txt += _('MD5 (currently): %s\n') % self._payload[self._idx['md5_hint']] 263 txt += _('MD5 (at suppression): %s\n') % self._payload[self._idx['md5_suppressed']] 264 txt += _('Source: %s\n') % self._payload[self._idx['source']] 265 txt += _('Language: %s\n') % self._payload[self._idx['lang']] 266 txt += '\n' 267 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['hint']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 268 txt += '\n' 269 if self._payload[self._idx['recommendation']] is not None: 270 txt += '\n' 271 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['recommendation']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 272 txt += '\n' 273 txt += '%s\n' % gmTools.wrap ( 274 gmTools.coalesce(self._payload[self._idx['url']], ''), 275 width = 50, 276 initial_indent = ' ', 277 subsequent_indent = ' ' 278 ) 279 txt += '\n' 280 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['query']], width = 50, initial_indent = ' ', subsequent_indent = ' ') 281 return txt
282 283 #------------------------------------------------------------
284 -def get_suppressed_hints(pk_identity=None, order_by=None, return_pks=False):
285 args = {'pat': pk_identity} 286 if pk_identity is None: 287 where = 'true' 288 else: 289 where = "pk_identity = %(pat)s" 290 if order_by is None: 291 order_by = '' 292 else: 293 order_by = ' ORDER BY %s' % order_by 294 cmd = (_SQL_get_suppressed_hints % where) + order_by 295 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 296 if return_pks: 297 return [ r['pk_suppressed_hint'] for r in rows ] 298 return [ cSuppressedHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_suppressed_hint'}) for r in rows ]
299 300 #------------------------------------------------------------
301 -def delete_suppressed_hint(pk_suppressed_hint=None):
302 args = {'pk': pk_suppressed_hint} 303 cmd = "DELETE FROM clin.suppressed_hint WHERE pk = %(pk)s" 304 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 305 return True
306 307 #------------------------------------------------------------
308 -def invalidate_hint_suppression(pk_hint=None, pk_encounter=None):
309 _log.debug('invalidating suppression of hint #%s', pk_hint) 310 args = { 311 'pk_hint': pk_hint, 312 'enc': pk_encounter, 313 'fake_md5': '***INVALIDATED***' # only needs to NOT match ANY md5 sum 314 } 315 cmd = """ 316 UPDATE clin.suppressed_hint SET 317 fk_encounter = %(enc)s, 318 md5_sum = %(fake_md5)s 319 WHERE 320 pk = ( 321 SELECT pk_suppressed_hint 322 FROM clin.v_suppressed_hints 323 WHERE 324 pk_hint = %(pk_hint)s 325 AND 326 pk_identity = ( 327 SELECT fk_patient FROM clin.encounter WHERE pk = %(enc)s 328 ) 329 ) 330 """ 331 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 332 return True
333 334 #============================================================ 335 if __name__ == '__main__': 336 337 if len(sys.argv) < 2: 338 sys.exit() 339 340 if sys.argv[1] != 'test': 341 sys.exit() 342 343 from Gnumed.pycommon import gmI18N 344 345 gmI18N.activate_locale() 346 gmI18N.install_domain() 347 348 #---------------------------------------
349 - def test_auto_hints():
350 # for row in get_dynamic_hints(): 351 # print row 352 for row in get_hints_for_patient(pk_identity = 12): 353 print(row)
354 #--------------------------------------- 355 test_auto_hints() 356