1 """GNUmed generic address related widgets."""
2
3 __author__ = 'karsten.hilbert@gmx.net'
4 __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
5
6
7 import logging, sys
8
9
10
11 import wx
12
13
14
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17
18 from Gnumed.pycommon import gmTools
19 from Gnumed.pycommon import gmMatchProvider
20 from Gnumed.business import gmDemographicRecord
21
22 from Gnumed.wxpython import gmCfgWidgets
23 from Gnumed.wxpython import gmPhraseWheel
24 from Gnumed.wxpython import gmListWidgets
25 from Gnumed.wxpython import gmEditArea
26 from Gnumed.wxpython import gmGuiHelpers
27
28
29 _log = logging.getLogger('gm.ui')
30
31
32
49
51
53
54 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
55
56 context = {
57 u'ctxt_zip': {
58 u'where_part': u'and zip ilike %(zip)s',
59 u'placeholder': u'zip'
60 }
61 }
62 query = u"""
63 SELECT
64 data,
65 field_label,
66 list_label
67 FROM (
68 SELECT DISTINCT ON (data)
69 data,
70 field_label,
71 list_label,
72 rank
73 FROM (
74
75 -- localized to user
76 SELECT
77 code_country AS data,
78 l10n_country AS field_label,
79 l10n_country || ' (' || code_country || '): ' || country AS list_label,
80 1 AS rank
81 FROM dem.v_zip2data
82 WHERE
83 l10n_country %(fragment_condition)s
84 %(ctxt_zip)s
85 UNION ALL
86 SELECT
87 code AS data,
88 _(name) AS field_label,
89 _(name) || ' (' || code || '): ' || name AS list_label,
90 2 AS rank
91 FROM dem.country
92 WHERE
93 _(name) %(fragment_condition)s
94
95 UNION ALL
96
97 -- non-localized
98 SELECT
99 code_country AS data,
100 l10n_country AS field_label,
101 country || ' (' || code_country || '): ' || l10n_country AS list_label,
102 3 AS rank
103 FROM dem.v_zip2data
104 WHERE
105 country %(fragment_condition)s
106 %(ctxt_zip)s
107 UNION ALL
108 SELECT
109 code AS data,
110 _(name) AS field_label,
111 name || ' (' || code || '): ' || _(name) AS list_label,
112 4 AS rank
113 FROM dem.country
114 WHERE
115 name %(fragment_condition)s
116
117 UNION ALL
118
119 -- abbreviation
120 SELECT
121 code AS data,
122 _(name) AS field_label,
123 code || ': ' || _(name) || ' (' || name || ')' AS list_label,
124 5 AS rank
125 FROM dem.country
126 WHERE
127 code %(fragment_condition)s
128
129 ) AS candidates
130 ) AS distint_candidates
131 ORDER BY rank, list_label
132 LIMIT 25"""
133 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
134 mp._SQL_data2match = u"""
135 SELECT
136 code AS data,
137 _(name) AS field_label,
138 code || ': ' || _(name) || ' (' || name || ')' AS list_label,
139 5 AS rank
140 FROM dem.country
141 WHERE
142 code = %(pk)s
143 """
144 mp.setThresholds(2, 5, 9)
145 self.matcher = mp
146
147 self.unset_context(context = u'zip')
148 self.SetToolTipString(_('Type or select a country.'))
149 self.capitalisation_mode = gmTools.CAPS_FIRST
150 self.selection_only = True
151
152
153
154
171
173 ea = cProvinceEAPnl(parent = parent, id = -1, province = province)
174 dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = (province is not None))
175 dlg.SetTitle(gmTools.coalesce(province, _('Adding province'), _('Editing province')))
176 result = dlg.ShowModal()
177 dlg.Destroy()
178 return (result == wx.ID_OK)
179
181
182 msg = _(
183 'Are you sure you want to delete this province ?\n'
184 '\n'
185 'Deletion will only work if this province is not\n'
186 'yet in use in any patient addresses.'
187 )
188
189 tt = _(
190 'Also delete any towns/cities/villages known\n'
191 'to be situated in this state as long as\n'
192 'no patients are recorded to live there.'
193 )
194
195 dlg = gmGuiHelpers.c2ButtonQuestionDlg (
196 parent,
197 -1,
198 caption = _('Deleting province'),
199 question = msg,
200 show_checkbox = True,
201 checkbox_msg = _('delete related townships'),
202 checkbox_tooltip = tt,
203 button_defs = [
204 {'label': _('Yes, delete'), 'tooltip': _('Delete province and possibly related townships.'), 'default': False},
205 {'label': _('No'), 'tooltip': _('No, do NOT delete anything.'), 'default': True}
206 ]
207 )
208
209 decision = dlg.ShowModal()
210 if decision != wx.ID_YES:
211 dlg.Destroy()
212 return False
213
214 include_urbs = dlg.checkbox_is_checked()
215 dlg.Destroy()
216
217 return gmDemographicRecord.delete_province(province = province, delete_urbs = include_urbs)
218
220
221 if parent is None:
222 parent = wx.GetApp().GetTopWindow()
223
224
225 def delete(province=None):
226 return delete_province(parent = parent, province = province['pk_state'])
227
228 def edit(province=None):
229 return edit_province(parent = parent, province = province)
230
231 def refresh(lctrl):
232 wx.BeginBusyCursor()
233 provinces = gmDemographicRecord.get_provinces()
234 lctrl.set_string_items([ (p['l10n_country'], p['l10n_state']) for p in provinces ])
235 lctrl.set_data(provinces)
236 wx.EndBusyCursor()
237
238 msg = _(
239 '\n'
240 'This list shows the provinces known to GNUmed.\n'
241 '\n'
242 'In your jurisdiction "province" may correspond to either of "state",\n'
243 '"county", "region", "territory", or some such term.\n'
244 '\n'
245 'Select the province you want to edit !\n'
246 )
247
248 gmListWidgets.get_choices_from_list (
249 parent = parent,
250 msg = msg,
251 caption = _('Editing provinces ...'),
252 columns = [_('Country'), _('Province')],
253 single_selection = True,
254 new_callback = edit,
255
256 delete_callback = delete,
257 refresh_callback = refresh
258 )
259
261
263
264 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
265
266 context = {
267 u'ctxt_country_name': {
268 u'where_part': u'AND l10n_country ILIKE %(country_name)s OR country ILIKE %(country_name)s',
269 u'placeholder': u'country_name'
270 },
271 u'ctxt_zip': {
272 u'where_part': u'AND zip ilike %(zip)s',
273 u'placeholder': u'zip'
274 },
275 u'ctxt_country_code': {
276 u'where_part': u'AND country IN (SELECT code FROM dem.country WHERE _(name) ILIKE %(country_name)s OR name ILIKE %(country_name)s)',
277 u'placeholder': u'country_name'
278 }
279 }
280
281 query = u"""
282 SELECT
283 data,
284 field_label,
285 list_label
286 FROM (
287 SELECT DISTINCT ON (field_label)
288 data,
289 field_label,
290 list_label,
291 rank
292 FROM (
293 -- 1: find states based on name, context: zip and country name
294 SELECT
295 code_state AS data,
296 state AS field_label,
297 state || ' (' || code_state || '), ' || l10n_country || ' (' || code_country || ')' AS list_label,
298 1 AS rank
299 FROM dem.v_zip2data
300 WHERE
301 state %(fragment_condition)s
302 %(ctxt_country_name)s
303 %(ctxt_zip)s
304
305 UNION ALL
306
307 -- 2: find states based on code, context: zip and country name
308 SELECT
309 code_state AS data,
310 state AS field_label,
311 code_state || ': ' || state || ' (' || l10n_country || ', ' || code_country || ')' AS list_label,
312 2 AS rank
313 FROM dem.v_zip2data
314 WHERE
315 code_state %(fragment_condition)s
316 %(ctxt_country_name)s
317 %(ctxt_zip)s
318
319 UNION ALL
320
321 -- 3: find states based on name, context: country
322 SELECT
323 code AS data,
324 name AS field_label,
325 name || ' (' || code || '), ' || country AS list_label,
326 3 AS rank
327 FROM dem.state
328 WHERE
329 name %(fragment_condition)s
330 %(ctxt_country_code)s
331
332 UNION ALL
333
334 -- 4: find states based on code, context: country
335 SELECT
336 code AS data,
337 name AS field_label,
338 code || ': ' || name || ', ' || country AS list_label,
339 3 AS rank
340 FROM dem.state
341 WHERE
342 code %(fragment_condition)s
343 %(ctxt_country_code)s
344
345 ) AS candidate_states
346 ) AS distinct_matches
347 ORDER BY rank, list_label
348 LIMIT 50"""
349
350 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
351 mp.setThresholds(2, 5, 6)
352 mp.word_separators = u'[ \t]+'
353 self.matcher = mp
354
355 self.unset_context(context = u'zip')
356 self.unset_context(context = u'country_name')
357 self.SetToolTipString(_('Type or select a state/region/province/territory.'))
358 self.capitalisation_mode = gmTools.CAPS_FIRST
359 self.selection_only = True
360
361 from Gnumed.wxGladeWidgets import wxgProvinceEAPnl
362
363 -class cProvinceEAPnl(wxgProvinceEAPnl.wxgProvinceEAPnl, gmEditArea.cGenericEditAreaMixin):
364
382
384 self._PRW_province.selection_only = False
385
386
387
415
431
433
434
435
436
437
438
439
440 return True
441
448
450 self._PRW_province.SetText(self.data['l10n_state'], self.data['code_state'])
451 self._TCTRL_code.SetValue(self.data['code_state'])
452 self._PRW_country.SetText(self.data['l10n_country'], self.data['code_country'])
453
454 self._PRW_province.SetFocus()
455
462
463
464
465
467
469
470 query = u"""
471 (SELECT distinct postcode, postcode FROM dem.street WHERE postcode %(fragment_condition)s limit 20)
472 UNION
473 (SELECT distinct postcode, postcode FROM dem.urb WHERE postcode %(fragment_condition)s limit 20)"""
474 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
475 mp.setThresholds(2, 3, 15)
476 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
477 self.SetToolTipString(_("Type or select a zip code (postcode).\n\nUse e.g. '?' if unknown."))
478 self.matcher = mp
479
481
483 context = {
484 u'ctxt_zip': {
485 u'where_part': u'AND zip ILIKE %(zip)s',
486 u'placeholder': u'zip'
487 }
488 }
489 query = u"""
490 SELECT
491 data,
492 field_label,
493 list_label
494 FROM (
495
496 SELECT DISTINCT ON (data)
497 street AS data,
498 street AS field_label,
499 street || ' (' || zip || ', ' || urb || coalesce(', ' || suburb, '') || ', ' || l10n_country || ')' AS list_label,
500 1 AS rank
501 FROM dem.v_zip2data
502 WHERE
503 street %(fragment_condition)s
504 %(ctxt_zip)s
505
506 UNION ALL
507
508 SELECT DISTINCT ON (data)
509 name AS data,
510 name AS field_label,
511 name || ' (' || postcode || coalesce(', ' || suburb, '') || ')' AS list_label,
512 2 AS rank
513 FROM dem.street
514 WHERE
515 name %(fragment_condition)s
516
517 ) AS matching_streets
518 ORDER BY rank, field_label
519 LIMIT 50"""
520 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
521 mp.setThresholds(3, 5, 8)
522 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
523 self.unset_context(context = u'zip')
524
525 self.SetToolTipString(_('Type or select a street.'))
526 self.capitalisation_mode = gmTools.CAPS_FIRST
527 self.matcher = mp
528
551
553
555 context = {
556 u'ctxt_zip': {
557 u'where_part': u'and zip ilike %(zip)s',
558 u'placeholder': u'zip'
559 }
560 }
561 query = u"""
562 SELECT DISTINCT ON (rank, data)
563 data,
564 field_label,
565 list_label
566 FROM (
567
568 SELECT
569 urb AS data,
570 urb AS field_label,
571 urb || ' (' || zip || ', ' || state || ', ' || l10n_country || ')' AS list_label,
572 1 AS rank
573 FROM dem.v_zip2data
574 WHERE
575 urb %(fragment_condition)s
576 %(ctxt_zip)s
577
578 UNION ALL
579
580 SELECT
581 name AS data,
582 name AS field_label,
583 name || ' (' || postcode ||')' AS list_label,
584 2 AS rank
585 FROM dem.urb
586 WHERE
587 name %(fragment_condition)s
588
589 ) AS matching_urbs
590 ORDER BY rank, data
591 LIMIT 50"""
592 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
593 mp.setThresholds(3, 5, 7)
594 gmPhraseWheel.cPhraseWheel.__init__ (
595 self,
596 *args,
597 **kwargs
598 )
599 self.unset_context(context = u'zip')
600
601 self.SetToolTipString(_('Type or select a city/town/village/dwelling.'))
602 self.capitalisation_mode = gmTools.CAPS_FIRST
603 self.matcher = mp
604
605
606
607
609
610 if parent is None:
611 parent = wx.GetApp().GetTopWindow()
612
613
614 def calculate_tooltip(address):
615 return u'\n'.join(address.format())
616
617 def delete(address):
618 return gmDemographicRecord.delete_address(pk_address = address['pk_address'])
619
620 def refresh(lctrl):
621 adrs = gmDemographicRecord.get_addresses(order_by = u'l10n_country, urb, street, number, subunit')
622 items = [ [
623 a['street'],
624 gmTools.coalesce(a['notes_street'], u''),
625 a['number'],
626 gmTools.coalesce(a['subunit'], u''),
627 a['postcode'],
628 a['urb'],
629 gmTools.coalesce(a['suburb'], u''),
630 a['l10n_state'],
631 a['l10n_country'],
632 gmTools.coalesce(a['notes_subunit'], u'')
633 ] for a in adrs
634 ]
635 lctrl.set_string_items(items)
636 lctrl.set_data(adrs)
637
638
639 cols = [
640 _('Street'),
641 _('Street info'),
642 _('Number'),
643 _('Subunit'),
644 _('Postal code'),
645 _('Community'),
646 _('Suburb'),
647 _('Region'),
648 _('Country'),
649 _('Comment')
650 ]
651 return gmListWidgets.get_choices_from_list (
652 parent = parent,
653 caption = _('Showing addresses registered in GNUmed.'),
654 columns = cols,
655 single_selection = True,
656 refresh_callback = refresh,
657 delete_callback = delete,
658 list_tooltip_callback = calculate_tooltip
659 )
660
661 from Gnumed.wxGladeWidgets import wxgGenericAddressEditAreaPnl
662
664 """An edit area for editing/creating an address."""
665
681
682
683
684 - def refresh(self, address = None):
685 if address is not None:
686 self.__address = address
687
688 if self.__address is None:
689 self._PRW_type.SetText(u'', None)
690 self._PRW_zip.SetText(u'', None)
691 self._PRW_street.SetText(u'', None)
692 self._TCTRL_notes_street.SetValue(u'')
693 self._TCTRL_number.SetValue(u'')
694 self._TCTRL_subunit.SetValue(u'')
695 self._PRW_suburb.SetText(u'', None)
696 self._PRW_urb.SetText(u'', None)
697 self._PRW_state.SetText(u'', None)
698 self._PRW_country.SetText(u'', None)
699 self._TCTRL_notes_subunit.SetValue(u'')
700 if self.__type_is_editable:
701 self._PRW_type.SetFocus()
702 else:
703 self._PRW_zip.SetFocus()
704 return
705
706 if self.__type_is_editable:
707 self._PRW_type.SetText(self.address['l10n_address_type'])
708 else:
709 self._PRW_type.SetText(u'', None)
710 self._PRW_zip.SetText(self.address['postcode'])
711 self._PRW_street.SetText(self.address['street'], data = self.address['street'])
712 self._TCTRL_notes_street.SetValue(gmTools.coalesce(self.address['notes_street'], ''))
713 self._TCTRL_number.SetValue(self.address['number'])
714 self._TCTRL_subunit.SetValue(gmTools.coalesce(self.address['subunit'], ''))
715 self._PRW_suburb.SetText(gmTools.coalesce(self.address['suburb'], ''))
716 self._PRW_urb.SetText(self.address['urb'], data = self.address['urb'])
717 self._PRW_state.SetText(self.address['l10n_state'], data = self.address['code_state'])
718 self._PRW_country.SetText(self.address['l10n_country'], data = self.address['code_country'])
719 self._TCTRL_notes_subunit.SetValue(gmTools.coalesce(self.address['notes_subunit'], ''))
720
721 if self.__type_is_editable:
722 self._PRW_type.SetFocus()
723 else:
724 self._PRW_zip.SetFocus()
725 return
726
728 """Links address to patient or org, creating new address if necessary"""
729
730 if not self.__valid_for_save():
731 return False
732
733 try:
734 address = gmDemographicRecord.create_address (
735 country = self._PRW_country.GetData(),
736 state = self._PRW_state.GetData(),
737 urb = self._PRW_urb.GetValue().strip(),
738 suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), u''),
739 postcode = self._PRW_zip.GetValue().strip(),
740 street = self._PRW_street.GetValue().strip(),
741 number = self._TCTRL_number.GetValue().strip(),
742 subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), u'')
743 )
744 except:
745 _log.exception('cannot save address')
746 gmGuiHelpers.gm_show_error (
747 _('Cannot save address.\n\n'
748 'Does the state [%s]\n'
749 'exist in country [%s] ?'
750 ) % (
751 self._PRW_state.GetValue().strip(),
752 self._PRW_country.GetValue().strip()
753 ),
754 _('Saving address')
755 )
756 return False
757
758
759 a = self.address_holder.link_address(id_type = self._PRW_type.GetData(), address = address)
760 if a['pk_address'] != address['pk_address']:
761 raise ValueError('problem linking address to person or org')
762
763 notes = self._TCTRL_notes_street.GetValue().strip()
764 if notes != u'':
765 address['notes_street'] = notes
766 notes = self._TCTRL_notes_subunit.GetValue().strip()
767 if notes != u'':
768 address['notes_subunit'] = notes
769 address.save_payload()
770
771 self.__address = address
772
773 return True
774
775
776
780
782 """Set the street, town, state and country according to entered zip code."""
783 zip_code = self._PRW_zip.GetValue()
784 if zip_code.strip() == u'':
785 self._PRW_street.unset_context(context = u'zip')
786 self._PRW_urb.unset_context(context = u'zip')
787 self._PRW_state.unset_context(context = u'zip')
788 self._PRW_country.unset_context(context = u'zip')
789 else:
790 self._PRW_street.set_context(context = u'zip', val = zip_code)
791 self._PRW_urb.set_context(context = u'zip', val = zip_code)
792 self._PRW_state.set_context(context = u'zip', val = zip_code)
793 self._PRW_country.set_context(context = u'zip', val = zip_code)
794
796 """Set the states according to entered country."""
797 country = self._PRW_country.GetData()
798 if country is None:
799 self._PRW_state.unset_context(context = 'country')
800 else:
801 self._PRW_state.set_context(context = 'country', val = country)
802
803
804
806
807
808 is_any_field_filled = False
809
810 required_fields = [
811 self._PRW_zip,
812 self._PRW_street,
813 self._TCTRL_number,
814 self._PRW_urb
815 ]
816 if self.__type_is_editable:
817 required_fields.insert(0, self._PRW_type)
818
819 for field in required_fields:
820 if len(field.GetValue().strip()) == 0:
821 if is_any_field_filled:
822 field.SetBackgroundColour('pink')
823 field.SetFocus()
824 field.Refresh()
825 gmGuiHelpers.gm_show_error (
826 _('Address details must be filled in completely or not at all.'),
827 _('Saving contact data')
828 )
829 return False
830 else:
831 is_any_field_filled = True
832 field.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
833 field.Refresh()
834
835 required_fields = (
836 self._PRW_state,
837 self._PRW_country
838 )
839 for field in required_fields:
840 if field.GetData() is None:
841 if is_any_field_filled:
842 field.SetBackgroundColour('pink')
843 field.SetFocus()
844 field.Refresh()
845 gmGuiHelpers.gm_show_error (
846 _('Address details must be filled in completely or not at all.'),
847 _('Saving contact data')
848 )
849 return False
850 else:
851 is_any_field_filled = True
852 field.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
853 field.Refresh()
854
855 return True
856
857
858
860 return self.__type_is_editable
861
867
868 type_is_editable = property(_get_type_is_editable, _set_type_is_editable)
869
871 return self.__address_is_searchable
872
879
880 address_is_searchable = property(_get_address_is_searchable, _set_address_is_searchable)
881
883 return self.__address
884
888
889 address = property(_get_address, _set_address)
890
891
893
895
896 query = u"""
897 SELECT id, type FROM ((
898 SELECT id, _(name) AS type, 1 AS rank
899 FROM dem.address_type
900 WHERE _(name) %(fragment_condition)s
901 ) UNION (
902 SELECT id, name AS type, 2 AS rank
903 FROM dem.address_type
904 WHERE name %(fragment_condition)s
905 )) AS ur
906 order by
907 ur.rank, ur.type
908 """
909 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
910 mp.setThresholds(1, 2, 4)
911 mp.word_separators = u'[ \t]+'
912 gmPhraseWheel.cPhraseWheel.__init__ (
913 self,
914 *args,
915 **kwargs
916 )
917 self.matcher = mp
918 self.SetToolTipString(_('Select the type of address.'))
919
920 self.selection_only = True
921
922
923
924
925
926
927
928
930
932
933 query = u"""
934 SELECT * FROM (
935 (SELECT
936 pk_address AS data,
937 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
938 || urb || coalesce(' (' || suburb || ')', '') || ', '
939 || postcode || ', '
940 || code_country
941 ) AS field_label,
942 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
943 || urb || coalesce(' (' || suburb || ')', '') || ', '
944 || postcode || ', '
945 || l10n_state || ', '
946 || l10n_country
947 || coalesce(', ' || notes_street, '')
948 || coalesce(', ' || notes_subunit, '')
949 ) AS list_label
950 FROM
951 dem.v_address
952 WHERE
953 street %(fragment_condition)s
954
955 ) UNION (
956
957 SELECT
958 pk_address AS data,
959 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
960 || urb || coalesce(' (' || suburb || ')', '') || ', '
961 || postcode || ', '
962 || code_country
963 ) AS field_label,
964 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
965 || urb || coalesce(' (' || suburb || ')', '') || ', '
966 || postcode || ', '
967 || l10n_state || ', '
968 || l10n_country
969 || coalesce(', ' || notes_street, '')
970 || coalesce(', ' || notes_subunit, '')
971 ) AS list_label
972 FROM
973 dem.v_address
974 WHERE
975 postcode_street %(fragment_condition)s
976
977 ) UNION (
978
979 SELECT
980 pk_address AS data,
981 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
982 || urb || coalesce(' (' || suburb || ')', '') || ', '
983 || postcode || ', '
984 || code_country
985 ) AS field_label,
986 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
987 || urb || coalesce(' (' || suburb || ')', '') || ', '
988 || postcode || ', '
989 || l10n_state || ', '
990 || l10n_country
991 || coalesce(', ' || notes_street, '')
992 || coalesce(', ' || notes_subunit, '')
993 ) AS list_label
994 FROM
995 dem.v_address
996 WHERE
997 postcode_urb %(fragment_condition)s
998 )
999 ) AS matching_addresses
1000 ORDER BY list_label
1001 LIMIT 50"""
1002
1003 gmMatchProvider.cMatchProvider_SQL2.__init__(self, queries = query)
1004
1005 self.setThresholds(2, 4, 6)
1006
1007
1008 self._SQL_data2match = u"""
1009 SELECT
1010 pk_address AS data,
1011 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1012 || urb || coalesce(' (' || suburb || ')', '') || ', '
1013 || postcode || ', '
1014 || code_country
1015 ) AS field_label,
1016 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1017 || urb || coalesce(' (' || suburb || ')', '') || ', '
1018 || postcode || ', '
1019 || l10n_state || ', '
1020 || l10n_country
1021 || coalesce(', ' || notes_street, '')
1022 || coalesce(', ' || notes_subunit, '')
1023 ) AS list_label
1024 FROM
1025 dem.v_address
1026 WHERE
1027 pk_address = %(pk)s
1028 """
1029
1030
1032
1034
1035 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
1036 self.matcher = cAddressMatchProvider()
1037 self.SetToolTipString(_('Select an address by postcode or street name.'))
1038 self.selection_only = True
1039 self.__address = None
1040 self.__old_pk = None
1041
1047
1050
1051
1052
1054 pk = self.GetData()
1055 if pk is None:
1056 self.__address = None
1057 return None
1058 if self.__address is None:
1059 self.__old_pk = pk
1060 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
1061 else:
1062 if pk != self.__old_pk:
1063 self.__old_pk = pk
1064 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
1065 return self.__address
1066
1068 if address is None:
1069 self.__old_pk = None
1070 self.__address = None
1071 self.SetText(u'', None)
1072 return
1073 if isinstance(address, gmDemographicRecord.cAddress):
1074 self.__old_pk = address['pk_address']
1075 self.__address = address
1076 pk = self.__old_pk
1077 else:
1078 self.__old_pk = None
1079 self.__address = None
1080 pk = address
1081 match = self.matcher.get_match_by_data(data = pk)
1082 if match is None:
1083 raise ValueError(u'[%s]: cannot match address [#%s]' % (self.__class__.__name__, pk))
1084 self.SetText(match['field_label'], pk)
1085
1086 address = property(__get_address, __set_address)
1087
1088
1089
1090
1091 if __name__ == '__main__':
1092
1093 if len(sys.argv) < 2:
1094 sys.exit()
1095
1096 if sys.argv[1] != 'test':
1097 sys.exit()
1098
1099 from Gnumed.pycommon import gmI18N
1100 gmI18N.activate_locale()
1101 gmI18N.install_domain()
1102 from Gnumed.business import gmPersonSearch
1103
1104
1106 app = wx.PyWidgetTester(size = (200, 50))
1107 pw = cCountryPhraseWheel(app.frame, -1)
1108 app.frame.Show(True)
1109 app.MainLoop()
1110
1112 app = wx.PyWidgetTester(size = (200, 50))
1113 pw = cStateSelectionPhraseWheel(app.frame, -1)
1114 pw.set_context(context = u'zip', val = u'04318')
1115 pw.set_context(context = u'country', val = u'Deutschland')
1116 app.frame.Show(True)
1117 app.MainLoop()
1118
1120 app = wx.PyWidgetTester(size = (200, 50))
1121 pw = cZipcodePhraseWheel(app.frame, -1)
1122 app.frame.Show(True)
1123 app.MainLoop()
1124
1126 app = wx.PyWidgetTester(size = (200, 50))
1127 pw = cStreetPhraseWheel(app.frame, -1)
1128
1129 app.frame.Show(True)
1130 app.MainLoop()
1131
1133 app = wx.PyWidgetTester(size = (200, 50))
1134 pw = cSuburbPhraseWheel(app.frame, -1)
1135 app.frame.Show(True)
1136 app.MainLoop()
1137
1139 app = wx.PyWidgetTester(size = (200, 50))
1140 pw = cUrbPhraseWheel(app.frame, -1)
1141 app.frame.Show(True)
1142 pw.set_context(context = u'zip', val = u'04317')
1143 app.MainLoop()
1144
1146 app = wx.PyWidgetTester(size = (200, 50))
1147 pw = cAddressTypePhraseWheel(app.frame, -1)
1148 app.frame.Show(True)
1149 app.MainLoop()
1150
1152 app = wx.PyWidgetTester(size = (200, 50))
1153 pw = cAddressPhraseWheel(app.frame, -1)
1154 app.frame.Show(True)
1155 app.MainLoop()
1156
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170 test_address_prw()
1171
1172
1173