1
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
14 import sys
15 import os
16 import os.path
17 import logging
18
19
20
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
39
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
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
74
75 if self._payload[self._idx['size']] == 0:
76 return None
77
78 if filename is None:
79 suffix = None
80
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
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
108
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
120 self.refetch_payload()
121 return True
122
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
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
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
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
199
200 if self._payload[self._idx['image_size']] == 0:
201 return None
202
203 if filename is None:
204 suffix = None
205
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
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
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
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
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
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
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
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
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
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
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
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
468
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
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
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
504
509
510
511
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 WHERE
522 pk = %(pk_lnk_identity2comm)s
523 AND
524 xmin = %(xmin_lnk_identity2comm)s
525 RETURNING
526 xmin AS xmin_lnk_identity2comm
527 """
528 ]
529 _updatable_fields = [
530 'pk_address',
531 'url',
532 'comm_type',
533 'is_confidential'
534 ]
535
537
538 _cmd_fetch_payload = u"SELECT * FROM dem.v_org_unit_comms WHERE pk_lnk_org_unit2comm = %s"
539 _cmds_store_payload = [
540 u"""UPDATE dem.lnk_org_unit2comm SET
541 fk_type = dem.create_comm_type(%(comm_type)s),
542 url = %(url)s,
543 is_confidential = %(is_confidential)s
544 WHERE
545 pk = %(pk_lnk_org_unit2comm)s
546 AND
547 xmin = %(xmin_lnk_org_unit2comm)s
548 RETURNING
549 xmin AS xmin_lnk_org_unit2comm
550 """
551 ]
552 _updatable_fields = [
553 'url',
554 'comm_type',
555 'is_confidential'
556 ]
557
558 -def create_comm_channel(comm_medium=None, url=None, is_confidential=False, pk_channel_type=None, pk_identity=None, pk_org_unit=None):
559 """Create a communications channel for a patient."""
560
561 if url is None:
562 return None
563
564 args = {
565 'url': url,
566 'secret': is_confidential,
567 'pk_type': pk_channel_type,
568 'type': comm_medium
569 }
570
571 if pk_identity is not None:
572 args['pk_owner'] = pk_identity
573 tbl = u'dem.lnk_identity2comm'
574 col = u'fk_identity'
575 view = u'dem.v_person_comms'
576 view_pk = u'pk_lnk_identity2comm'
577 channel_class = cCommChannel
578 if pk_org_unit is not None:
579 args['pk_owner'] = pk_org_unit
580 tbl = u'dem.lnk_org_unit2comm'
581 col = u'fk_org_unit'
582 view = u'dem.v_org_unit_comms'
583 view_pk = u'pk_lnk_org_unit2comm'
584 channel_class = cOrgCommChannel
585
586 if pk_channel_type is None:
587 cmd = u"""INSERT INTO %s (
588 %s,
589 url,
590 fk_type,
591 is_confidential
592 ) VALUES (
593 %%(pk_owner)s,
594 %%(url)s,
595 dem.create_comm_type(%%(type)s),
596 %%(secret)s
597 )""" % (tbl, col)
598 else:
599 cmd = u"""INSERT INTO %s (
600 %s,
601 url,
602 fk_type,
603 is_confidential
604 ) VALUES (
605 %%(pk_owner)s,
606 %%(url)s,
607 %%(pk_type)s,
608 %%(secret)s
609 )""" % (tbl, col)
610
611 queries = [{'cmd': cmd, 'args': args}]
612 cmd = u"SELECT * FROM %s WHERE %s = currval(pg_get_serial_sequence('%s', 'pk'))" % (view, view_pk, tbl)
613 queries.append({'cmd': cmd})
614
615 rows, idx = gmPG2.run_rw_queries(queries = queries, return_data = True, get_col_idx = True)
616
617 if pk_identity is not None:
618 return cCommChannel(row = {'pk_field': view_pk, 'data': rows[0], 'idx': idx})
619
620 return channel_class(row = {'pk_field': view_pk, 'data': rows[0], 'idx': idx})
621
623 if pk_patient is not None:
624 query = {
625 'cmd': u"DELETE FROM dem.lnk_identity2comm WHERE pk = %(pk)s AND fk_identity = %(pat)s",
626 'args': {'pk': pk, 'pat': pk_patient}
627 }
628 if pk_org_unit is not None:
629 query = {
630 'cmd': u"DELETE FROM dem.lnk_org_unit2comm WHERE pk = %(pk)s AND fk_org_unit = %(unit)s",
631 'args': {'pk': pk, 'unit': pk_org_unit}
632 }
633 gmPG2.run_rw_queries(queries = [query])
634
636 cmd = u"SELECT pk, _(description) AS l10n_description, description FROM dem.enum_comm_types"
637 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
638 return rows
639
641 cmd = u"""
642 DELETE FROM dem.enum_comm_types
643 WHERE
644 pk = %(pk)s
645 AND NOT EXISTS (
646 SELECT 1 FROM dem.lnk_identity2comm WHERE fk_type = %(pk)s
647 )
648 AND NOT EXISTS (
649 SELECT 1 FROM dem.lnk_org_unit2comm WHERE fk_type = %(pk)s
650 )
651 """
652 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': pk_channel_type}}])
653 return True
654
655
656
657 -class cOrg (gmBusinessDBObject.cBusinessDBObject):
658 """
659 Organisations
660
661 This is also the common ancestor of cIdentity, self._table is used to
662 hide the difference.
663 The aim is to be able to sanely write code which doesn't care whether
664 its talking to an organisation or an individual"""
665 _table = "org"
666
667 _cmd_fetch_payload = "select *, xmin from dem.org where id=%s"
668 _cmds_lock_rows_for_update = ["select 1 from dem.org where id=%(id)s and xmin=%(xmin)s"]
669 _cmds_store_payload = [
670 """update dem.org set
671 description=%(description)s,
672 id_category=(select id from dem.org_category where description=%(occupation)s)
673 where id=%(id)s""",
674 "select xmin from dem.org where id=%(id)s"
675 ]
676 _updatable_fields = ["description", "occupation"]
677 _service = 'personalia'
678
681
683 if not self.__cache.has_key ('addresses'):
684 self['addresses']
685 if not self.__cache.has_key ('comms'):
686 self['comms']
687 return self.__cache
688
690 """
691 Returns a list of (address dict, cIdentity) tuples
692 """
693 cmd = """select
694 vba.id,
695 vba.number,
696 vba.addendum,
697 vba.street,
698 vba.urb,
699 vba.postcode,
700 at.name,
701 lpoa.id_type,
702 vbp.pk_identity,
703 title,
704 firstnames,
705 lastnames,
706 dob,
707 cob,
708 gender,
709 pupic,
710 pk_marital_status,
711 marital_status,
712 karyotype,
713 xmin_identity,
714 preferred
715 from
716 dem.v_basic_address vba,
717 dem.lnk_person_org_address lpoa,
718 dem.address_type at,
719 dem.v_basic_person vbp
720 where
721 lpoa.id_address = vba.id
722 and lpoa.id_type = at.id
723 and lpoa.id_identity = vbp.pk_identity
724 and lpoa.id_org = %%s
725 """
726
727 rows, idx = gmPG.run_ro_query('personalia', cmd, 1, self.getId ())
728 if rows is None:
729 return []
730 elif len(rows) == 0:
731 return []
732 else:
733 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]
734
736 """
737 Binds a person to this organisation at this address.
738 person is a cIdentity object
739 address is a dict of {'number', 'street', 'addendum', 'city', 'postcode', 'type'}
740 type is one of the IDs returned by getAddressTypes
741 """
742 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)"
743 address['pk_identity'] = person['pk_identity']
744 address['org_id'] = self.getId()
745 if not id_addr:
746 return (False, None)
747 return gmPG.run_commit2 ('personalia', [(cmd, [address])])
748
752
754 """
755 Hide the difference between org.id and v_basic_person.pk_identity
756 """
757 return self['id']
758
760 """
761 wrap mx.DateTime brokenness
762 Returns 9-tuple for use with pyhon time functions
763 """
764 return [ int(x) for x in str(mx).split(' ')[0].split('-') ] + [0,0,0, 0,0,0]
765
767 """Gets a dict matching address types to their ID"""
768 row_list = gmPG.run_ro_query('personalia', "select name, id from dem.address_type")
769 if row_list is None:
770 return {}
771 if len(row_list) == 0:
772 return {}
773 return dict (row_list)
774
776 """Gets a dictionary matching marital status types to their internal ID"""
777 row_list = gmPG.run_ro_query('personalia', "select name, pk from dem.marital_status")
778 if row_list is None:
779 return {}
780 if len(row_list) == 0:
781 return {}
782 return dict(row_list)
783
785 """Gets a dictionary of relationship types to internal id"""
786 row_list = gmPG.run_ro_query('personalia', "select description, id from dem.relation_types")
787 if row_list is None:
788 return None
789 if len (row_list) == 0:
790 return None
791 return dict(row_list)
792
793
795 cmd = """
796 select
797 dem.state.name,
798 dem.urb.postcode
799 from
800 dem.urb,
801 dem.state
802 where
803 dem.urb.id = %s and
804 dem.urb.id_state = dem.state.id"""
805 row_list = gmPG.run_ro_query('personalia', cmd, None, id_urb)
806 if not row_list:
807 return None
808 else:
809 return (row_list[0][0], row_list[0][1])
810
812 cmd = """
813 select
814 dem.state.name,
815 coalesce (dem.street.postcode, dem.urb.postcode),
816 dem.urb.name
817 from
818 dem.urb,
819 dem.state,
820 dem.street
821 where
822 dem.street.id = %s and
823 dem.street.id_urb = dem.urb.id and
824 dem.urb.id_state = dem.state.id
825 """
826 row_list = gmPG.run_ro_query('personalia', cmd, None, id_street)
827 if not row_list:
828 return None
829 else:
830 return (row_list[0][0], row_list[0][1], row_list[0][2])
831
833 row_list = gmPG.run_ro_query('personalia', "select name from dem.country where code = %s", None, country_code)
834 if not row_list:
835 return None
836 else:
837 return row_list[0][0]
838
840 row_list = gmPG.run_ro_query ('personalia', """
841 select
842 dem.urb.postcode,
843 dem.state.code,
844 dem.state.name,
845 dem.country.code,
846 dem.country.name
847 from
848 dem.urb,
849 dem.state,
850 dem.country
851 where
852 dem.urb.name = %s and
853 dem.urb.id_state = dem.state.id and
854 dem.state.country = dem.country.code""", None, town)
855 if not row_list:
856 return (None, None, None, None, None)
857 else:
858 return tuple (row_list[0])
859
860
861
863 print "received post_patient_selection notification"
864 print kwargs['kwds']
865
866
867
868
869
870 if __name__ == "__main__":
871
872 if len(sys.argv) < 2:
873 sys.exit()
874
875 if sys.argv[1] != 'test':
876 sys.exit()
877
878 import random
879
881
882 addresses = [
883 {
884 'country': 'Germany',
885 'state': 'Sachsen',
886 'urb': 'Leipzig',
887 'postcode': '04318',
888 'street': u'Cunnersdorfer Strasse',
889 'number': '11'
890 },
891 {
892 'country': 'DE',
893 'state': 'SN',
894 'urb': 'Leipzig',
895 'postcode': '04317',
896 'street': u'Riebeckstraße',
897 'number': '65',
898 'subunit': 'Parterre'
899 },
900 {
901 'country': 'DE',
902 'state': 'SN',
903 'urb': 'Leipzig',
904 'postcode': '04317',
905 'street': u'Riebeckstraße',
906 'number': '65',
907 'subunit': '1. Stock'
908 },
909 {
910 'country': 'DE',
911 'state': 'SN',
912 'urb': 'Leipzig',
913 'postcode': '04317',
914 'street': u'Riebeckstraße',
915 'number': '65',
916 'subunit': '1. Stock'
917 },
918 {
919
920
921 'urb': 'Leipzig',
922 'postcode': '04317',
923 'street': u'Riebeckstraße',
924 'number': '65',
925 'subunit': '1. Stock'
926 },
927 ]
928
929 for adr in addresses:
930 print adr
931 exists = address_exists(**adr)
932 if exists is None:
933 print "address does not exist"
934 else:
935 print "address exists, primary key:", exists
936
937
939 address = create_address (
940 country ='DE',
941 state ='SN',
942 urb ='Leipzig',
943 suburb ='Sellerhausen',
944 postcode ='04318',
945 street = u'Cunnersdorfer Strasse',
946 number = '11'
947
948 )
949 print "created existing address"
950 print address.format()
951
952 su = str(random.random())
953
954 address = create_address (
955 country ='DE',
956 state = 'SN',
957 urb ='Leipzig',
958 suburb ='Sellerhausen',
959 postcode ='04318',
960 street = u'Cunnersdorfer Strasse',
961 number = '11',
962
963 subunit = su
964 )
965 print "created new address with subunit", su
966 print address
967 print address.format()
968 print "deleted address:", delete_address(pk_address = address['pk_address'])
969
973
975 region = raw_input("Please enter a region: ")
976 print "country for region [%s] is: %s" % (region, get_country_for_region(region = region))
977
979 if delete_tag_image(tag_image = 9999):
980 print "deleted tag 9999"
981 else:
982 print "did not delete tag 9999"
983 if delete_tag_image(tag_image = 1):
984 print "deleted tag 1"
985 else:
986 print "did not delete tag 1"
987
992
993
994
995
996
997 test_create_address()
998
999
1000
1001
1002
1003 sys.exit()
1004
1005