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