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

Source Code for Module Gnumed.business.gmPraxis

  1  # -*- coding: utf8 -*- 
  2  """GNUmed Praxis related middleware.""" 
  3  #============================================================ 
  4  __license__ = "GPL" 
  5  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>" 
  6   
  7   
  8  import sys 
  9  import logging 
 10  import io 
 11  import urllib.parse 
 12   
 13   
 14  if __name__ == '__main__': 
 15          sys.path.insert(0, '../../') 
 16  from Gnumed.pycommon import gmPG2 
 17  from Gnumed.pycommon import gmTools 
 18  from Gnumed.pycommon import gmBorg 
 19  from Gnumed.pycommon import gmCfg2 
 20  from Gnumed.pycommon import gmBusinessDBObject 
 21   
 22  from Gnumed.business import gmOrganization 
 23   
 24   
 25  _log = logging.getLogger('gm.praxis') 
 26  _cfg = gmCfg2.gmCfgData() 
 27   
 28  #============================================================ 
29 -def delete_workplace(workplace=None, delete_config=False, conn=None):
30 31 args = {'wp': workplace} 32 33 # delete workplace itself (plugin load list, that is) 34 queries = [ 35 {'cmd': """ 36 delete from cfg.cfg_item 37 where 38 fk_template = ( 39 select pk 40 from cfg.cfg_template 41 where name = 'horstspace.notebook.plugin_load_order' 42 ) 43 and 44 workplace = %(wp)s""", 45 'args': args 46 } 47 ] 48 49 # delete other config items associated with this workplace 50 if delete_config: 51 queries.append ({ 52 'cmd': """ 53 delete from cfg.cfg_item 54 where 55 workplace = %(wp)s""", 56 'args': args 57 }) 58 59 gmPG2.run_rw_queries(link_obj = conn, queries = queries, end_tx = True)
60 61 #============================================================ 62 # short description 63 #------------------------------------------------------------ 64 _SQL_get_praxis_branches = "SELECT * FROM dem.v_praxis_branches WHERE %s" 65
66 -class cPraxisBranch(gmBusinessDBObject.cBusinessDBObject):
67 """Represents a praxis branch""" 68 69 _cmd_fetch_payload = _SQL_get_praxis_branches % "pk_praxis_branch = %s" 70 _cmds_store_payload = [ 71 """UPDATE dem.praxis_branch SET 72 fk_org_unit = %(pk_org_unit)s 73 WHERE 74 pk = %(pk_praxis_branch)s 75 AND 76 xmin = %(xmin_praxis_branch)s 77 RETURNING 78 xmin as xmin_praxis_branch 79 """ 80 ] 81 _updatable_fields = [ 82 'pk_org_unit' 83 ] 84 #--------------------------------------------------------
85 - def format(self):
86 txt = _('Praxis branch #%s\n') % self._payload[self._idx['pk_praxis_branch']] 87 txt += ' ' 88 txt += '\n '.join(self.org_unit.format(with_address = True, with_org = True, with_comms = True)) 89 return txt
90 91 #--------------------------------------------------------
92 - def lock(self, exclusive=False):
93 return lock_praxis_branch(pk_praxis_branch = self._payload[self._idx['pk_praxis_branch']], exclusive = exclusive)
94 95 #--------------------------------------------------------
96 - def unlock(self, exclusive=False):
97 return unlock_praxis_branch(pk_praxis_branch = self._payload[self._idx['pk_praxis_branch']], exclusive = exclusive)
98 99 #--------------------------------------------------------
100 - def get_comm_channels(self, comm_medium=None):
101 return self.org_unit.get_comm_channels(comm_medium = comm_medium)
102 103 #--------------------------------------------------------
104 - def get_external_ids(self, id_type=None, issuer=None):
105 return self.org_unit.get_external_ids(id_type = id_type, issuer = issuer)
106 107 #--------------------------------------------------------
108 - def get_distance2address_url(self, address):
109 self_adr = self.address 110 url = 'https://www.luftlinie.org/%s-%s-%s-%s-%s/%s-%s-%s-%s-%s' % ( 111 urllib.parse.quote(self_adr['street'].encode('utf8')), 112 urllib.parse.quote(self_adr['number'].encode('utf8')), 113 urllib.parse.quote(self_adr['urb'].encode('utf8')), 114 urllib.parse.quote(self_adr['postcode'].encode('utf8')), 115 urllib.parse.quote(self_adr['country'].encode('utf8')), 116 urllib.parse.quote(address['street'].encode('utf8')), 117 urllib.parse.quote(address['number'].encode('utf8')), 118 urllib.parse.quote(address['urb'].encode('utf8')), 119 urllib.parse.quote(address['postcode'].encode('utf8')), 120 urllib.parse.quote(address['country'].encode('utf8')) 121 ) 122 return url
123 124 #-------------------------------------------------------- 125 # properties 126 #--------------------------------------------------------
127 - def _get_org_unit(self):
128 return gmOrganization.cOrgUnit(aPK_obj = self._payload[self._idx['pk_org_unit']])
129 130 org_unit = property(_get_org_unit, lambda x:x) 131 132 #--------------------------------------------------------
133 - def _get_org(self):
134 return gmOrganization.cOrg(aPK_obj = self._payload[self._idx['pk_org']])
135 136 organization = property(_get_org, lambda x:x) 137 138 #--------------------------------------------------------
139 - def _get_address(self):
140 return self.org_unit.address
141 142 address = property(_get_address, lambda x:x) 143 144 # def _set_address(self, address): 145 # self['pk_address'] = address['pk_address'] 146 # self.save() 147 # address = property(_get_address, _set_address) 148 149 #--------------------------------------------------------
150 - def _get_vcf(self):
151 vcf_fields = [ 152 'BEGIN:VCARD', 153 'VERSION:4.0', 154 'KIND:org', 155 _('FN:%(l10n_unit_category)s %(branch)s of %(l10n_organization_category)s %(praxis)s') % self, 156 'N:%(praxis)s;%(branch)s' % self 157 ] 158 adr = self.address 159 if adr is not None: 160 vcf_fields.append('ADR:;%(subunit)s;%(street)s %(number)s;%(urb)s;%(l10n_region)s;%(postcode)s;%(l10n_country)s' % adr) 161 comms = self.get_comm_channels(comm_medium = 'workphone') 162 if len(comms) > 0: 163 vcf_fields.append('TEL;VALUE=uri;TYPE=work:tel:%(url)s' % comms[0]) 164 comms = self.get_comm_channels(comm_medium = 'email') 165 if len(comms) > 0: 166 vcf_fields.append('EMAIL:%(url)s' % comms[0]) 167 vcf_fields.append('END:VCARD') 168 vcf_fname = gmTools.get_unique_filename ( 169 prefix = 'gm-praxis-', 170 suffix = '.vcf' 171 ) 172 vcf_file = io.open(vcf_fname, mode = 'wt', encoding = 'utf8') 173 vcf_file.write('\n'.join(vcf_fields)) 174 vcf_file.write('\n') 175 vcf_file.close() 176 return vcf_fname
177 178 vcf = property(_get_vcf, lambda x:x)
179 180 #------------------------------------------------------------
181 -def lock_praxis_branch(pk_praxis_branch=None, exclusive=False):
182 return gmPG2.lock_row(table = 'dem.praxis_branch', pk = pk_praxis_branch, exclusive = exclusive)
183 184 #------------------------------------------------------------
185 -def unlock_praxis_branch(pk_praxis_branch=None, exclusive=False):
186 return gmPG2.unlock_row(table = 'dem.praxis_branch', pk = pk_praxis_branch, exclusive = exclusive)
187 188 #------------------------------------------------------------
189 -def get_praxis_branches(order_by=None):
190 if order_by is None: 191 order_by = 'true' 192 else: 193 order_by = 'true ORDER BY %s' % order_by 194 195 cmd = _SQL_get_praxis_branches % order_by 196 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 197 return [ cPraxisBranch(row = {'data': r, 'idx': idx, 'pk_field': 'pk_praxis_branch'}) for r in rows ]
198 199 #------------------------------------------------------------
200 -def get_praxis_branch_by_org_unit(pk_org_unit=None):
201 cmd = _SQL_get_praxis_branches % 'pk_org_unit = %(pk_ou)s' 202 args = {'pk_ou': pk_org_unit} 203 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 204 if len(rows) == 0: 205 return None 206 return cPraxisBranch(row = {'data': rows[0], 'idx': idx, 'pk_field': 'pk_praxis_branch'})
207 208 #------------------------------------------------------------
209 -def create_praxis_branch(pk_org_unit=None):
210 211 args = {'fk_unit': pk_org_unit} 212 cmd1 = """ 213 INSERT INTO dem.praxis_branch (fk_org_unit) 214 SELECT %(fk_unit)s WHERE NOT EXISTS ( 215 SELECT 1 FROM dem.praxis_branch WHERE fk_org_unit = %(fk_unit)s 216 ) 217 """ 218 cmd2 = """SELECT * from dem.v_praxis_branches WHERE pk_org_unit = %(fk_unit)s""" 219 queries = [ 220 {'cmd': cmd1, 'args': args}, 221 {'cmd': cmd2, 'args': args} 222 ] 223 rows, idx = gmPG2.run_rw_queries(queries = queries, return_data = True, get_col_idx = True) 224 return cPraxisBranch(row = {'data': rows[0], 'idx': idx, 'pk_field': 'pk_praxis_branch'})
225 226 #------------------------------------------------------------
227 -def create_praxis_branches(pk_org_units=None):
228 queries = [] 229 for pk in pk_org_units: 230 args = {'fk_unit': pk} 231 cmd = """ 232 INSERT INTO dem.praxis_branch (fk_org_unit) 233 SELECT %(fk_unit)s WHERE NOT EXISTS ( 234 SELECT 1 FROM dem.praxis_branch WHERE fk_org_unit = %(fk_unit)s 235 ) 236 """ 237 queries.append({'cmd': cmd, 'args': args}) 238 239 args = {'fk_units': tuple(pk_org_units)} 240 cmd = """SELECT * from dem.v_praxis_branches WHERE pk_org_unit IN %(fk_units)s""" 241 queries.append({'cmd': cmd, 'args': args}) 242 rows, idx = gmPG2.run_rw_queries(queries = queries, return_data = True, get_col_idx = True) 243 return [ cPraxisBranch(row = {'data': r, 'idx': idx, 'pk_field': 'pk_praxis_branch'}) for r in rows ]
244 245 #------------------------------------------------------------
246 -def delete_praxis_branch(pk_praxis_branch=None):
247 if not lock_praxis_branch(pk_praxis_branch = pk_praxis_branch, exclusive = True): 248 return False 249 args = {'pk': pk_praxis_branch} 250 cmd = "DELETE FROM dem.praxis_branch WHERE pk = %(pk)s" 251 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 252 unlock_praxis_branch(pk_praxis_branch = pk_praxis_branch, exclusive = True) 253 return True
254 255 #------------------------------------------------------------
256 -def delete_praxis_branches(pk_praxis_branches=None, except_pk_praxis_branches=None):
257 258 if pk_praxis_branches is None: 259 cmd = 'SELECT pk from dem.praxis_branch' 260 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False) 261 pks_to_lock = [ r[0] for r in rows ] 262 else: 263 pks_to_lock = pk_praxis_branches[:] 264 265 if except_pk_praxis_branches is not None: 266 for pk in except_pk_praxis_branches: 267 try: pks_to_lock.remove(pk) 268 except ValueError: pass 269 270 for pk in pks_to_lock: 271 if not lock_praxis_branch(pk_praxis_branch = pk, exclusive = True): 272 return False 273 274 args = {} 275 where_parts = [] 276 277 if pk_praxis_branches is not None: 278 args['pks'] = tuple(pk_praxis_branches) 279 where_parts.append('pk IN %(pks)s') 280 281 if except_pk_praxis_branches is not None: 282 args['except'] = tuple(except_pk_praxis_branches) 283 where_parts.append('pk NOT IN %(except)s') 284 285 if len(where_parts) == 0: 286 cmd = "DELETE FROM dem.praxis_branch" 287 else: 288 cmd = "DELETE FROM dem.praxis_branch WHERE %s" % ' AND '.join(where_parts) 289 290 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 291 for pk in pks_to_lock: 292 unlock_praxis_branch(pk_praxis_branch = pk, exclusive = True) 293 return True
294 295 #============================================================
296 -class gmCurrentPraxisBranch(gmBorg.cBorg):
297
298 - def __init__(self, branch=None):
299 try: 300 self.has_been_initialized 301 except AttributeError: 302 self.branch = None 303 self.has_been_initialized = True 304 self.__helpdesk = None 305 self.__active_workplace = None 306 307 # user wants copy of current branch 308 if branch is None: 309 return None 310 311 # must be cPraxisBranch instance, then 312 if not isinstance(branch, cPraxisBranch): 313 _log.error('cannot set current praxis branch to [%s], must be a cPraxisBranch instance' % str(branch)) 314 raise TypeError('gmPraxis.gmCurrentPraxisBranch.__init__(): <branch> must be a cPraxisBranch instance but is: %s' % str(branch)) 315 316 if self.branch is not None: 317 self.branch.unlock() 318 319 branch.lock() 320 self.branch = branch 321 _log.debug('current praxis branch now: %s', self.branch) 322 323 return None
324 325 #-------------------------------------------------------- 326 # __getattr__ handling 327 #--------------------------------------------------------
328 - def __getattr__(self, attribute):
329 if attribute == 'has_been_initialized': 330 raise AttributeError 331 if attribute in ['branch', 'waiting_list_patients', 'help_desk', 'db_logon_banner', 'active_workplace', 'workplaces', 'user_email']: 332 return getattr(self, attribute) 333 return getattr(self.branch, attribute)
334 335 #-------------------------------------------------------- 336 # __get/setitem__ handling 337 #--------------------------------------------------------
338 - def __getitem__(self, attribute = None):
339 """Return any attribute if known how to retrieve it by proxy.""" 340 return self.branch[attribute]
341 342 #--------------------------------------------------------
343 - def __setitem__(self, attribute, value):
344 self.branch[attribute] = value
345 346 #-------------------------------------------------------- 347 # waiting list handling 348 #--------------------------------------------------------
349 - def remove_from_waiting_list(self, pk=None):
350 cmd = 'delete from clin.waiting_list where pk = %(pk)s' 351 args = {'pk': pk} 352 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
353 #--------------------------------------------------------
354 - def update_in_waiting_list(self, pk = None, urgency = 0, comment = None, zone = None):
355 cmd = """ 356 update clin.waiting_list 357 set 358 urgency = %(urg)s, 359 comment = %(cmt)s, 360 area = %(zone)s 361 where 362 pk = %(pk)s""" 363 args = { 364 'pk': pk, 365 'urg': urgency, 366 'cmt': gmTools.none_if(comment, ''), 367 'zone': gmTools.none_if(zone, '') 368 } 369 370 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
371 #--------------------------------------------------------
372 - def raise_in_waiting_list(self, current_position=None):
373 if current_position == 1: 374 return 375 376 cmd = 'select clin.move_waiting_list_entry(%(pos)s, (%(pos)s - 1))' 377 args = {'pos': current_position} 378 379 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
380 #--------------------------------------------------------
381 - def lower_in_waiting_list(self, current_position=None):
382 cmd = 'select clin.move_waiting_list_entry(%(pos)s, (%(pos)s+1))' 383 args = {'pos': current_position} 384 385 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
386 #-------------------------------------------------------- 387 # properties 388 #--------------------------------------------------------
390 cmd = """ 391 SELECT * FROM clin.v_waiting_list 392 ORDER BY 393 list_position 394 """ 395 rows, idx = gmPG2.run_ro_queries ( 396 queries = [{'cmd': cmd}], 397 get_col_idx = False 398 ) 399 return rows
400 401 waiting_list_patients = property (_get_waiting_list_patients, lambda x:x) 402 403 #--------------------------------------------------------
404 - def _set_helpdesk(self, helpdesk):
405 return
406
407 - def _get_helpdesk(self):
408 409 if self.__helpdesk is not None: 410 return self.__helpdesk 411 412 self.__helpdesk = gmTools.coalesce ( 413 _cfg.get ( 414 group = 'workplace', 415 option = 'help desk', 416 source_order = [ 417 ('explicit', 'return'), 418 ('workbase', 'return'), 419 ('local', 'return'), 420 ('user', 'return'), 421 ('system', 'return') 422 ] 423 ), 424 'http://wiki.gnumed.de' 425 ) 426 427 return self.__helpdesk
428 429 helpdesk = property(_get_helpdesk, _set_helpdesk) 430 431 #--------------------------------------------------------
432 - def _get_db_logon_banner(self):
433 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': 'select _(message) from cfg.db_logon_banner'}]) 434 if len(rows) == 0: 435 return '' 436 return gmTools.coalesce(rows[0][0], '').strip()
437
438 - def _set_db_logon_banner(self, banner):
439 queries = [ 440 {'cmd': 'delete from cfg.db_logon_banner'} 441 ] 442 if banner.strip() != '': 443 queries.append ({ 444 'cmd': 'insert into cfg.db_logon_banner (message) values (%(msg)s)', 445 'args': {'msg': banner.strip()} 446 }) 447 rows, idx = gmPG2.run_rw_queries(queries = queries, end_tx = True)
448 449 db_logon_banner = property(_get_db_logon_banner, _set_db_logon_banner) 450 451 #--------------------------------------------------------
452 - def _set_workplace(self, workplace):
453 # maybe later allow switching workplaces on the fly 454 return True
455
456 - def _get_workplace(self):
457 """Return the current workplace (client profile) definition. 458 459 The first occurrence counts. 460 """ 461 if self.__active_workplace is not None: 462 return self.__active_workplace 463 464 self.__active_workplace = gmTools.coalesce ( 465 _cfg.get ( 466 group = 'workplace', 467 option = 'name', 468 source_order = [ 469 ('explicit', 'return'), 470 ('workbase', 'return'), 471 ('local', 'return'), 472 ('user', 'return'), 473 ('system', 'return'), 474 ] 475 ), 476 'Local Default' 477 ) 478 479 return self.__active_workplace
480 481 active_workplace = property(_get_workplace, _set_workplace) 482 483 #--------------------------------------------------------
484 - def _set_workplaces(self, val):
485 pass
486
487 - def _get_workplaces(self):
488 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': 'SELECT DISTINCT workplace FROM cfg.cfg_item ORDER BY workplace'}]) 489 return [ r[0] for r in rows ]
490 491 workplaces = property(_get_workplaces, _set_workplaces) 492 493 #--------------------------------------------------------
494 - def _get_user_email(self):
495 # FIXME: get this from the current users staff record in the database 496 return _cfg.get ( 497 group = 'preferences', 498 option = 'user email', 499 source_order = [ 500 ('explicit', 'return'), 501 ('user', 'return'), 502 ('local', 'return'), 503 ('workbase', 'return'), 504 ('system', 'return') 505 ] 506 )
507
508 - def _set_user_email(self, val):
509 prefs_file = _cfg.get(option = 'user_preferences_file') 510 gmCfg2.set_option_in_INI_file ( 511 filename = prefs_file, 512 group = 'preferences', 513 option = 'user email', 514 value = val 515 ) 516 _cfg.reload_file_source(file = prefs_file)
517 518 user_email = property(_get_user_email, _set_user_email)
519 520 #============================================================ 521 if __name__ == '__main__': 522 523 if len(sys.argv) < 2: 524 sys.exit() 525 526 if sys.argv[1] != 'test': 527 sys.exit() 528 529 from Gnumed.pycommon import gmI18N 530 gmI18N.install_domain() 531
532 - def run_tests():
533 prac = gmCurrentPraxisBranch() 534 # print "help desk:", prac.helpdesk 535 # print "active workplace:", prac.active_workplace 536 537 old_banner = prac.db_logon_banner 538 test_banner = 'a test banner' 539 prac.db_logon_banner = test_banner 540 if prac.db_logon_banner != test_banner: 541 print(('Cannot set logon banner to', test_banner)) 542 return False 543 prac.db_logon_banner = '' 544 if prac.db_logon_banner != '': 545 print('Cannot set logon banner to ""') 546 return False 547 prac.db_logon_banner = old_banner 548 549 return True
550 551 # if not run_tests(): 552 # print "regression tests failed" 553 # print "regression tests succeeded" 554 555 for b in get_praxis_branches(): 556 print((b.format())) 557 558 #============================================================ 559