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