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