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