1 """
2 data objects for organization. Hoping to use the helper class to act as Facade
3 for aggregated data objects ? with validation rules.
4 re-used working code form gmClinItem and followed Script Module layout of gmEMRStructItems.
5
6 license: GPL"""
7
8 __version__ = "$Revision: 1.40 $"
9
10 from Gnumed.pycommon import gmExceptions, gmBorg, gmPG
11 from Gnumed.business import gmDemographicRecord, gmPerson
12
13 import inspect
14
15 if __name__ == '__main__':
16 _ = lambda x:x
17
18 _log = logging.getLogger('gm.demos')
19 _log.info(__version__)
20
21
22 attrNames = [ 'name', 'office', 'subtype', 'memo','category', 'phone', 'fax', 'email', 'mobile' ]
23 addressNames = [ 'number', 'street', 'urb', 'postcode', 'state', 'country']
24
25 commtypes = {
26
27
28
29
30
31
32
33 }
34
35 commnames = dict( [ (v,k) for (k,v) in commtypes.items()] )
36
37 workAddressType = 2
38
39
40
42
43 - def __init__(self, categoryType = None, pkCol = 'id', nameCol = 'description'):
44 gmBorg.cBorg.__init__(self)
45 if not self.__dict__.has_key("categories"):
46 self.categories = {}
47
48 if categoryType == None:
49 return
50
51 if not self.categories.has_key(categoryType):
52 self.categories[categoryType] = {'toId': {}, 'toDescription': {},'id': pkCol, 'name': nameCol }
53 self.reload(categoryType)
54
55
56
57 - def reload(self, categoryType):
58 self.__init__(categoryType)
59 pk = self.categories[categoryType]['id']
60 name = self.categories[categoryType]['name']
61 result = gmPG.run_ro_query("personalia","select %s, %s from %s" % (pk, name, categoryType))
62 if result is None:
63 _log.error("failed to load %s" % categoryType)
64
65 for (id, description) in result:
66 self.categories[categoryType]['toId'][description] = id
67 self.categories[categoryType]['toDescription'][id] = description
68 return self.categories[categoryType]
69
70
71
72 - def getId(self, categoryType, category):
73 return self.categories.get(categoryType, self.reload(categoryType)).get('toId',{}).get(category, None)
74
76 return self.categories.get(categoryType, self.reload(categoryType)).get('toDescription',{}).get(id, "")
77
79 return self.categories.get(categoryType, self.reload(categoryType)).get('toId',{}).keys()
80
81
82
83
84
85 DEPARTMENT = 1
86
87
88
89
100
101 - def set(self, name, office, subtype, memo, category, phone, fax, email,mobile = ""):
103
104 - def setAddress(self, number, street, urb, postcode, state, country):
106
109
112
115
116
118 return []
119
120 - def load(self, pk):
122
125
126
129
130
131
133
134
135
138
141
144
147
152
155
158
161
164
167
170
173
174
175
176
178
184
185
188
199
200 - def getClipboardText(self, org):
201
202 d = { 'name': org['name'],
203 'address_str': self.getAddressStr(org),
204 'phone' : org['phone'],
205 'fax' : org['fax'],
206 'email' : org['email'],
207 'id': org.getId()
208 }
209 if self.isPerson(org):
210 d['orgtype'] = 'person'
211
212 elif org.getParent() <> None:
213 d['orgtype'] = 'org'
214 d['name'] = ' '.join( [ org['name'], org['subtype'], ',',org.getParent()['name'] ] )
215 else:
216 d['orgtype'] = 'org'
217
218
219 o = org
220 while o.getParent() <> None and self.getAddressStr(o).strip() == '':
221 d['address_str'] = self.getAddressStr(o.getParent() )
222 o = o.getParent()
223
224 str = self._clipboardFormat % d
225
226 return str
227
230
233
236
242
244 result = gmPG.run_ro_query("personalia", """select id from dem.org""",[])
245 if result == None:
246 _log.exception("Unable to select id from org")
247 return False
248
249 ids = [ x for [x] in result]
250 return self.findOrgsForIds(ids)
251
252
254 """ finds org objects by id. returns a list of cOrgHelper objects
255 """
256
257
258
259 return self._findOrgsForIdsCacheCheck(ids)
260
261
262
264 orglist = []
265 fetch_ids = []
266 for id in ids:
267 if self.cacheContains(id):
268 org = self.getFromCache(id)
269 orglist.append(org)
270 continue
271 fetch_ids.append(id)
272
273 dbOrgList = self._findOrgsForIdsFromDB( fetch_ids)
274
275 for org in dbOrgList:
276 self.updateCache(org)
277
278 return orglist + dbOrgList
279
281 if fetch_ids == None or fetch_ids == []:
282 return []
283
284 om = get_org_data_for_org_ids(fetch_ids)
285 cm = get_comm_channels_data_for_org_ids(fetch_ids )
286 am = get_address_data_for_org_ids( fetch_ids)
287 m = {}
288 orglist = []
289 for id in fetch_ids:
290 org = self.create()
291 if not org._load_org_from_tuple(om.get(id, None), id):
292 continue
293 org._load_comm_channels_from_tuples( cm.get(id, None) )
294 org._load_address_from_tuple( am.get(id, None) )
295 orglist.append(org)
296 return orglist
297
299 """the org name is a unique key, so should only return one or none org"""
300 if exact: query= "select id from dem.org where description = '%s'"%name
301 else: query = "select id from dem.org where description like '%s%%'"%name
302
303 result = gmPG.run_ro_query("personalia", query )
304 if result is None:
305 _log.error("Unable to find org by name %s" % name)
306 return [None]
307
308 return self.findOrgsForIds([ x[0] for x in result])
309
310
313
314
317
318
320 a = org.getAddress()
321 return " ".join( [a.get('number','').strip(), a.get('street','').strip(), a.get('urb','').strip(), a.get('postcode','')])
322
323
324
326
329
332
334 """extends cOrgHelperImpl1's findOrgsforIds and orders them
335 parent/ child order"""
336
337 l = cOrgHelperImpl1.findOrgsForIds(self, ids)
338 childMap = {}
339 parents = filter( lambda(o): o.getParent() is None, l)
340 childMap = dict( [ (p.getId() , []) for p in parents ] )
341 for o in l:
342 if o in parents:
343 continue
344 childMap[o.getParent().getId()].append(o)
345
346 l2 = []
347 for p in parents:
348 l2.append(p)
349 for c in childMap[p.getId()]:
350 l2.append(c)
351
352 return l2
353
354
356 """marker class, for person type check"""
357 pass
358
360 """extends org/suborg handling of cOrgHelperImpl2 to handle org persons"""
361
364
367
370
372 return _cPersonMarker in inspect.getmro(org.__class__)
373
376
378
379 _cache = {}
380
381
382
383
385 self._map = dict ( [ (n,'') for n in attrNames] )
386
387 self._changed= {}
388 self.pk = None
389 self._addressModified(False)
390 self._address = {}
391
392 self._personMap = {}
393 self._helper = helper
394 pass
395
398
401
404
407
409 d = {}
410 d.update(self._address)
411 return d
412
413 - def setAddress(self, number, street, urb, postcode, state, country):
414 self._setAddressImpl( number, street, urb, postcode, state, country)
415
417 names = addressNames
418 if kargs == {} and kwrd <> []:
419 kargs = dict( [ (a, v) for a,v in zip( names, kwrd) ] )
420
421
422 for k in names:
423 a = self._address
424 if a.get(k, None) <> kargs.get(k, None):
425 self._addressModified(True)
426 a[k] = kargs[k]
427
428
430 if val <> None:
431 self._amodified = val
432 return self._amodified
433
434 - def set(self, name, office, subtype, memo, category, phone, fax, email,mobile):
435 self._set_impl(name, office, subtype, memo, category, phone, fax, email,mobile)
436
437
439 """
440
441 """
442 n = attrNames
443 if kargs == {} and kwrd <> []:
444 kargs = dict( [ (a, v) for a,v in zip( n, kwrd) ] )
445
446 changed = {}
447 for k in n:
448 v = self._map.get(k, None)
449
450 if v != kargs[k]:
451 changed[k] = kargs[k]
452
453 self._changed = changed
454
456 if k in attrNames and self._map.get(k, None) <> v:
457 self._changed[k] = v
458
460 v = self._changed.get(k, None)
461 if v == None:
462 v = self._map.get(k, None)
463
464 return v
465
466
468 if self.getId() is None:
469 _log.error("Unable to save comm channel %s : %s due to no org id" % (k,v) )
470 return False
471
472 comm_changes = {}
473 for k,id_type in commtypes. items():
474 if self._changed.has_key(k):
475 comm_changes[id_type] = self._changed[k]
476
477 urls = comm_changes.values()
478 if urls == []:
479 return True
480
481 places = ['%s'] *len(urls)
482
483 format = ', '.join(places)
484
485 cmd = [
486 ("""select id, url, id_type from dem.comm_channel where url in( %s )""" % format, urls) ]
487 result = gmPG.run_commit('personalia', cmd)
488 if result is None:
489 _log.error("find existing org comms failed" )
490 return False
491
492
493 existing_urls = dict( [ (url,(id, id_type) ) for (id, url, id_type) in result] )
494 for id_type , url in comm_changes.items():
495 if url in existing_urls.keys() and existing_urls[url][1] <> id_type:
496 _log.warning("Existing comm url mismatches type for org url %s, inserting same url different type!" % url)
497 del existing_urls[url]
498 cmds = []
499
500 delete_link_cmd = """delete from dem.lnk_org2comm_channel
501 where id_comm in (
502 select l2.id_comm from
503 dem.lnk_org2comm_channel l2 , dem.comm_channel c
504 where c.id = l2.id_comm
505 and c.id_type = %d
506 and l2.id_org = %d
507 ) """
508
509 for url in existing_urls.keys():
510 (id_comm, id_type) = existing_urls[url]
511 cmds = [ (delete_link_cmd % (id_type, self.getId()) ,[] ),
512 ("""insert into dem.lnk_org2comm_channel( id_comm, id_org)
513 values ( %d, %d ) """ % ( id_comm, self.getId() ) , [] )
514 ]
515
516 for id_type, url in comm_changes.items():
517 if url in existing_urls.keys():
518 continue
519
520 if url.strip() == "":
521 cmds.append(
522 (delete_link_cmd %(id_type, self.getId()) , [] )
523 )
524 else:
525
526 cmds.append(
527 ("""insert into dem.comm_channel( url, id_type)
528 values( '%s', %d)""" % (url, id_type),[] )
529 )
530 cmds.append(
531 ("""insert into dem.lnk_org2comm_channel(id_comm, id_org)
532 values( currval('comm_channel_id_seq'), %d)""" %
533 self.getId() ,[] ) )
534
535
536 result = gmPG.run_commit('personalia',cmds)
537
539 a = self._address
540
541 if not self._addressModified():
542 return True
543
544
545 if a['urb'].strip() == '':
546 return True
547
548 return self.linkNewAddress(a['number'],a['street'], a['urb'], a['postcode'], a.get('state', None), a.get('country', None) )
549
550
551
552 - def linkNewAddress (self, number, street, urb, postcode, state = None, country = None):
553 """Adds a new address into this org list of addresses. Basically cut and
554 paste and delete unnecessary fields from gmDemographics function.
555 """
556 urb = urb.upper()
557 if state == "": state = None
558 if country == "": country = None
559
560
561
562 if state is None:
563 print "urb, postcode", urb, postcode
564 state, country = gmDemographicRecord.guess_state_country(urb, postcode)
565 print "state, country", state, country
566
567 cmd = """
568 select addr_id from dem.v_basic_address
569 where
570 number = %s and
571 street = %s and
572 city = %s and
573 postcode = %s and
574 state = %s and
575 country = %s
576 """
577 data = gmPG.run_ro_query ('personalia', cmd, None, number, street, urb, postcode, state, country)
578 if data is None:
579 s = " ".join( ( number, street, urb, postcode, state, country ) )
580 _log.error('cannot check for address existence (%s)' % s)
581 return None
582
583
584 cmd = """
585 delete from dem.lnk_person_org_address
586 where
587 id_org = %s
588 """
589 gmPG.run_commit ('personalia', [(cmd, [self.getId()])])
590
591
592 if len(data) > 0:
593 addr_id = data[0][0]
594 cmd = """
595 insert into dem.lnk_person_org_address (id_org, id_address)
596 values (%d, %d)
597 """ % (self.getId(), addr_id)
598 return gmPG.run_commit ("personalia", [ ( cmd,[]) ])
599
600
601 cmd1 = """
602 insert into dem.v_basic_address (number, street, city, postcode, state, country)
603 values (%s, %s, %s, %s, %s, %s)
604 """
605 cmd2 = """
606 insert into dem.lnk_person_org_address (id_org, id_address)
607 values (%d, currval('address_id_seq'))
608 """ % self.getId()
609 return gmPG.run_commit ("personalia", [
610 (cmd1, (number, street, urb, postcode, state, country)),
611 (cmd2, [] )
612 ]
613 )
614
615
616
618 m = {}
619 m.update(self._map)
620 m.update(self._changed)
621 return m
622
623
624 - def load(self, pk):
625 return ( self._load_org(pk) and
626 self._load_comm_channels()
627 and self._load_address() )
628
629
630
631
633 m_org = get_org_data_for_org_ids( [pk] )
634 if m_org == None or not m_org.has_key(pk):
635
636 print "org id = ", pk, " not found"
637
638 return False
639 self._load_org_from_tuple(m_org[pk], pk)
640
641
643 if tuple == None or tuple == []:
644 self.setId(None)
645 return False
646
647 (description, id_category) = tuple
648 m=self._map
649 cf = cCatFinder()
650 m['category']=cf.getCategory("org_category",id_category)
651
652 m['name']=description
653 self.setId(pk)
654
655 return True
656
657
659 """uses get_comm_channels_data_for_org_ids with only a singleton id list,
660 with the current id to be fetched, then convert to self._map so
661 can be read from self.get() #returning a map of comm channel types vs urls"""
662 m = get_comm_channels_data_for_org_ids([ self.getId() ] )
663 if m == None:
664 return False
665
666 if m.has_key(self.getId()):
667 return self._load_comm_channels_from_tuples(m[self.getId()])
668
669
670
672 if rows == None :
673 return False
674 n = commnames
675 for ( id_type, url) in rows:
676 if commnames.has_key(int(id_type)):
677 self._map[commnames[id_type]] = url
678
679 return True
680
691
692
694
695 if r == None or len(r) < 6:
696 return False
697
698 self._address = { 'number':r[0], 'street':r[1], 'urb':r[2], 'postcode':r[3], 'state':r[4], 'country': r[5] }
699
700 self._addressModified(False)
701
702 return True
703
704
706 cmds = [
707 ("delete from dem.lnk_person_org_address where id_org = %d"%self.getId() , [] ),
708 ("delete from dem.lnk_org2comm_channel where id_org = %d"%self.getId(),[] ),
709 ("delete from dem.org where id = %d"%self.getId() , [] )
710 ]
711
712 if (gmPG.run_commit('personalia',cmds) == None):
713 _log.error("failed to remove org")
714 return False
715
716 self.setId(None)
717
718 return True
719
720
721
722
724
725
726
727 v = self['name']
728 if v <> None:
729 cmd = "select id from dem.org where description = '%s'" % v
730 result = gmPG.run_ro_query('personalia', cmd)
731 if result <> None and len(result) <> 0:
732 self.setId(result[0][0])
733 return True
734
735
736 cmd = ("""insert into dem.org (description, id_category) values('xxxDefaultxxx', ( select id from dem.org_category limit 1) )""", [])
737 cmd2 = ("""select currval('dem.org_id_seq')""", [])
738 result = gmPG.run_commit('personalia', [cmd, cmd2])
739 if result is None:
740 cmd = ("""select id from dem.org where description ='xxxDefaultxxx'""",[])
741 result = gmPG.run_commit('personalia', [cmd] )
742 if result <> None and len(result) == 1:
743 self.setId(result[0][0])
744
745
746
747 return True
748 return False
749 self.setId(result[0][0])
750
751
752
753 return True
754
756
757
758 m={}
759 c = self._changed
760 m.update(self._map)
761 m.update(self._map)
762 m.update(c)
763 if not m.has_key('name') or m['name'].strip() =='':
764 print "PLEASE ENTER ORG NAME"
765 return False
766 print "self.getId() = ", self.getId() , " is None : ", self.getId() is None
767 if self.getId() is None:
768 if not self._create():
769 import sys
770 _log.error("Cannot create org")
771 return False
772 if self.getId() is None:
773 return False
774
775 if c.has_key('name') or c.has_key('category'):
776
777
778
779 cf = cCatFinder()
780
781
782 cmd = """
783 update dem.org set description='%s' ,
784 id_category = %s where id = %s
785 """ % ( m['name'],
786 str( cf.getId('org_category', m['category']) ),
787 str(self.getId()) )
788 result = gmPG.run_commit( "personalia", [ (cmd,[] ) ] )
789 if result is None:
790 _log.error("Cannot save org")
791 return False
792
793 self._save_address()
794 self._save_comm_channels()
795 self._helper.updateCache(self)
796 return True
797
799 if self.getId() == None:
800 return False, _( "Org must be saved before adding persons")
801
802
803 if demRecord.getID() is None:
804 return False, _("demRecord doesn't have an ID ! Impossible !")
805
806 self._personMap[int(demRecord.getID())] = demRecord
807
808
809 cmd = "select id from dem.lnk_person_org_address where id_identity = %d and id_org = %d" % (int(demRecord.getID()), self.getId() )
810
811 result = gmPG.run_ro_query("personalia", cmd,[])
812 if not result is None and len(result) == 1:
813 return True, _("Ok")
814
815 cmd = "insert into dem.lnk_person_org_address(id_identity, id_org) values (%d,%d)" % ( int(demRecord.getID()), self.getId() )
816
817 result = gmPG.run_commit("personalia", [ (cmd,[]) ] )
818
819 if result is None:
820 _log.error("Cannot link person")
821 return False, _("SQL failed for link persons")
822
823 return True, _("Ok")
824
826 if self.getId() == None:
827 return False, _("Org must be saved before adding persons")
828
829 cmd = """delete from dem.lnk_person_org_address where id_identity = %d
830 and id_org = %d """ % ( int(demographicRecord.getID()) , self.getId() )
831
832 result = gmPG.run_commit("personalia", [ (cmd,[]) ] )
833
834 if result is None:
835 _log.error("Cannot unlink person")
836 return False
837
838 del self._personMap[demographicRecord.getID()]
839
840 return True
841
842
844 """gets the persons associated with this org, lazy loading demographic records
845 and caching if needed; need to later use a singleton demographic cache,
846 so that single copies of a demographic record is shared """
847 if self.getId() == None:
848 return {}
849
850 m = {}
851 m.update(self._personMap)
852
853 if not reload and not self._personMap == {} :
854 return m
855
856 query = "select id_identity from dem.lnk_person_org_address where id_org = %d"% self.getId()
857 result = gmPG.run_ro_query("personalia", query)
858 print "for ", query, " got ", result
859 if result is None:
860 _log.error("Cannot search for org persons")
861 return None
862
863 ids = filter( lambda(t): t <> None, [ id for [id] in result ])
864 print "id list is ", ids
865 new_ids = filter( lambda(id): id not in m.keys(), ids)
866
867 for id in new_ids:
868 rec = gmDemographicRecord.cDemographicRecord_SQL(id)
869 m[id] = rec
870
871 self._personMap.update(m)
872
873 return m
874
875
877 """this class behaves differently from cOrgImpl1 iff there is a parent org"""
878
882
884
885 if not cOrgImpl1._create(self):
886
887 return False
888
889 return self._saveCompositeName()
890
892 """if getParent() is None, then the behaviour is
893 unchanged from cOrgImpl1, but if there is a parent org,
894 then there will also sub-org information saved in the description"""
895
896 if not cOrgImpl1.save(self):
897 return False
898 return self._saveCompositeName()
899
900
901
903 parent = self.getParent()
904 if parent == None:
905 return True
906
907 new_description = '\n'.join([parent['name'] , self['name'], self['subtype']])
908 result = gmPG.run_commit("personalia", [ ("""update dem.org set description='%s' where id=%d
909 """ % (new_description, self.getId() ), [] ) ])
910 if result == None:
911 _log.exception("unable to update sub-org name")
912 return False
913 return True
914
915
917 """this loads the org like cOrgImpl1, but then checks for
918 additional sub-org information in the 'name' aka org.description,
919 and if it exists, the parent is retrieved or constructed using
920 the findOrgByName function.
921 """
922
923 if not cOrgImpl1._load_org_from_tuple(self, tuple, pk):
924 return False
925
926
927 self['subtype'] = ''
928
929 l = self['name'].split('\n')
930 print "split org name into ", l
931 if len(l) < 3:
932 return True
933
934 (parentName, self['name'], self['subtype'] ) = l
935 orgList = self._helper.findOrgsByName(parentName, exact = True)
936 if orgList == []:
937 return True
938 org = orgList[0]
939 self.setParent(org)
940
941 return True
942
943
946
948 self._parent = parent
949
950
951
952
954
956 self._parent = parent
957 self._helper = helper
958 self._record = None
959 self._data = { 'name':'',
960 'subtype':'',
961 'memo':'',
962 'phone':'',
963 'fax':'',
964 'email':'',
965 'mobile': ''
966 }
967
968 self._address = {
969 'number':'',
970 'street':'',
971 'urb' :'',
972 'postcode': '',
973 'state' : None,
974 'country': None
975 }
976
979
981 self._record = record
982 self._parseRecord()
983
986
988 if self._record is None:
989 return None
990 return self._record.getID()
991
992
994 pass
995
996 - def set(self, name, office, subtype, memo, category, phone, fax, email,mobile = ""):
997 d = self._data
998 s = { 'name':name,
999 'office': office,
1000 'subtype': subtype,
1001 'memo': memo,
1002 'category': category,
1003 'phone': phone,
1004 'fax' : fax,
1005 'email' : email,
1006 'mobile': mobile
1007 }
1008 for k in d.keys():
1009 d[k] = s[k]
1010
1011
1012
1013
1014
1015
1016
1017 - def setAddress(self, number, street, urb, postcode, state, country):
1018 d = self._address
1019 s = { 'number': number,
1020 'street': street,
1021 'urb' : urb,
1022 'postcode' : postcode,
1023 'state' : state,
1024 'country': country
1025 }
1026
1027
1028 for k in s.keys():
1029 d[k] = s[k]
1030
1031
1032
1033
1035 m = {}
1036 m.update(self._address)
1037 return m
1038
1039
1040
1042 d = self._data
1043 if d.has_key(k):
1044 d[k] = v
1045 return True
1046 return False
1047
1049 d = self._data
1050 if d.has_key(k):
1051 return d[k]
1052 return None
1053
1054
1056 m = {}
1057 m.update(self._data)
1058 return m
1059
1060 - def load(self, pk):
1062
1064 d = self._data
1065 r = self._record
1066 n = r.get_names()
1067 if n['title'][-1] <> '.':
1068 n['title'] = n['title'] + '.'
1069 d['name'] = ' '.join([n['title'], n['firstnames'], n['lastnames'] ])
1070 if r.getOccupation() :
1071 d['subtype'] = r.getOccupation()
1072
1073 for k,id in commtypes.items():
1074 v = r.getCommChannel(id)
1075 if v: d[k] = v
1076
1077 addressTypes = gmDemographicRecord.getAddressTypes()
1078 address = r.getAddresses( addressTypes[workAddressType], firstonly=1)
1079 a = self._address
1080
1081 print "got back address from demographic record", address
1082
1083 if address is None:
1084 return
1085
1086 fields = ['number', 'street', 'urb', 'postcode']
1087 if type(address) is type([]) and len(address) >0:
1088 if type(address[0]) is type({}):
1089 address = address[0]
1090 elif type(address[0]) is type(''):
1091 a = dict ( [(k,v) for k,v in zip( fields, address) ] )
1092 return
1093
1094 for k in fields:
1095 if type(address) is type({}):
1096 a[k] = address.get(k, '')
1097
1098
1100 print "Called save on orgPersonAdapter"
1101 if self.getParent() is None:
1102 print "no parent"
1103 _log.error("This orgPersonAdapter needs a parent org")
1104 return False
1105
1106 if self.getId() is None:
1107 print "no id"
1108 if not self._create():
1109 print "can't create an id"
1110 return False
1111
1112
1113 r = self._record
1114 d = self._data
1115
1116 print "splitting name"
1117
1118 l0 = d['name'].split('.')
1119 if len(l0) > 1:
1120 if len(l0) > 2:
1121 print "ambiguous title separation at '.'"
1122 title = l0[0] + '.'
1123 name = " ".join( l0[1:])
1124 else:
1125 name = d['name']
1126 title = ''
1127
1128 l1 = name.split(',')
1129
1130
1131 if len(l1) == 2:
1132
1133 l = [ x.strip() for x in l1]
1134 first , last = l[1], l[0]
1135 else:
1136 l1 = name.split(' ')
1137 l = [ x.strip() for x in l1]
1138
1139 inUpper = -1
1140 while inUpper > -len(l) and l[inUpper - 1].isupper():
1141 inUpper -= 1
1142
1143 first, last = ' '.join(l[0:inUpper]), ' '.join(l[inUpper:])
1144 print "adding name"
1145 r.addName(first, last, True)
1146 r.setTitle(title)
1147
1148 if r.setOccupation( d['subtype']) is None:
1149 print "FAILED TO save occupation"
1150 print "record occupation is ", r.getOccupation()
1151
1152 for k in commtypes.keys():
1153 v = d.get(k,'')
1154 if v is None or v.strip() == '':
1155 continue
1156 t = commtypes[k]
1157 r.linkCommChannel( t, v)
1158
1159
1160 a = self._address
1161
1162 if a['urb'].strip() <> '' and a['street'].strip() <> '':
1163 r.linkNewAddress( addressTypes[workAddressType],
1164 a['number'],
1165 a['street'],
1166 a['urb'],
1167 a['postcode'] )
1168
1169 self.getParent().linkPerson(self.getDemographicRecord())
1170 return True
1171
1172
1179
1182
1184 self._parent = parent
1185
1186
1187
1188
1190 """gets comm_channels for a list of org_id.
1191 returns a map keyed by org_id with lists of comm_channel data (url, type).
1192 this allows a single fetch of comm_channel data for multiple orgs"""
1193
1194 ids = ", ".join( [ str(x) for x in idList])
1195 cmd = """select l.id_org, id_type, url
1196 from dem.comm_channel c, dem.lnk_org2comm_channel l
1197 where
1198 c.id = l.id_comm and
1199 l.id_org in ( select id from dem.org where id in (%s) )
1200 """ % ids
1201 result = gmPG.run_ro_query("personalia", cmd)
1202 if result == None:
1203 _log.error("Unable to load comm channels for org" )
1204 return None
1205 m = {}
1206 for (id_org, id_type, url) in result:
1207 if not m.has_key(id_org):
1208 m[id_org] = []
1209 m[id_org].append( (id_type, url) )
1210
1211 return m
1212
1214 """gets addresses for a list of valid id values for orgs.
1215 returns a map keyed by org_id with the address data
1216 """
1217
1218 ids = ", ".join( [ str(x) for x in idList])
1219 cmd = """select l.id_org, number, street, city, postcode, state, country
1220 from dem.v_basic_address v , dem.lnk_org2address l
1221 where v.addr_id = l.id_address and
1222 l.id_org in ( select id from dem.org where id in (%s) ) """ % ids
1223 result = gmPG.run_ro_query( "personalia", cmd)
1224
1225 if result == None:
1226 _log.error("failure in org address load" )
1227 return None
1228 m = {}
1229 for (id_org, n,s,ci,p,st,co) in result:
1230 m[id_org] = (n,s,ci,p,st,co)
1231 return m
1232
1234 """ for a given list of org id values ,
1235 returns a map of id_org vs. org attributes: description, id_category"""
1236
1237 ids = ", ".join( [ str(x) for x in idList])
1238 cmd = """select id, description, id_category from dem.org
1239 where id in ( select id from dem.org where id in( %s) )""" % ids
1240
1241 print cmd
1242
1243 result = gmPG.run_ro_query("personalia", cmd, )
1244 if result is None:
1245 _log.error("Unable to load orgs with ids (%s)" %ids)
1246 return None
1247 m = {}
1248 for (id_org, d, id_cat) in result:
1249 m[id_org] = (d, id_cat)
1250 return m
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261 if __name__ == '__main__':
1262 print "Please enter a write-enabled user e.g. _test-doc "
1263
1279
1280
1281
1282
1283
1284
1286 """test org data for unit testing in testOrg()"""
1287 return [
1288 ( ["Box Hill Hospital", "", "", "Eastern", "hospital", "0398953333", "111-1111","bhh@oz", ""], ["33", "Nelson Rd", "Box Hill", "3128", None , None] ),
1289 ( ["Frankston Hospital", "", "", "Peninsula", "hospital", "0397847777", "03784-3111","fh@oz", ""], ["21", "Hastings Rd", "Frankston", "3199", None , None] )
1290 ]
1291
1293 return { "Box Hill Hospital":
1294 [
1295 ['Dr.', 'Bill' , 'Smith', '123-4567', '0417 111 222'],
1296 ['Ms.', 'Anita', 'Jones', '124-5544', '0413 222 444'],
1297 ['Dr.', 'Will', 'Stryker', '999-4444', '0402 333 111'] ],
1298 "Frankston Hospital":
1299 [ [ "Dr.", "Jason", "Boathead", "444-5555", "0403 444 2222" ],
1300 [ "Mr.", "Barnie", "Commuter", "222-1111", "0444 999 3333"],
1301 [ "Ms.", "Morita", "Traveller", "999-1111", "0222 333 1111"]] }
1302
1304 m = get_test_persons()
1305 d = dict( [ (f[0] , (f, a)) for (f, a) in get_test_data() ] )
1306 for orgName , personList in m.items():
1307 f1 , a1 = d[orgName][0], d[orgName][1]
1308 _testOrgClassPersonRun( f1, a1, personList, cOrgImpl1)
1309 _testOrgClassPersonRun( f1, a1, personList, cCompositeOrgImpl1)
1310 _testOrgClassPersonRun( f1, a1, personList, cOrgHelperImpl1().create)
1311 _testOrgClassPersonRun( f1, a1, personList, cOrgHelperImpl2().create)
1312 _testOrgClassPersonRun( f1, a1, personList, cOrgHelperImpl3().create)
1313 _testOrgClassPersonRun( f1, a1, personList, cOrgHelperImpl3().create, getTestIdentityUsing_cOrgDemographicAdapter)
1314
1315
1316
1318 m = org.getPersonMap()
1319
1320 if m== []:
1321 print "NO persons were found unfortunately"
1322
1323 print """ TestOrgPersonRun got back for """
1324 a = org.getAddress()
1325 print org["name"], a["number"], a["street"], a["urb"], a["postcode"] , " phone=", org['phone']
1326
1327 for id, r in m.items():
1328 print "\t",", ".join( [ " ".join(r.get_names().values()),
1329 "work no=", r.getCommChannel(gmDemographicRecord.WORK_PHONE),
1330 "mobile no=", r.getCommChannel(gmDemographicRecord.MOBILE)
1331 ] )
1332
1333
1335 print "Using test data :f1 = ", f1, "and a1 = ", a1 , " and lp = ", personList
1336 print "-" * 50
1337 _testOrgClassPersonRun( f1, a1, personList, cOrgImpl1)
1338 _testOrgClassPersonRun( f1, a1, personList, cCompositeOrgImpl1)
1339 _testOrgClassPersonRun( f1, a1, personList, cOrgHelperImpl1().create)
1340 _testOrgClassPersonRun( f1, a1, personList, cOrgHelperImpl2().create)
1341
1342
1348
1354
1364
1365
1366 - def _testOrgClassPersonRun(f1, a1, personList, orgCreate, identityCreator = getTestIdentityUsingDirectDemographicRecord):
1367 print "-" * 50
1368 print "Testing org creator ", orgCreate
1369 print " and identity creator ", identityCreator
1370 print "-" * 50
1371 h = orgCreate()
1372 h.set(*f1)
1373 h.setAddress(*a1)
1374 if not h.save():
1375 print "Unable to save org for person test"
1376 h.shallow_del()
1377 return False
1378
1379 for lp in personList:
1380 identity = identityCreator(lp, h)
1381 result , msg = h.linkPerson(identity)
1382 print msg
1383
1384 _outputPersons(h)
1385 deletePersons(h)
1386
1387 if h.shallow_del():
1388 print "Managed to dispose of org"
1389 else:
1390 print "unable to dispose of org"
1391
1392 return True
1393
1394
1395
1397 cmds = [ ( "delete from dem.lnk_identity2comm_chan where fk_identity=%d"%id,[]),
1398 ("delete from dem.names where id_identity=%d"%id,[]),
1399 ("delete from dem.identity where id = %d"%id,[]) ]
1400 result = gmPG.run_commit("personalia", cmds)
1401 return result
1402
1404 map = org.getPersonMap()
1405 for id, r in map.items():
1406 org.unlinkPerson(r)
1407
1408 result = deletePerson(r.getID())
1409 if result == None:
1410 _log.error("FAILED TO CLEANUP PERSON %d" %r.getID() )
1411
1412
1413
1415 """runs a test of load, save , shallow_del on items in from get_test_data"""
1416 l = get_test_data()
1417 results = []
1418 for (f, a) in l:
1419 result, obj = _testOrgRun(f, a)
1420 results.append( (result, obj) )
1421 return results
1422
1423
1424
1426
1427 print """testing single level orgs"""
1428 f = [ "name", "office", "subtype", "memo", "category", "phone", "fax", "email","mobile"]
1429 a = ["number", "street", "urb", "postcode", "state", "country"]
1430 h = cOrgImpl1()
1431
1432 h.set(*f1)
1433 h.setAddress(*a1)
1434
1435 print "testing get, getAddress"
1436 print h.get()
1437 print h.getAddressDict()
1438
1439 import sys
1440 if not h.save():
1441 print "failed to save first time. Is an old test org needing manual removal?"
1442 return False, h
1443 print "saved pk =", h.getId()
1444
1445
1446 pk = h.getId()
1447 if h.shallow_del():
1448 print "shallow deleted ", h['name']
1449 else:
1450 print "failed shallow delete of ", h['name']
1451
1452
1453
1454 h2 = cOrgImpl1()
1455
1456 print "testing load"
1457
1458 print "should fail"
1459 if not h2.load(pk):
1460 print "Failed as expected"
1461
1462 if h.save():
1463 print "saved ", h['name'] , "again"
1464 else:
1465 print "failed re-save"
1466 return False, h
1467
1468 h['fax'] = '222-1111'
1469 print "using update save"
1470
1471 if h.save():
1472 print "saved updated passed"
1473 print "Test reload next"
1474 else:
1475 print "failed save of updated data"
1476 print "continuing to reload"
1477
1478
1479 if not h2.load(h.getId()):
1480 print "failed load"
1481 return False, h
1482 print "reloaded values"
1483 print h2.get()
1484 print h2.getAddressDict()
1485
1486 print "** End of Test org"
1487
1488 if h2.shallow_del():
1489 print "cleaned up"
1490 else:
1491 print "Test org needs to be manually removed"
1492
1493 return True, h2
1494
1496 l = get_test_data()
1497
1498 names = [ "".join( ["'" ,str(org[0]), "'"] ) for ( org, address) in l]
1499 names += [ "'John Hunter Hospital'", "'Belmont District Hospital'"]
1500 nameList = ",".join(names)
1501 categoryList = "'hospital'"
1502
1503 cmds = [ ( """create temp table del_org as
1504 select id from dem.org
1505 where description in(%s) or
1506 id_category in ( select id from dem.org_category c
1507 where c.description in (%s))
1508 """ % (nameList, categoryList), [] ),
1509 ("""create temp table del_identity as
1510 select id from dem.identity
1511 where id in
1512 (
1513 select id_identity from dem.lnk_person_org_address
1514 where id_org in ( select id from del_org)
1515 )""",[] ),
1516 ("""create temp table del_comm as
1517 (select id_comm from dem.lnk_org2comm_channel where
1518 id_org in ( select id from del_org)
1519 ) UNION
1520 (select id_comm from dem.lnk_identity2comm_chan where
1521 id_identity in ( select id from del_identity)
1522 )""", [] ),
1523 ("""delete from dem.names where id_identity in
1524 (select id from del_identity)""",[]),
1525 ("""delete from dem.lnk_person_org_address where
1526 id_org in (select id from del_org )""",[]),
1527 ("""delete from dem.lnk_person_org_address where
1528 id_identity in (select id from del_identity)""", []),
1529 ("""delete from dem.lnk_org2comm_channel
1530 where id_org in (select id from del_org) """,[]),
1531 ("""delete from dem.lnk_identity2comm_chan
1532 where id_identity in (select id from del_identity)""",[] ),
1533 ("""delete from dem.comm_channel where id in ( select id_comm from del_comm)""",[]),
1534 ("""delete from dem.lnk_job2person where id_identity in (select id from del_identity)""", []),
1535 ("""delete from dem.identity where id in (select id from del_identity)""",[] ),
1536 ("""delete from dem.org where id in ( select id from del_org) """ , [] ),
1537 ("""drop table del_comm""",[]),
1538 ("""drop table del_identity""",[]),
1539 ("""drop table del_org""", [])
1540
1541 ]
1542 result = gmPG.run_commit("personalia", cmds) <> None
1543
1544 return result
1545
1546
1547 - def login_user_and_test(logintest, service = 'personalia', msg = "failed test" , use_prefix_rw= False):
1548 """ tries to get and verify a read-write connection
1549 which has permission to write to org tables, so the test case
1550 can run.
1551 """
1552 login2 = gmPG.request_login_params()
1553
1554
1555 p = gmPG.ConnectionPool( login2)
1556 if use_prefix_rw:
1557 conn = p.GetConnection( service, readonly = 0)
1558 else:
1559 conn = p.GetConnection(service)
1560 result = logintest(conn)
1561
1562 if result is False:
1563 print msg
1564
1565 p.ReleaseConnection(service)
1566 return result, login2
1567
1569
1570 try:
1571 c.reload("org_category")
1572 cursor = conn.cursor()
1573
1574 cursor.execute("select last_value from dem.org_id_seq")
1575 [org_id_seq] = cursor.fetchone()
1576
1577 cursor.execute("""
1578 insert into dem.org ( description, id_category, id)
1579 values ( 'xxxDEFAULTxxx', %d,
1580 %d)
1581 """ % ( c.getId('org_category', 'hospital') , org_id_seq + 1 ) )
1582 cursor.execute("""
1583 delete from dem.org where id = %d""" % ( org_id_seq + 1) )
1584
1585 conn.commit()
1586 except:
1587 _log.exception("Test of Update Permission failed")
1588 return False
1589 return True
1590
1592 try:
1593 cursor = conn.cursor()
1594
1595 cursor.execute("select last_value from dem.org_category_id_seq")
1596 [org_cat_id_seq] = cursor.fetchone()
1597
1598 cursor.execute("""
1599 insert into dem.org_category ( description, id)
1600 values ( 'xxxDEFAULTxxx',%d)
1601 """ % (org_cat_id_seq + 1 ) )
1602 cursor.execute("""
1603 delete from dem.org_category where description like 'xxxDEFAULTxxx' """ )
1604
1605 conn.commit()
1606 except:
1607 _log.exception("Test of Update Permission failed")
1608 return False
1609 return True
1610
1612 return login_user_and_test( test_rw_user, "login cannot update org", use_prefix_rw = True)
1613
1614
1616 return login_user_and_test( test_admin_user, "login cannot update org_category" )
1617
1618
1620 print "NEED TO CREATE TEMPORARY ORG_CATEGORY.\n\n ** PLEASE ENTER administrator login : e.g user 'gm-dbo' and his password"
1621
1622 for i in xrange(0, 4):
1623 result ,tmplogin = login_admin_user()
1624 if result:
1625 break
1626 if i == 4:
1627 print "Failed to login"
1628 return categories
1629
1630
1631 from Gnumed.pycommon import gmLoginInfo
1632 adminlogin = gmLoginInfo.LoginInfo(*tmplogin.GetInfo())
1633
1634
1635 p = gmPG.ConnectionPool( tmplogin)
1636 conn = p.GetConnection("personalia")
1637
1638
1639 cursor = conn.cursor()
1640
1641 failed_categories = []
1642 n =1
1643 for cat in categories:
1644 cursor.execute("select last_value from dem.org_category_id_seq")
1645 [org_cat_id_seq] = cursor.fetchone()
1646
1647 cursor.execute( "insert into dem.org_category(description, id) values('%s', %d)" % (cat, org_cat_id_seq + n) )
1648 cursor.execute("select id from dem.org_category where description in ('%s')" % cat)
1649
1650 result = cursor.fetchone()
1651 if result == None or len(result) == 0:
1652 failed_categories.append(cat)
1653 print "Failed insert of category", cat
1654 conn.rollback()
1655 else:
1656 conn.commit()
1657 n += 1
1658
1659 conn.commit()
1660 p.ReleaseConnection('personalia')
1661 return failed_categories, adminlogin
1662
1664
1665 print"""
1666
1667 The temporary category(s) will now
1668 need to be removed under an administrator login
1669 e.g. gm-dbo
1670 Please enter login for administrator:
1671 """
1672 if adminlogin is None:
1673 for i in xrange(0, 4):
1674 result, adminlogin = login_admin_user()
1675 if result:
1676 break
1677 if i == 4:
1678 print "FAILED TO LOGIN"
1679 return categories
1680
1681 p = gmPG.ConnectionPool(adminlogin)
1682 conn = p.GetConnection(service)
1683 failed_remove = []
1684 for cat in categories:
1685 try:
1686 cursor = conn.cursor()
1687 cursor.execute( "delete from dem.org_category where description in ('%s')"%cat)
1688 conn.commit()
1689 cursor.execute("select id from dem.org_category where description in ('%s')"%cat)
1690 if cursor.fetchone() == None:
1691 print "Succeeded in removing temporary org_category"
1692 else:
1693 print "*** Unable to remove temporary org_category"
1694 failed_remove .append(cat)
1695 except:
1696 import sys
1697 print sys.exc_info()[0], sys.exc_info()[1]
1698 import traceback
1699 traceback.print_tb(sys.exc_info()[2])
1700
1701 failed_remove.append(cat)
1702
1703 conn = None
1704 p.ReleaseConnection(service)
1705 if failed_remove <> []:
1706 print "FAILED TO REMOVE ", failed_remove
1707 return failed_remove
1708
1710 print "TESTING cCatFinder"
1711
1712 print """c = cCatFinder("org_category")"""
1713 c = cCatFinder("org_category")
1714
1715 print c.getCategories("org_category")
1716
1717 print """c = cCatFinder("enum_comm_types")"""
1718 c = cCatFinder("enum_comm_types")
1719
1720 l = c.getCategories("enum_comm_types")
1721 print "testing getId()"
1722 l2 = []
1723 for x in l:
1724 l2.append((x, c.getId("enum_comm_types", x)))
1725 print l2
1726
1727 print """testing borg behaviour of cCatFinder"""
1728
1729 print c.getCategories("org_category")
1730
1731
1733 print """\nNB If imports not found , try:
1734
1735 change to gnumed/client directory , then
1736
1737 export PYTHONPATH=$PYTHONPATH:../;python business/gmOrganization.py
1738
1739 --clean , cleans the test data and categories
1740
1741 --gui sets up as for no arguments, then runs the client.
1742 on normal exit of client, normal tests run, and
1743 then cleanup of entered data.
1744
1745 using the gui,
1746
1747 the 'list organisations' toolbar button , loads all organisations
1748 in the database, and display suborgs and persons associated
1749 with each organisation.
1750
1751 the 'add organisation' button will add a top-level organisation.
1752 the 'add branch/division' button will work when the last selected
1753 org was a top level org.
1754
1755 the 'add person M|F' button works if an org is selected.
1756
1757 the save button works when entry is finished.
1758
1759 selecting on an item, will bring it into the editing area.
1760
1761 No test yet for dirtied edit data, to query whether to
1762 save or discard. (30/5/2004)
1763 """
1764 print
1765 print "In the connection query, please enter"
1766 print "a WRITE-ENABLED user e.g. _test-doc (not test-doc), and the right password"
1767 print
1768 print "Run the unit test with cmdline argument '--clean' if trying to clean out test data"
1769 print
1770
1771 print """You can get a sermon by running
1772 export PYTHONPATH=$PYTHONPATH:../;python business/gmOrganization.py --sermon
1773 """
1774 print """
1775 Pre-requisite data in database is :
1776 gnumed=# select * from org_category ;
1777 id | description
1778 ----+-------------
1779 1 | hospital
1780 (1 row)
1781
1782 gnumed=# select * from enum_comm_types ;
1783 id | description
1784 ----+-------------
1785 1 | email
1786 2 | fax
1787 3 | homephone
1788 4 | workphone
1789 5 | mobile
1790 6 | web
1791 7 | jabber
1792 (7 rows)
1793 """
1794
1796 print"""
1797 This test case shows how many things can go wrong , even with just a test case.
1798 Problem areas include:
1799 - postgres administration : pg_ctl state, pg_hba.conf, postgres.conf config files .
1800 - schema integrity constraints : deletion of table entries which are subject to foreign keys, no input for no default value and no null value columns, input with duplicated values where unique key constraint applies to non-primary key columns, dealing with access control by connection identity management.
1801
1802
1803 - efficiency trade-offs -e.g. using db objects for localising code with data and easier function call interface ( then hopefully, easier to program with) , vs. need to access many objects at once
1804 without calling the backend for each object.
1805
1806 - error and exception handling - at what point in the call stack to handle an error.
1807 Better to use error return values and log exceptions near where they occur, vs. wrapping inside try: except: blocks and catching typed exceptions.
1808
1809
1810 - test-case construction: test data is needed often, and the issue
1811 is whether it is better to keep the test data volatile in the test-case,
1812 which handles both its creation and deletion, or to add it to test data
1813 server configuration files, which may involve running backend scripts
1814 for loading and removing test data.
1815
1816
1817
1818 - Database connection problems:
1819 -Is the problem in :
1820 - pg_ctl start -D /...mydata-directory is wrong, and gnumed isn't existing there.
1821
1822 - ..mydata-directory/pg_hba.conf
1823 - can psql connect locally and remotely with the username and password.
1824 - Am I using md5 authenentication and I've forgotten the password.
1825 - I need to su postgres, alter pg_hba.conf to use trust for
1826 the gnumed database, pg_ctl restart -D .., su normal_user, psql gnumed, alter user my_username password 'doh'
1827 - might be helpful: the default password for _test-doc is test-doc
1828
1829 - ../mydata-directory/postgres.conf
1830 - tcp connect flag isn't set to true
1831
1832 - remote/local mixup :
1833 a different set of user passwords on different hosts. e.g the password
1834 for _test-doc is 'pass' on localhost and 'test-doc' for the serverhost.
1835 - In the prompts for admin and user login, local host was used for one, and
1836 remote host for the other
1837
1838
1839
1840 - test data won't go away :
1841 - 'hospital' category in org_category : the test case failed in a previous run
1842 and the test data was left there; now the test case won't try to delete it
1843 because it exists as a pre-existing category;
1844 soln : run with --clean option
1845
1846
1847 - test-case failed unexpectedly, or break key was hit in the middle of a test-case run.
1848 Soln: run with --clean option,
1849
1850
1851 """
1852
1853
1854
1855
1856 import sys
1857 testgui = False
1858 if len(sys.argv) > 1:
1859 if sys.argv[1] == '--clean':
1860 result = clean_test_org()
1861 p = gmPG.ConnectionPool()
1862 p.ReleaseConnection('personalia')
1863 if result:
1864 print "probably succeeded in cleaning orgs"
1865 else: print "failed to clean orgs"
1866
1867 clean_org_categories()
1868 sys.exit(1)
1869
1870 if sys.argv[1] == "--sermon":
1871 sermon()
1872
1873 if sys.argv[1] == "--help":
1874 help()
1875
1876 if sys.argv[1] =="--gui":
1877 testgui = True
1878
1879 print "*" * 50
1880 print "RUNNING UNIT TEST of gmOrganization "
1881
1882
1883 test_CatFinder()
1884 tmp_category = False
1885
1886
1887 c = cCatFinder()
1888 if not "hospital" in c.getCategories("org_category") :
1889 print "FAILED in prerequisite for org_category : test categories are not present."
1890
1891 tmp_category = True
1892
1893 if tmp_category:
1894
1895
1896 print """You will need to switch login identity to database administrator in order
1897 to have permission to write to the org_category table,
1898 and then switch back to the ordinary write-enabled user in order
1899 to run the test cases.
1900 Finally you will need to switch back to administrator login to
1901 remove the temporary org_categories.
1902 """
1903 categories = ['hospital']
1904 result, adminlogin = create_temp_categories(categories)
1905 if result == categories:
1906 print "Unable to create temporary org_category. Test aborted"
1907 sys.exit(-1)
1908 if result <> []:
1909 print "UNABLE TO CREATE THESE CATEGORIES"
1910 if not raw_input("Continue ?") in ['y', 'Y'] :
1911 sys.exit(-1)
1912
1913 try:
1914 results = []
1915 if tmp_category:
1916 print "succeeded in creating temporary org_category"
1917 print
1918 print "** Now ** RESUME LOGIN ** of write-enabled user (e.g. _test-doc) "
1919 while (1):
1920
1921 if login_rw_user():
1922 break
1923
1924 if testgui:
1925 if cCatFinder().getId('org_category','hospital') == None:
1926 print "Needed to set up temporary org_category 'hospital"
1927 sys.exit(-1)
1928 import os
1929 print os.environ['PWD']
1930 os.spawnl(os.P_WAIT, "/usr/bin/python", "/usr/bin/python","wxpython/gnumed.py", "--debug")
1931
1932
1933
1934
1935 results = testOrg()
1936
1937
1938 for (result , org) in results:
1939 if not result and org.getId() <> None:
1940 print "trying cleanup"
1941 if org.shallow_del(): print " may have succeeded"
1942 else:
1943 print "May need manual removal of org id =", org.getId()
1944
1945 testOrgPersons()
1946
1947 testListOrgs()
1948
1949 except:
1950 import sys
1951 print sys.exc_info()[0], sys.exc_info()[1]
1952 _log.exception( "Fatal exception")
1953
1954
1955 if tmp_category:
1956 try:
1957 clean_org_categories(adminlogin)
1958 except:
1959 while(not login_rw_user()[0]):
1960 pass
1961 clean_test_org()
1962 clean_org_categories(adminlogin)
1963
1964
1965
1967 """convenience method for urb and postcode phrasewheel interaction.
1968 never called without both arguments, but need to check that id_urb
1969 is not invalid"""
1970
1971
1972 if postcodeWidget is None or id_urb is None:
1973 return False
1974 postcode = getPostcodeForUrbId(id_urb)
1975 if postcode is None:
1976 return False
1977 if len(postcode) == 0:
1978 return True
1979 postcodeWidget.SetValue(postcode)
1980 postcodeWidget.input_was_selected= 1
1981 return True
1982
1983
1984
1986 """convenience method for common postcode to urb phrasewheel collaboration.
1987 there is no default args for these utility functions,
1988 This function is never called without both arguments, otherwise
1989 there is no intention (= modify the urb phrasewheel with postcode value).
1990 """
1991
1992
1993
1994 if pwheel is None:
1995 return False
1996 if postcode == '':
1997 pwheel.set_context("postcode", "%")
1998 return True
1999 urbs = getUrbsForPostcode(postcode)
2000 if urbs is None:
2001 return False
2002 if len(urbs) == 0:
2003 return True
2004 pwheel.SetValue(urbs[0])
2005 pwheel.input_was_selected = 1
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018 pwheel.set_context("postcode", postcode)
2019 return True
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186