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

Source Code for Module Gnumed.business.gmProviderInbox

  1  # -*- coding: latin-1 -*- 
  2  """GNUmed provider inbox 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   
 13   
 14  if __name__ == '__main__': 
 15          sys.path.insert(0, '../../') 
 16  from Gnumed.pycommon import gmPG2 
 17  from Gnumed.pycommon import gmBusinessDBObject 
 18  from Gnumed.pycommon import gmTools 
 19  from Gnumed.pycommon import gmDateTime 
 20   
 21  from Gnumed.business import gmStaff 
 22   
 23  #============================================================ 
 24  # provider message inbox 
 25  #------------------------------------------------------------ 
 26  _SQL_get_inbox_messages = u"SELECT * FROM dem.v_message_inbox WHERE %s" 
 27   
28 -class cInboxMessage(gmBusinessDBObject.cBusinessDBObject):
29 30 _cmd_fetch_payload = _SQL_get_inbox_messages % u"pk_inbox_message = %s" 31 _cmds_store_payload = [ 32 u""" 33 UPDATE dem.message_inbox SET 34 fk_staff = %(pk_staff)s, 35 fk_inbox_item_type = %(pk_type)s, 36 comment = gm.nullify_empty_string(%(comment)s), 37 data = gm.nullify_empty_string(%(data)s), 38 importance = %(importance)s, 39 fk_patient = %(pk_patient)s, 40 ufk_context = NULLIF(%(pk_context)s::integer[], ARRAY[NULL::integer]), 41 due_date = %(due_date)s, 42 expiry_date = %(expiry_date)s 43 WHERE 44 pk = %(pk_inbox_message)s 45 AND 46 xmin = %(xmin_message_inbox)s 47 RETURNING 48 pk as pk_inbox_message, 49 xmin as xmin_message_inbox 50 """ 51 ] 52 _updatable_fields = [ 53 u'pk_staff', 54 u'pk_type', 55 u'comment', 56 u'data', 57 u'importance', 58 u'pk_patient', 59 u'pk_context', 60 u'due_date', 61 u'expiry_date' 62 ] 63 #------------------------------------------------------------
64 - def format(self):
65 tt = u'%s: %s%s\n' % ( 66 gmDateTime.pydt_strftime ( 67 self._payload[self._idx['received_when']], 68 format = '%A, %Y %B %d, %H:%M', 69 accuracy = gmDateTime.acc_minutes 70 ), 71 gmTools.bool2subst(self._payload[self._idx['is_virtual']], _('virtual message'), _('message')), 72 gmTools.coalesce(self._payload[self._idx['pk_inbox_message']], u'', u' #%s ') 73 ) 74 75 tt += u'%s: %s\n' % ( 76 self._payload[self._idx['l10n_category']], 77 self._payload[self._idx['l10n_type']] 78 ) 79 80 tt += u'%s %s %s\n' % ( 81 self._payload[self._idx['modified_by']], 82 gmTools.u_right_arrow, 83 gmTools.coalesce(self._payload[self._idx['provider']], _('everyone')) 84 ) 85 86 tt += u'\n%s%s%s\n\n' % ( 87 gmTools.u_left_double_angle_quote, 88 self._payload[self._idx['comment']], 89 gmTools.u_right_double_angle_quote 90 ) 91 92 tt += gmTools.coalesce ( 93 self._payload[self._idx['pk_patient']], 94 u'', 95 u'%s\n\n' % _('Patient #%s') 96 ) 97 98 tt += gmTools.coalesce ( 99 self._payload[self._idx['due_date']], 100 u'', 101 _('Due: %s\n'), 102 function_initial = ('strftime', '%Y-%m-%d') 103 ) 104 105 tt += gmTools.coalesce ( 106 self._payload[self._idx['expiry_date']], 107 u'', 108 _('Expiry: %s\n'), 109 function_initial = ('strftime', '%Y-%m-%d') 110 ) 111 112 if self._payload[self._idx['data']] is not None: 113 tt += self._payload[self._idx['data']][:150] 114 if len(self._payload[self._idx['data']]) > 150: 115 tt += gmTools.u_ellipsis 116 117 return tt
118 #------------------------------------------------------------
119 -def get_due_messages(pk_patient=None, order_by=None):
120 121 if order_by is None: 122 order_by = u'%s ORDER BY due_date, importance DESC, received_when DESC' 123 else: 124 order_by = u'%%s ORDER BY %s' % order_by 125 126 args = {'pat': pk_patient} 127 where_parts = [ 128 u'pk_patient = %(pat)s', 129 u'is_due IS TRUE' 130 ] 131 132 cmd = u"SELECT *, now() - due_date AS interval_due FROM dem.v_message_inbox WHERE %s" % ( 133 order_by % u' AND '.join(where_parts) 134 ) 135 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 136 137 return [ cInboxMessage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_inbox_message'}) for r in rows ]
138 139 #------------------------------------------------------------
140 -def get_inbox_messages(pk_staff=None, pk_patient=None, include_without_provider=False, order_by=None):
141 142 if order_by is None: 143 order_by = u'%s ORDER BY importance desc, received_when desc' 144 else: 145 order_by = u'%%s ORDER BY %s' % order_by 146 147 args = {} 148 where_parts = [] 149 150 if pk_staff is not None: 151 if include_without_provider: 152 where_parts.append(u'pk_staff IN (%(staff)s, NULL) OR modified_by = (SELECT short_alias FROM dem.staff WHERE pk = %(staff)s)') 153 else: 154 where_parts.append(u'pk_staff = %(staff)s OR modified_by = (SELECT short_alias FROM dem.staff WHERE pk = %(staff)s)') 155 args['staff'] = pk_staff 156 157 if pk_patient is not None: 158 where_parts.append(u'pk_patient = %(pat)s') 159 args['pat'] = pk_patient 160 161 cmd = _SQL_get_inbox_messages % ( 162 order_by % u' AND '.join(where_parts) 163 ) 164 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 165 166 return [ cInboxMessage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_inbox_message'}) for r in rows ]
167 #------------------------------------------------------------
168 -def create_inbox_message(message_type=None, subject=None, patient=None, staff=None):
169 170 success, pk_type = gmTools.input2int(initial = message_type) 171 if not success: 172 pk_type = create_inbox_item_type(message_type = message_type) 173 174 cmd = u""" 175 INSERT INTO dem.message_inbox ( 176 fk_staff, 177 fk_patient, 178 fk_inbox_item_type, 179 comment 180 ) VALUES ( 181 %(staff)s, 182 %(pat)s, 183 %(type)s, 184 gm.nullify_empty_string(%(subject)s) 185 ) 186 RETURNING pk 187 """ 188 args = { 189 u'staff': staff, 190 u'pat': patient, 191 u'type': pk_type, 192 u'subject': subject 193 } 194 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False) 195 196 return cInboxMessage(aPK_obj = rows[0]['pk'])
197 #------------------------------------------------------------
198 -def delete_inbox_message(inbox_message=None):
199 args = {'pk': inbox_message} 200 cmd = u"DELETE FROM dem.message_inbox WHERE pk = %(pk)s" 201 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 202 return True
203 #------------------------------------------------------------
204 -def create_inbox_item_type(message_type=None, category=u'clinical'):
205 206 # determine category PK 207 success, pk_cat = gmTools.input2int(initial = category) 208 if not success: 209 args = {u'cat': category} 210 cmd = u"""SELECT COALESCE ( 211 (SELECT pk FROM dem.inbox_item_category WHERE _(description) = %(cat)s), 212 (SELECT pk FROM dem.inbox_item_category WHERE description = %(cat)s) 213 ) AS pk""" 214 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 215 if rows[0]['pk'] is None: 216 cmd = u"INSERT INTO dem.inbox_item_category (description) VALUES (%(cat)s) RETURNING pk" 217 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 218 pk_cat = rows[0]['pk'] 219 else: 220 pk_cat = rows[0]['pk'] 221 222 # find type PK or create type 223 args = {u'cat': pk_cat, u'type': message_type} 224 cmd = u"""SELECT COALESCE ( 225 (SELECT pk FROM dem.inbox_item_type where fk_inbox_item_category = %(cat)s and _(description) = %(type)s), 226 (SELECT pk FROM dem.inbox_item_type where fk_inbox_item_category = %(cat)s and description = %(type)s) 227 ) AS pk""" 228 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 229 if rows[0]['pk'] is None: 230 cmd = u""" 231 INSERT INTO dem.inbox_item_type ( 232 fk_inbox_item_category, 233 description, 234 is_user 235 ) VALUES ( 236 %(cat)s, 237 %(type)s, 238 TRUE 239 ) RETURNING pk""" 240 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 241 242 return rows[0]['pk']
243 244 #============================================================
245 -class cProviderInbox:
246 - def __init__(self, provider_id=None):
247 if provider_id is None: 248 self.__provider_id = gmStaff.gmCurrentProvider()['pk_staff'] 249 else: 250 self.__provider_id = provider_id
251 #--------------------------------------------------------
252 - def delete_message(self, pk=None):
253 return delete_inbox_message(inbox_message = pk)
254 #--------------------------------------------------------
255 - def add_message(message_type=None, subject=None, patient=None):
256 return create_inbox_message ( 257 message_type = message_type, 258 subject = subject, 259 patient = patient, 260 staff = self.__provider_id 261 )
262 #-------------------------------------------------------- 263 # properties 264 #--------------------------------------------------------
265 - def _get_messages(self):
266 return get_inbox_messages(pk_staff = self.__provider_id)
267
268 - def _set_messages(self, messages):
269 return
270 271 messages = property(_get_messages, _set_messages)
272 273 #============================================================ 274 # dynamic hints API 275 #------------------------------------------------------------ 276 _SQL_get_dynamic_hints = u"SELECT *, xmin AS xmin_auto_hint FROM ref.auto_hint WHERE %s" 277
278 -class cDynamicHint(gmBusinessDBObject.cBusinessDBObject):
279 """Represents dynamic hints to be run against the database.""" 280 281 _cmd_fetch_payload = _SQL_get_dynamic_hints % u"pk = %s" 282 _cmds_store_payload = [ 283 u"""UPDATE ref.auto_hint SET 284 is_active = %(is_active)s 285 WHERE 286 pk = %(pk)s 287 AND 288 xmin = %(xmin_auto_hint)s 289 RETURNING 290 pk, 291 xmin AS xmin_auto_hint 292 """ 293 ] 294 _updatable_fields = [ 295 u'is_active' 296 ] 297 #--------------------------------------------------------
298 - def format(self):
299 txt = u'%s [#%s]\n' % ( 300 gmTools.bool2subst(self._payload[self._idx['is_active']], _('Active clinical hint'), _('Inactive clinical hint')), 301 self._payload[self._idx['pk']] 302 ) 303 txt += u'\n' 304 txt += u'%s\n\n' % self._payload[self._idx['title']] 305 txt += _('Source: %s\n') % self._payload[self._idx['source']] 306 txt += _('Language: %s\n') % self._payload[self._idx['lang']] 307 txt += u'\n' 308 txt += u'%s\n' % gmTools.wrap(self._payload[self._idx['hint']], width = 50, initial_indent = u' ', subsequent_indent = u' ') 309 txt += u'\n' 310 txt += u'%s\n' % gmTools.wrap ( 311 gmTools.coalesce(self._payload[self._idx['url']], u''), 312 width = 50, 313 initial_indent = u' ', 314 subsequent_indent = u' ' 315 ) 316 txt += u'\n' 317 txt += u'%s\n' % gmTools.wrap(self._payload[self._idx['query']], width = 50, initial_indent = u' ', subsequent_indent = u' ') 318 return txt
319 320 #------------------------------------------------------------
321 -def get_dynamic_hints(order_by=None):
322 if order_by is None: 323 order_by = u'true' 324 else: 325 order_by = u'true ORDER BY %s' % order_by 326 327 cmd = _SQL_get_dynamic_hints % order_by 328 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 329 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk'}) for r in rows ]
330 #------------------------------------------------------------ 331 #def create_xxx(xxx=None, xxx=None): 332 # 333 # args = { 334 # u'xxx': xxx, 335 # u'xxx': xxx 336 # } 337 # cmd = u""" 338 # INSERT INTO xxx.xxx ( 339 # xxx, 340 # xxx, 341 # xxx 342 # ) VALUES ( 343 # %(xxx)s, 344 # %(xxx)s, 345 # gm.nullify_empty_string(%(xxx)s) 346 # ) 347 # RETURNING pk 348 # """ 349 # rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False) 350 # 351 # return cDynamicHint(aPK_obj = rows[0]['pk']) 352 #------------------------------------------------------------ 353 #def delete_xxx(xxx=None): 354 # args = {'pk': xxx} 355 # cmd = u"DELETE FROM xxx.xxx WHERE pk = %(pk)s" 356 # gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 357 # return True 358 #------------------------------------------------------------ 359 360 #------------------------------------------------------------
361 -def get_hints_for_patient(pk_identity=None):
362 conn = gmPG2.get_connection() 363 curs = conn.cursor() 364 curs.callproc('clin.get_hints_for_patient', [pk_identity]) 365 rows = curs.fetchall() 366 idx = gmPG2.get_col_indices(curs) 367 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk'}) for r in rows ]
368 369 #============================================================ 370 if __name__ == '__main__': 371 372 if len(sys.argv) < 2: 373 sys.exit() 374 375 if sys.argv[1] != 'test': 376 sys.exit() 377 378 from Gnumed.pycommon import gmI18N 379 380 gmI18N.activate_locale() 381 gmI18N.install_domain() 382 383 #---------------------------------------
384 - def test_inbox():
385 gmStaff.gmCurrentProvider(provider = gmStaff.cStaff()) 386 inbox = cProviderInbox() 387 for msg in inbox.messages: 388 print msg
389 #---------------------------------------
390 - def test_msg():
391 msg = cInboxMessage(aPK_obj = 1) 392 print msg
393 #---------------------------------------
394 - def test_create_type():
395 print create_inbox_item_type(message_type = 'test')
396 #---------------------------------------
397 - def test_due():
398 for msg in get_due_messages(pk_patient = 12): 399 print msg.format()
400 #---------------------------------------
401 - def test_auto_hints():
402 for row in get_dynamic_hints(pk_identity = 13): 403 print row
404 #--------------------------------------- 405 #test_inbox() 406 #test_msg() 407 #test_create_type() 408 #test_due() 409 test_auto_hints() 410 411 #============================================================ 412