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_reminders(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'due_date IS NOT NULL' 130 ] 131 132 cmd = u"SELECT * 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_due_messages(pk_patient=None, order_by=None):
141 142 if order_by is None: 143 order_by = u'%s ORDER BY due_date, importance DESC, received_when DESC' 144 else: 145 order_by = u'%%s ORDER BY %s' % order_by 146 147 args = {'pat': pk_patient} 148 where_parts = [ 149 u'pk_patient = %(pat)s', 150 u'is_due IS TRUE' 151 ] 152 153 cmd = u"SELECT * FROM dem.v_message_inbox WHERE %s" % ( 154 order_by % u' AND '.join(where_parts) 155 ) 156 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 157 158 return [ cInboxMessage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_inbox_message'}) for r in rows ]
159 160 #------------------------------------------------------------
161 -def get_inbox_messages(pk_staff=None, pk_patient=None, include_without_provider=False, order_by=None):
162 163 if order_by is None: 164 order_by = u'%s ORDER BY importance desc, received_when desc' 165 else: 166 order_by = u'%%s ORDER BY %s' % order_by 167 168 args = {} 169 where_parts = [] 170 171 if pk_staff is not None: 172 if include_without_provider: 173 where_parts.append(u'pk_staff IN (%(staff)s, NULL) OR modified_by = (SELECT short_alias FROM dem.staff WHERE pk = %(staff)s)') 174 else: 175 where_parts.append(u'pk_staff = %(staff)s OR modified_by = (SELECT short_alias FROM dem.staff WHERE pk = %(staff)s)') 176 args['staff'] = pk_staff 177 178 if pk_patient is not None: 179 where_parts.append(u'pk_patient = %(pat)s') 180 args['pat'] = pk_patient 181 182 cmd = _SQL_get_inbox_messages % ( 183 order_by % u' AND '.join(where_parts) 184 ) 185 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 186 187 return [ cInboxMessage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_inbox_message'}) for r in rows ]
188 #------------------------------------------------------------
189 -def create_inbox_message(message_type=None, subject=None, patient=None, staff=None):
190 191 success, pk_type = gmTools.input2int(initial = message_type) 192 if not success: 193 pk_type = create_inbox_item_type(message_type = message_type) 194 195 cmd = u""" 196 INSERT INTO dem.message_inbox ( 197 fk_staff, 198 fk_patient, 199 fk_inbox_item_type, 200 comment 201 ) VALUES ( 202 %(staff)s, 203 %(pat)s, 204 %(type)s, 205 gm.nullify_empty_string(%(subject)s) 206 ) 207 RETURNING pk 208 """ 209 args = { 210 u'staff': staff, 211 u'pat': patient, 212 u'type': pk_type, 213 u'subject': subject 214 } 215 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False) 216 217 return cInboxMessage(aPK_obj = rows[0]['pk'])
218 #------------------------------------------------------------
219 -def delete_inbox_message(inbox_message=None):
220 args = {'pk': inbox_message} 221 cmd = u"DELETE FROM dem.message_inbox WHERE pk = %(pk)s" 222 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 223 return True
224 #------------------------------------------------------------
225 -def create_inbox_item_type(message_type=None, category=u'clinical'):
226 227 # determine category PK 228 success, pk_cat = gmTools.input2int(initial = category) 229 if not success: 230 args = {u'cat': category} 231 cmd = u"""SELECT COALESCE ( 232 (SELECT pk FROM dem.inbox_item_category WHERE _(description) = %(cat)s), 233 (SELECT pk FROM dem.inbox_item_category WHERE description = %(cat)s) 234 ) AS pk""" 235 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 236 if rows[0]['pk'] is None: 237 cmd = u"INSERT INTO dem.inbox_item_category (description) VALUES (%(cat)s) RETURNING pk" 238 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 239 pk_cat = rows[0]['pk'] 240 else: 241 pk_cat = rows[0]['pk'] 242 243 # find type PK or create type 244 args = {u'cat': pk_cat, u'type': message_type} 245 cmd = u"""SELECT COALESCE ( 246 (SELECT pk FROM dem.inbox_item_type where fk_inbox_item_category = %(cat)s and _(description) = %(type)s), 247 (SELECT pk FROM dem.inbox_item_type where fk_inbox_item_category = %(cat)s and description = %(type)s) 248 ) AS pk""" 249 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 250 if rows[0]['pk'] is None: 251 cmd = u""" 252 INSERT INTO dem.inbox_item_type ( 253 fk_inbox_item_category, 254 description, 255 is_user 256 ) VALUES ( 257 %(cat)s, 258 %(type)s, 259 TRUE 260 ) RETURNING pk""" 261 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 262 263 return rows[0]['pk']
264 265 #============================================================
266 -class cProviderInbox:
267 - def __init__(self, provider_id=None):
268 if provider_id is None: 269 self.__provider_id = gmStaff.gmCurrentProvider()['pk_staff'] 270 else: 271 self.__provider_id = provider_id
272 #--------------------------------------------------------
273 - def delete_message(self, pk=None):
274 return delete_inbox_message(inbox_message = pk)
275 #--------------------------------------------------------
276 - def add_message(message_type=None, subject=None, patient=None):
277 return create_inbox_message ( 278 message_type = message_type, 279 subject = subject, 280 patient = patient, 281 staff = self.__provider_id 282 )
283 #-------------------------------------------------------- 284 # properties 285 #--------------------------------------------------------
286 - def _get_messages(self):
287 return get_inbox_messages(pk_staff = self.__provider_id)
288
289 - def _set_messages(self, messages):
290 return
291 292 messages = property(_get_messages, _set_messages)
293 294 #============================================================ 295 # dynamic hints API 296 #------------------------------------------------------------ 297 _SQL_get_dynamic_hints = u"SELECT *, xmin AS xmin_auto_hint FROM ref.auto_hint WHERE %s" 298
299 -class cDynamicHint(gmBusinessDBObject.cBusinessDBObject):
300 """Represents dynamic hints to be run against the database.""" 301 302 _cmd_fetch_payload = _SQL_get_dynamic_hints % u"pk = %s" 303 _cmds_store_payload = [ 304 u"""UPDATE ref.auto_hint SET 305 is_active = %(is_active)s 306 WHERE 307 pk = %(pk)s 308 AND 309 xmin = %(xmin_auto_hint)s 310 RETURNING 311 pk, 312 xmin AS xmin_auto_hint 313 """ 314 ] 315 _updatable_fields = [ 316 u'is_active' 317 ] 318 #--------------------------------------------------------
319 - def format(self):
320 txt = u'%s [#%s]\n' % ( 321 gmTools.bool2subst(self._payload[self._idx['is_active']], _('Active clinical hint'), _('Inactive clinical hint')), 322 self._payload[self._idx['pk']] 323 ) 324 txt += u'\n' 325 txt += u'%s\n\n' % self._payload[self._idx['title']] 326 txt += _('Source: %s\n') % self._payload[self._idx['source']] 327 txt += _('Language: %s\n') % self._payload[self._idx['lang']] 328 txt += u'\n' 329 txt += u'%s\n' % gmTools.wrap(self._payload[self._idx['hint']], width = 50, initial_indent = u' ', subsequent_indent = u' ') 330 txt += u'\n' 331 txt += u'%s\n' % gmTools.wrap ( 332 gmTools.coalesce(self._payload[self._idx['url']], u''), 333 width = 50, 334 initial_indent = u' ', 335 subsequent_indent = u' ' 336 ) 337 txt += u'\n' 338 txt += u'%s\n' % gmTools.wrap(self._payload[self._idx['query']], width = 50, initial_indent = u' ', subsequent_indent = u' ') 339 return txt
340 341 #------------------------------------------------------------
342 -def get_dynamic_hints(order_by=None):
343 if order_by is None: 344 order_by = u'true' 345 else: 346 order_by = u'true ORDER BY %s' % order_by 347 348 cmd = _SQL_get_dynamic_hints % order_by 349 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 350 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk'}) for r in rows ]
351 #------------------------------------------------------------ 352 #def create_xxx(xxx=None, xxx=None): 353 # 354 # args = { 355 # u'xxx': xxx, 356 # u'xxx': xxx 357 # } 358 # cmd = u""" 359 # INSERT INTO xxx.xxx ( 360 # xxx, 361 # xxx, 362 # xxx 363 # ) VALUES ( 364 # %(xxx)s, 365 # %(xxx)s, 366 # gm.nullify_empty_string(%(xxx)s) 367 # ) 368 # RETURNING pk 369 # """ 370 # rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False) 371 # 372 # return cDynamicHint(aPK_obj = rows[0]['pk']) 373 #------------------------------------------------------------ 374 #def delete_xxx(xxx=None): 375 # args = {'pk': xxx} 376 # cmd = u"DELETE FROM xxx.xxx WHERE pk = %(pk)s" 377 # gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 378 # return True 379 #------------------------------------------------------------ 380 381 #------------------------------------------------------------
382 -def get_hints_for_patient(pk_identity=None):
383 conn = gmPG2.get_connection() 384 curs = conn.cursor() 385 curs.callproc('clin.get_hints_for_patient', [pk_identity]) 386 rows = curs.fetchall() 387 idx = gmPG2.get_col_indices(curs) 388 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk'}) for r in rows ]
389 390 #============================================================ 391 if __name__ == '__main__': 392 393 if len(sys.argv) < 2: 394 sys.exit() 395 396 if sys.argv[1] != 'test': 397 sys.exit() 398 399 from Gnumed.pycommon import gmI18N 400 401 gmI18N.activate_locale() 402 gmI18N.install_domain() 403 404 #---------------------------------------
405 - def test_inbox():
406 gmStaff.gmCurrentProvider(provider = gmStaff.cStaff()) 407 inbox = cProviderInbox() 408 for msg in inbox.messages: 409 print msg
410 #---------------------------------------
411 - def test_msg():
412 msg = cInboxMessage(aPK_obj = 1) 413 print msg
414 #---------------------------------------
415 - def test_create_type():
416 print create_inbox_item_type(message_type = 'test')
417 #---------------------------------------
418 - def test_due():
419 for msg in get_due_messages(pk_patient = 12): 420 print msg.format()
421 #---------------------------------------
422 - def test_auto_hints():
423 for row in get_dynamic_hints(pk_identity = 13): 424 print row
425 #--------------------------------------- 426 #test_inbox() 427 #test_msg() 428 #test_create_type() 429 #test_due() 430 test_auto_hints() 431 432 #============================================================ 433