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

Source Code for Module Gnumed.business.gmDemographicRecord

  1  # -*- coding: utf8 -*- 
  2  """GNUmed demographics object. 
  3   
  4  This is a patient object intended to let a useful client-side 
  5  API crystallize from actual use in true XP fashion. 
  6   
  7  license: GPL v2 or later 
  8  """ 
  9  #============================================================ 
 10  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>, I.Haywood <ihaywood@gnu.org>" 
 11   
 12  # stdlib 
 13  import sys 
 14  import os 
 15  import os.path 
 16  import logging 
 17   
 18   
 19  # GNUmed 
 20  if __name__ == '__main__': 
 21          sys.path.insert(0, '../../') 
 22  from Gnumed.pycommon import gmDispatcher 
 23  from Gnumed.pycommon import gmBusinessDBObject 
 24  from Gnumed.pycommon import gmPG2 
 25  from Gnumed.pycommon import gmTools 
 26   
 27   
 28  _log = logging.getLogger('gm.business') 
 29   
 30  try: 
 31          _ 
 32  except NameError: 
 33          _ = lambda x:x 
 34   
 35  #============================================================ 
 36  # occupation handling 
 37  #------------------------------------------------------------ 
38 -def get_occupations(pk_identity=None):
39 cmd = u""" 40 SELECT * 41 FROM dem.v_person_jobs 42 WHERE pk_identity = %(pk)s 43 ORDER BY l10n_occupation 44 """ 45 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'pk': pk_identity}}]) 46 return rows
47 #============================================================ 48 # text+image tags 49 #------------------------------------------------------------ 50 _SQL_get_tag_image = u"SELECT * FROM ref.v_tag_images_no_data WHERE %s" 51
52 -class cTagImage(gmBusinessDBObject.cBusinessDBObject):
53 54 _cmd_fetch_payload = _SQL_get_tag_image % u"pk_tag_image = %s" 55 _cmds_store_payload = [ 56 u""" 57 UPDATE ref.tag_image SET 58 description = gm.nullify_empty_string(%(description)s), 59 filename = gm.nullify_empty_string(%(filename)s) 60 WHERE 61 pk = %(pk_tag_image)s 62 AND 63 xmin = %(xmin_tag_image)s 64 RETURNING 65 pk as pk_tag_image, 66 xmin as xmin_tag_image 67 """ 68 ] 69 _updatable_fields = [u'description', u'filename'] 70 #--------------------------------------------------------
71 - def export_image2file(self, aChunkSize=0, filename=None):
72 73 if self._payload[self._idx['size']] == 0: 74 return None 75 76 if filename is None: 77 suffix = None 78 # preserve original filename extension if available 79 if self._payload[self._idx['filename']] is not None: 80 name, suffix = os.path.splitext(self._payload[self._idx['filename']]) 81 suffix = suffix.strip() 82 if suffix == u'': 83 suffix = None 84 # get unique filename 85 filename = gmTools.get_unique_filename ( 86 prefix = 'gm-tag_image-', 87 suffix = suffix 88 ) 89 90 success = gmPG2.bytea2file ( 91 data_query = { 92 'cmd': u'SELECT substring(image from %(start)s for %(size)s) FROM ref.tag_image WHERE pk = %(pk)s', 93 'args': {'pk': self.pk_obj} 94 }, 95 filename = filename, 96 chunk_size = aChunkSize, 97 data_size = self._payload[self._idx['size']] 98 ) 99 100 if success: 101 return filename 102 103 return None
104 #--------------------------------------------------------
105 - def update_image_from_file(self, filename=None):
106 # sanity check 107 if not (os.access(filename, os.R_OK) and os.path.isfile(filename)): 108 _log.error('[%s] is not a readable file' % filename) 109 return False 110 111 gmPG2.file2bytea ( 112 query = u"UPDATE ref.tag_image SET image = %(data)s::bytea WHERE pk = %(pk)s", 113 filename = filename, 114 args = {'pk': self.pk_obj} 115 ) 116 117 # must update XMIN now ... 118 self.refetch_payload() 119 return True
120 #------------------------------------------------------------
121 -def get_tag_images(order_by=None):
122 if order_by is None: 123 order_by = u'true' 124 else: 125 order_by = 'true ORDER BY %s' % order_by 126 127 cmd = _SQL_get_tag_image % order_by 128 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 129 return [ cTagImage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_tag_image'}) for r in rows ]
130 #------------------------------------------------------------
131 -def create_tag_image(description=None, link_obj=None):
132 133 args = {u'desc': description, u'img': u''} 134 cmd = u""" 135 INSERT INTO ref.tag_image ( 136 description, 137 image 138 ) VALUES ( 139 %(desc)s, 140 %(img)s::bytea 141 ) 142 RETURNING pk 143 """ 144 rows, idx = gmPG2.run_rw_queries ( 145 link_obj = link_obj, 146 queries = [{'cmd': cmd, 'args': args}], 147 end_tx = True, 148 return_data = True, 149 get_col_idx = False 150 ) 151 152 return cTagImage(aPK_obj = rows[0]['pk'])
153 #------------------------------------------------------------
154 -def delete_tag_image(tag_image=None):
155 args = {'pk': tag_image} 156 cmd = u""" 157 DELETE FROM ref.tag_image 158 WHERE 159 pk = %(pk)s 160 AND 161 NOT EXISTS ( 162 SELECT 1 163 FROM dem.identity_tag 164 WHERE fk_tag = %(pk)s 165 LIMIT 1 166 ) 167 RETURNING 1 168 """ 169 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 170 if len(rows) == 0: 171 return False 172 return True
173 174 #============================================================ 175 _SQL_get_identity_tags = u"""SELECT * FROM dem.v_identity_tags WHERE %s""" 176
177 -class cIdentityTag(gmBusinessDBObject.cBusinessDBObject):
178 179 _cmd_fetch_payload = _SQL_get_identity_tags % u"pk_identity_tag = %s" 180 _cmds_store_payload = [ 181 u""" 182 UPDATE dem.identity_tag SET 183 fk_tag = %(pk_tag_image)s, 184 comment = gm.nullify_empty_string(%(comment)s) 185 WHERE 186 pk = %(pk_identity_tag)s 187 AND 188 xmin = %(xmin_identity_tag)s 189 RETURNING 190 pk as pk_identity_tag, 191 xmin as xmin_identity_tag 192 """ 193 ] 194 _updatable_fields = [u'fk_tag', u'comment'] 195 #--------------------------------------------------------
196 - def export_image2file(self, aChunkSize=0, filename=None):
197 198 if self._payload[self._idx['image_size']] == 0: 199 return None 200 201 if filename is None: 202 suffix = None 203 # preserve original filename extension if available 204 if self._payload[self._idx['filename']] is not None: 205 name, suffix = os.path.splitext(self._payload[self._idx['filename']]) 206 suffix = suffix.strip() 207 if suffix == u'': 208 suffix = None 209 # get unique filename 210 filename = gmTools.get_unique_filename ( 211 prefix = 'gm-identity_tag-', 212 suffix = suffix 213 ) 214 215 exported = gmPG2.bytea2file ( 216 data_query = { 217 'cmd': u'SELECT substring(image from %(start)s for %(size)s) FROM ref.tag_image WHERE pk = %(pk)s', 218 'args': {'pk': self._payload[self._idx['pk_tag_image']]} 219 }, 220 filename = filename, 221 chunk_size = aChunkSize, 222 data_size = self._payload[self._idx['image_size']] 223 ) 224 if exported: 225 return filename 226 227 return None
228 #============================================================ 229 #============================================================
230 -def get_countries():
231 cmd = u""" 232 select 233 _(name) as l10n_country, name, code, deprecated 234 from dem.country 235 order by l10n_country""" 236 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}]) 237 return rows
238 #============================================================
239 -def get_country_for_region(region=None):
240 cmd = u""" 241 SELECT code_country, l10n_country FROM dem.v_state WHERE l10n_state = %(region)s 242 union 243 SELECT code_country, l10n_country FROM dem.v_state WHERE state = %(region)s 244 """ 245 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'region': region}}]) 246 return rows
247 #============================================================
248 -def delete_province(province=None, delete_urbs=False):
249 250 args = {'prov': province} 251 252 queries = [] 253 if delete_urbs: 254 queries.append ({ 255 'cmd': u""" 256 delete from dem.urb du 257 where 258 du.id_state = %(prov)s 259 and 260 not exists (select 1 from dem.street ds where ds.id_urb = du.id)""", 261 'args': args 262 }) 263 264 queries.append ({ 265 'cmd': u""" 266 delete from dem.state ds 267 where 268 ds.id = %(prov)s 269 and 270 not exists (select 1 from dem.urb du where du.id_state = ds.id)""", 271 'args': args 272 }) 273 274 gmPG2.run_rw_queries(queries = queries) 275 276 return True
277 #------------------------------------------------------------
278 -def create_province(name=None, code=None, country=None):
279 280 args = {'code': code, 'country': country, 'name': name} 281 282 cmd = u"""SELECT EXISTS (SELECT 1 FROM dem.state WHERE name = %(name)s)""" 283 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False) 284 285 if rows[0][0]: 286 return 287 288 cmd = u""" 289 INSERT INTO dem.state ( 290 code, country, name 291 ) VALUES ( 292 %(code)s, %(country)s, %(name)s 293 )""" 294 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
295 #------------------------------------------------------------
296 -def get_provinces():
297 cmd = u""" 298 select 299 l10n_state, l10n_country, state, code_state, code_country, pk_state, country_deprecated 300 from dem.v_state 301 order by l10n_country, l10n_state""" 302 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}]) 303 return rows
304 #============================================================ 305 # address related classes 306 #------------------------------------------------------------
307 -class cAddress(gmBusinessDBObject.cBusinessDBObject):
308 """A class representing an address as an entity in itself. 309 310 We consider addresses to be self-complete "labels" for locations. 311 It does not depend on any people actually living there. Thus 312 an address can get attached to as many people as we want to 313 signify that that is their place of residence/work/... 314 315 This class acts on the address as an entity. Therefore it can 316 modify the address fields. Think carefully about *modifying* 317 addresses attached to people, though. Most times when you think 318 person.modify_address() what you *really* want is as sequence of 319 person.unlink_address(old) and person.link_address(new). 320 321 Modifying an address may or may not be the proper thing to do as 322 it will transparently modify the address for *all* the people to 323 whom it is attached. In many cases you will want to create a *new* 324 address and link it to a person instead of the old address. 325 """ 326 _cmd_fetch_payload = u"select * from dem.v_address where pk_address = %s" 327 _cmds_store_payload = [ 328 u"""UPDATE dem.address SET 329 aux_street = %(notes_street)s, 330 subunit = %(subunit)s, 331 addendum = %(notes_subunit)s, 332 lat_lon = %(lat_lon_street)s 333 WHERE 334 id = %(pk_address)s 335 AND 336 xmin = %(xmin_address)s 337 RETURNING 338 xmin AS xmin_address""" 339 ] 340 _updatable_fields = [ 341 'notes_street', 342 'subunit', 343 'notes_subunit', 344 'lat_lon_address' 345 ] 346 #--------------------------------------------------------
347 - def format(self, single_line=False, verbose=False, show_type=False):
348 if single_line: 349 return format_address_single_line(address = self, show_type = False, verbose = verbose) 350 return format_address(address = self, show_type = False)
351 #------------------------------------------------------------
352 -def address_exists(country=None, state=None, urb=None, postcode=None, street=None, number=None, subunit=None):
353 354 cmd = u"""SELECT dem.address_exists(%(country)s, %(state)s, %(urb)s, %(postcode)s, %(street)s, %(number)s, %(subunit)s)""" 355 args = { 356 'country': country, 357 'state': state, 358 'urb': urb, 359 'postcode': postcode, 360 'street': street, 361 'number': number, 362 'subunit': subunit 363 } 364 365 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 366 if rows[0][0] is None: 367 _log.debug('address does not exist') 368 for key, val in args.items(): 369 _log.debug('%s: %s', key, val) 370 return None 371 372 return rows[0][0]
373 #------------------------------------------------------------
374 -def create_address(country=None, state=None, urb=None, suburb=None, postcode=None, street=None, number=None, subunit=None):
375 376 if suburb is not None: 377 suburb = gmTools.none_if(suburb.strip(), u'') 378 379 pk_address = address_exists ( 380 country = country, 381 state = state, 382 urb = urb, 383 # suburb = suburb, 384 postcode = postcode, 385 street = street, 386 number = number, 387 subunit = subunit 388 ) 389 if pk_address is not None: 390 return cAddress(aPK_obj = pk_address) 391 392 cmd = u""" 393 SELECT dem.create_address ( 394 %(number)s, 395 %(street)s, 396 %(postcode)s, 397 %(urb)s, 398 %(state)s, 399 %(country)s, 400 %(subunit)s 401 )""" 402 args = { 403 'number': number, 404 'street': street, 405 'postcode': postcode, 406 'urb': urb, 407 'state': state, 408 'country': country, 409 'subunit': subunit 410 } 411 queries = [{'cmd': cmd, 'args': args}] 412 413 rows, idx = gmPG2.run_rw_queries(queries = queries, return_data = True) 414 adr = cAddress(aPK_obj = rows[0][0]) 415 416 if suburb is not None: 417 queries = [{ 418 # CAVE: suburb will be ignored if there already is one 419 'cmd': u"UPDATE dem.street SET suburb = %(suburb)s WHERE id = %(pk_street)s AND suburb IS NULL", 420 'args': {'suburb': suburb, 'pk_street': adr['pk_street']} 421 }] 422 rows, idx = gmPG2.run_rw_queries(queries = queries) 423 424 return adr
425 #------------------------------------------------------------
426 -def delete_address(pk_address=None):
427 cmd = u""" 428 DELETE FROM dem.address 429 WHERE 430 id = %(pk)s 431 AND 432 NOT EXISTS (( 433 SELECT 1 FROM dem.org_unit WHERE fk_address = %(pk)s LIMIT 1 434 ) UNION ( 435 SELECT 1 FROM dem.lnk_identity2comm WHERE fk_address = %(pk)s LIMIT 1 436 ) UNION ( 437 SELECT 1 FROM dem.lnk_person_org_address WHERE id_address = %(pk)s LIMIT 1 438 )) 439 """ 440 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': pk_address}}]) 441 return True
442 #------------------------------------------------------------
443 -def format_address_single_line(address=None, verbose=False, show_type=False):
444 data = { 445 'pk_adr': address['pk_address'], 446 'street': address['street'], 447 'notes_street': gmTools.coalesce(address['notes_street'], u'', u' (%s)'), 448 'number': address['number'], 449 'subunit': gmTools.coalesce(address['subunit'], u'', u'/%s'), 450 'notes_subunit': gmTools.coalesce(address['notes_subunit'], u'', u' (%s)'), 451 'zip': address['postcode'], 452 'urb': address['urb'], 453 'suburb': gmTools.coalesce(address['suburb'], u'', u' (%s)'), 454 'l10n_state': address['l10n_state'], 455 'code_state': address['code_state'], 456 'l10n_country': address['l10n_country'], 457 'code_country': address['code_country'] 458 } 459 if show_type: 460 data['type'] = address['l10n_address_type'] 461 462 if verbose: 463 if show_type: 464 template = _('%(type)s: %(street)s %(number)s%(subunit)s, %(zip)s %(urb)s %(suburb)s, %(code_state)s, %(code_country)s') 465 else: 466 template = _('%(street)s %(number)s%(subunit)s, %(zip)s %(urb)s %(suburb)s, %(code_state)s, %(code_country)s') 467 else: 468 if show_type: 469 template = _('%(type)s: %(street)s %(number)s%(subunit)s, %(zip)s %(urb)s, %(code_state)s, %(code_country)s') 470 else: 471 template = _('%(street)s %(number)s%(subunit)s, %(zip)s %(urb)s, %(code_state)s, %(code_country)s') 472 473 return template % data
474 #------------------------------------------------------------
475 -def format_address(address=None, show_type=False):
476 data = { 477 'pk_adr': address['pk_address'], 478 'street': address['street'], 479 'notes_street': gmTools.coalesce(address['notes_street'], u'', u' (%s)'), 480 'number': address['number'], 481 'subunit': gmTools.coalesce(address['subunit'], u'', u'/%s'), 482 'notes_subunit': gmTools.coalesce(address['notes_subunit'], u'', u' (%s)'), 483 'zip': address['postcode'], 484 'urb': address['urb'], 485 'suburb': gmTools.coalesce(address['suburb'], u'', u' (%s)'), 486 'l10n_state': address['l10n_state'], 487 'code_state': address['code_state'], 488 'l10n_country': address['l10n_country'], 489 'code_country': address['code_country'] 490 } 491 if show_type: 492 data['type'] = address['l10n_address_type'] 493 template = _( 494 'Address (%(type)s) [#%(pk_adr)s]\n' 495 ' Street: %(street)s%(notes_street)s\n' 496 ' Number/Unit: %(number)s%(subunit)s%(notes_subunit)s\n' 497 ' Location: %(zip)s %(urb)s%(suburb)s\n' 498 ' Region: %(l10n_state)s, %(code_state)s\n' 499 ' Country: %(l10n_country)s, %(code_country)s' 500 ) 501 else: 502 template = _( 503 'Address [#%(pk_adr)s]\n' 504 ' Street: %(street)s%(notes_street)s\n' 505 ' Number/Unit: %(number)s%(subunit)s%(notes_subunit)s\n' 506 ' Location: %(zip)s %(urb)s%(suburb)s\n' 507 ' Region: %(l10n_state)s, %(code_state)s\n' 508 ' Country: %(l10n_country)s, %(code_country)s' 509 ) 510 txt = template % data 511 return txt.split('\n')
512 #------------------------------------------------------------
513 -def get_address_types(identity=None):
514 cmd = u'select id as pk, name, _(name) as l10n_name from dem.address_type' 515 rows, idx = gmPG2.run_rw_queries(queries=[{'cmd': cmd}]) 516 return rows
517 #------------------------------------------------------------
518 -def get_addresses(order_by=None):
519 520 if order_by is None: 521 order_by = u'' 522 else: 523 order_by = u'ORDER BY %s' % order_by 524 525 cmd = u"SELECT * FROM dem.v_address %s" % order_by 526 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 527 return [ cAddress(row = {'data': r, 'idx': idx, 'pk_field': u'pk_address'}) for r in rows ]
528 #------------------------------------------------------------
529 -def get_address_from_patient_address_pk(pk_patient_address=None):
530 cmd = u""" 531 SELECT * FROM dem.v_address WHERE 532 pk_address = ( 533 SELECT id_address 534 FROM dem.lnk_person_org_address 535 WHERE id = %(pk_pat_adr)s 536 ) 537 """ 538 args = {'pk_pat_adr': pk_patient_address} 539 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 540 if len(rows) == 0: 541 return None 542 return cAddress(row = {'data': rows[0], 'idx': idx, 'pk_field': u'pk_address'})
543 544 #===================================================================
545 -def get_patient_address(pk_patient_address=None):
546 cmd = u'SELECT * FROM dem.v_pat_addresses WHERE pk_lnk_person_org_address = %(pk)s' 547 args = {'pk': pk_patient_address} 548 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 549 if len(rows) == 0: 550 return None 551 return cPatientAddress(row = {'data': rows[0], 'idx': idx, 'pk_field': u'pk_address'})
552 #-------------------------------------------------------------------
553 -def get_patient_address_by_type(pk_patient=None, adr_type=None):
554 cmd = u'SELECT * FROM dem.v_pat_addresses WHERE pk_identity = %(pat)s AND address_type = %(typ)s' 555 args = {'pat': pk_patient, 'typ': adr_type} 556 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 557 if len(rows) == 0: 558 return None 559 return cPatientAddress(row = {'data': rows[0], 'idx': idx, 'pk_field': u'pk_address'})
560 #-------------------------------------------------------------------
561 -class cPatientAddress(gmBusinessDBObject.cBusinessDBObject):
562 563 _cmd_fetch_payload = u"SELECT * FROM dem.v_pat_addresses WHERE pk_address = %s" 564 _cmds_store_payload = [ 565 u"""UPDATE dem.lnk_person_org_address SET 566 id_type = %(pk_address_type)s 567 WHERE 568 id = %(pk_lnk_person_org_address)s 569 AND 570 xmin = %(xmin_lnk_person_org_address)s 571 RETURNING 572 xmin AS xmin_lnk_person_org_address 573 """ 574 ] 575 _updatable_fields = ['pk_address_type'] 576 #---------------------------------------------------------------
577 - def get_identities(self, same_lastname=False):
578 pass
579 #--------------------------------------------------------
580 - def format(self, single_line=False, verbose=False, show_type=True):
581 if single_line: 582 return format_address_single_line(address = self, verbose = verbose, show_type = show_type) 583 txt = format_address(address = self, show_type = show_type) 584 return txt
585 #--------------------------------------------------------
586 - def _get_address(self):
587 return cAddress(aPK_obj = self._payload[self._idx['pk_address']])
588 589 address = property(_get_address, lambda x:x)
590 591 #=================================================================== 592 # communication channels API 593 #-------------------------------------------------------------------
594 -class cCommChannel(gmBusinessDBObject.cBusinessDBObject):
595 596 _cmd_fetch_payload = u"SELECT * FROM dem.v_person_comms WHERE pk_lnk_identity2comm = %s" 597 _cmds_store_payload = [ 598 u"""UPDATE dem.lnk_identity2comm SET 599 --fk_address = %(pk_address)s, 600 fk_type = dem.create_comm_type(%(comm_type)s), 601 url = %(url)s, 602 is_confidential = %(is_confidential)s, 603 comment = gm.nullify_empty_string(%(comment)s) 604 WHERE 605 pk = %(pk_lnk_identity2comm)s 606 AND 607 xmin = %(xmin_lnk_identity2comm)s 608 RETURNING 609 xmin AS xmin_lnk_identity2comm 610 """ 611 ] 612 _updatable_fields = [ 613 'url', 614 'comm_type', 615 'is_confidential', 616 'comment' 617 ]
618 619 #-------------------------------------------------------------------
620 -class cOrgCommChannel(gmBusinessDBObject.cBusinessDBObject):
621 622 _cmd_fetch_payload = u"SELECT * FROM dem.v_org_unit_comms WHERE pk_lnk_org_unit2comm = %s" 623 _cmds_store_payload = [ 624 u"""UPDATE dem.lnk_org_unit2comm SET 625 fk_type = dem.create_comm_type(%(comm_type)s), 626 url = %(url)s, 627 is_confidential = %(is_confidential)s, 628 comment = gm.nullify_empty_string(%(comment)s) 629 WHERE 630 pk = %(pk_lnk_org_unit2comm)s 631 AND 632 xmin = %(xmin_lnk_org_unit2comm)s 633 RETURNING 634 xmin AS xmin_lnk_org_unit2comm 635 """ 636 ] 637 _updatable_fields = [ 638 'url', 639 'comm_type', 640 'is_confidential', 641 'comment' 642 ]
643 644 #-------------------------------------------------------------------
645 -def create_comm_channel(comm_medium=None, url=None, is_confidential=False, pk_channel_type=None, pk_identity=None, pk_org_unit=None):
646 """Create a communications channel for a patient.""" 647 648 if url is None: 649 return None 650 651 args = { 652 'url': url, 653 'secret': is_confidential, 654 'pk_type': pk_channel_type, 655 'type': comm_medium 656 } 657 658 if pk_identity is not None: 659 args['pk_owner'] = pk_identity 660 tbl = u'dem.lnk_identity2comm' 661 col = u'fk_identity' 662 view = u'dem.v_person_comms' 663 view_pk = u'pk_lnk_identity2comm' 664 channel_class = cCommChannel 665 if pk_org_unit is not None: 666 args['pk_owner'] = pk_org_unit 667 tbl = u'dem.lnk_org_unit2comm' 668 col = u'fk_org_unit' 669 view = u'dem.v_org_unit_comms' 670 view_pk = u'pk_lnk_org_unit2comm' 671 channel_class = cOrgCommChannel 672 673 if pk_channel_type is None: 674 cmd = u"""INSERT INTO %s ( 675 %s, 676 url, 677 fk_type, 678 is_confidential 679 ) VALUES ( 680 %%(pk_owner)s, 681 %%(url)s, 682 dem.create_comm_type(%%(type)s), 683 %%(secret)s 684 )""" % (tbl, col) 685 else: 686 cmd = u"""INSERT INTO %s ( 687 %s, 688 url, 689 fk_type, 690 is_confidential 691 ) VALUES ( 692 %%(pk_owner)s, 693 %%(url)s, 694 %%(pk_type)s, 695 %%(secret)s 696 )""" % (tbl, col) 697 698 queries = [{'cmd': cmd, 'args': args}] 699 cmd = u"SELECT * FROM %s WHERE %s = currval(pg_get_serial_sequence('%s', 'pk'))" % (view, view_pk, tbl) 700 queries.append({'cmd': cmd}) 701 702 rows, idx = gmPG2.run_rw_queries(queries = queries, return_data = True, get_col_idx = True) 703 704 if pk_identity is not None: 705 return cCommChannel(row = {'pk_field': view_pk, 'data': rows[0], 'idx': idx}) 706 707 return channel_class(row = {'pk_field': view_pk, 'data': rows[0], 'idx': idx})
708 #-------------------------------------------------------------------
709 -def delete_comm_channel(pk=None, pk_patient=None, pk_org_unit=None):
710 if pk_patient is not None: 711 query = { 712 'cmd': u"DELETE FROM dem.lnk_identity2comm WHERE pk = %(pk)s AND fk_identity = %(pat)s", 713 'args': {'pk': pk, 'pat': pk_patient} 714 } 715 if pk_org_unit is not None: 716 query = { 717 'cmd': u"DELETE FROM dem.lnk_org_unit2comm WHERE pk = %(pk)s AND fk_org_unit = %(unit)s", 718 'args': {'pk': pk, 'unit': pk_org_unit} 719 } 720 gmPG2.run_rw_queries(queries = [query])
721 #-------------------------------------------------------------------
722 -def get_comm_channel_types():
723 cmd = u"SELECT pk, _(description) AS l10n_description, description FROM dem.enum_comm_types" 724 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False) 725 return rows
726 #-------------------------------------------------------------------
727 -def delete_comm_channel_type(pk_channel_type=None):
728 cmd = u""" 729 DELETE FROM dem.enum_comm_types 730 WHERE 731 pk = %(pk)s 732 AND NOT EXISTS ( 733 SELECT 1 FROM dem.lnk_identity2comm WHERE fk_type = %(pk)s 734 ) 735 AND NOT EXISTS ( 736 SELECT 1 FROM dem.lnk_org_unit2comm WHERE fk_type = %(pk)s 737 ) 738 """ 739 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': pk_channel_type}}]) 740 return True
741 #=================================================================== 742 #------------------------------------------------------------------- 743 744 #==============================================================================
745 -def get_time_tuple (mx):
746 """ 747 wrap mx.DateTime brokenness 748 Returns 9-tuple for use with pyhon time functions 749 """ 750 return [ int(x) for x in str(mx).split(' ')[0].split('-') ] + [0,0,0, 0,0,0]
751 #----------------------------------------------------------------
752 -def getAddressTypes():
753 """Gets a dict matching address types to their ID""" 754 row_list = gmPG.run_ro_query('personalia', "select name, id from dem.address_type") 755 if row_list is None: 756 return {} 757 if len(row_list) == 0: 758 return {} 759 return dict (row_list)
760 #----------------------------------------------------------------
761 -def getMaritalStatusTypes():
762 """Gets a dictionary matching marital status types to their internal ID""" 763 row_list = gmPG.run_ro_query('personalia', "select name, pk from dem.marital_status") 764 if row_list is None: 765 return {} 766 if len(row_list) == 0: 767 return {} 768 return dict(row_list)
769 #------------------------------------------------------------------
770 -def getRelationshipTypes():
771 """Gets a dictionary of relationship types to internal id""" 772 row_list = gmPG.run_ro_query('personalia', "select description, id from dem.relation_types") 773 if row_list is None: 774 return None 775 if len (row_list) == 0: 776 return None 777 return dict(row_list)
778 779 #----------------------------------------------------------------
780 -def getUrb (id_urb):
781 cmd = """ 782 select 783 dem.state.name, 784 dem.urb.postcode 785 from 786 dem.urb, 787 dem.state 788 where 789 dem.urb.id = %s and 790 dem.urb.id_state = dem.state.id""" 791 row_list = gmPG.run_ro_query('personalia', cmd, None, id_urb) 792 if not row_list: 793 return None 794 else: 795 return (row_list[0][0], row_list[0][1])
796
797 -def getStreet (id_street):
798 cmd = """ 799 select 800 dem.state.name, 801 coalesce (dem.street.postcode, dem.urb.postcode), 802 dem.urb.name 803 from 804 dem.urb, 805 dem.state, 806 dem.street 807 where 808 dem.street.id = %s and 809 dem.street.id_urb = dem.urb.id and 810 dem.urb.id_state = dem.state.id 811 """ 812 row_list = gmPG.run_ro_query('personalia', cmd, None, id_street) 813 if not row_list: 814 return None 815 else: 816 return (row_list[0][0], row_list[0][1], row_list[0][2])
817
818 -def getCountry (country_code):
819 row_list = gmPG.run_ro_query('personalia', "select name from dem.country where code = %s", None, country_code) 820 if not row_list: 821 return None 822 else: 823 return row_list[0][0]
824 #-------------------------------------------------------------------------------
825 -def get_town_data (town):
826 row_list = gmPG.run_ro_query ('personalia', """ 827 select 828 dem.urb.postcode, 829 dem.state.code, 830 dem.state.name, 831 dem.country.code, 832 dem.country.name 833 from 834 dem.urb, 835 dem.state, 836 dem.country 837 where 838 dem.urb.name = %s and 839 dem.urb.id_state = dem.state.id and 840 dem.state.country = dem.country.code""", None, town) 841 if not row_list: 842 return (None, None, None, None, None) 843 else: 844 return tuple (row_list[0])
845 #============================================================ 846 # callbacks 847 #------------------------------------------------------------
848 -def _post_patient_selection(**kwargs):
849 print "received post_patient_selection notification" 850 print kwargs['kwds']
851 #============================================================ 852 853 #============================================================ 854 # main 855 #------------------------------------------------------------ 856 if __name__ == "__main__": 857 858 if len(sys.argv) < 2: 859 sys.exit() 860 861 if sys.argv[1] != 'test': 862 sys.exit() 863 864 import random 865 #--------------------------------------------------------
866 - def test_address_exists():
867 868 addresses = [ 869 { 870 'country': 'Germany', 871 'state': 'Sachsen', 872 'urb': 'Leipzig', 873 'postcode': '04318', 874 'street': u'Cunnersdorfer Strasse', 875 'number': '11' 876 }, 877 { 878 'country': 'DE', 879 'state': 'SN', 880 'urb': 'Leipzig', 881 'postcode': '04317', 882 'street': u'Riebeckstraße', 883 'number': '65', 884 'subunit': 'Parterre' 885 }, 886 { 887 'country': 'DE', 888 'state': 'SN', 889 'urb': 'Leipzig', 890 'postcode': '04317', 891 'street': u'Riebeckstraße', 892 'number': '65', 893 'subunit': '1. Stock' 894 }, 895 { 896 'country': 'DE', 897 'state': 'SN', 898 'urb': 'Leipzig', 899 'postcode': '04317', 900 'street': u'Riebeckstraße', 901 'number': '65', 902 'subunit': '1. Stock' 903 }, 904 { 905 # 'country': 'DE', 906 # 'state': 'SN', 907 'urb': 'Leipzig', 908 'postcode': '04317', 909 'street': u'Riebeckstraße', 910 'number': '65', 911 'subunit': '1. Stock' 912 }, 913 ] 914 915 for adr in addresses: 916 print adr 917 exists = address_exists(**adr) 918 if exists is None: 919 print "address does not exist" 920 else: 921 print "address exists, primary key:", exists
922 923 #--------------------------------------------------------
924 - def test_create_address():
925 address = create_address ( 926 country ='DE', 927 state ='SN', 928 urb ='Leipzig', 929 suburb ='Sellerhausen', 930 postcode ='04318', 931 street = u'Cunnersdorfer Strasse', 932 number = '11' 933 # ,notes_subunit = '4.Stock rechts' 934 ) 935 print "created existing address" 936 print address.format() 937 938 su = str(random.random()) 939 940 address = create_address ( 941 country ='DE', 942 state = 'SN', 943 urb ='Leipzig', 944 suburb ='Sellerhausen', 945 postcode ='04318', 946 street = u'Cunnersdorfer Strasse', 947 number = '11', 948 # notes_subunit = '4.Stock rechts', 949 subunit = su 950 ) 951 print "created new address with subunit", su 952 print address 953 print address.format() 954 print "deleted address:", delete_address(pk_address = address['pk_address'])
955 #--------------------------------------------------------
956 - def test_get_countries():
957 for c in get_countries(): 958 print c
959 #--------------------------------------------------------
960 - def test_get_country_for_region():
961 region = raw_input("Please enter a region: ") 962 print "country for region [%s] is: %s" % (region, get_country_for_region(region = region))
963 #--------------------------------------------------------
964 - def test_delete_tag():
965 if delete_tag_image(tag_image = 9999): 966 print "deleted tag 9999" 967 else: 968 print "did not delete tag 9999" 969 if delete_tag_image(tag_image = 1): 970 print "deleted tag 1" 971 else: 972 print "did not delete tag 1"
973 #--------------------------------------------------------
974 - def test_tag_images():
975 tag = cTagImage(aPK_obj = 1) 976 print tag
977 #print get_tag_images() 978 #--------------------------------------------------------
979 - def test_get_billing_address():
980 print get_patient_address_by_type(pk_patient = 12, adr_type = u'billing')
981 #-------------------------------------------------------- 982 #gmPG2.get_connection() 983 984 #test_address_exists() 985 #test_create_address() 986 #test_get_countries() 987 #test_get_country_for_region() 988 #test_delete_tag() 989 test_tag_images() 990 #test_get_billing_address() 991 992 sys.exit() 993 #============================================================ 994