| Home | Trees | Indices | Help |
|
|---|
|
|
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 # stdlib
7 import logging, sys
8
9
10 # 3rd party
11 import wx
12
13
14 # GNUmed
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 # country related widgets / functions
32 #============================================================
34
35 if parent is None:
36 parent = wx.GetApp().GetTopWindow()
37
38 countries = gmDemographicRecord.get_countries()
39
40 gmCfgWidgets.configure_string_from_list_option (
41 parent = parent,
42 message = _('Select the default country for new persons.\n'),
43 option = 'person.create.default_country',
44 bias = 'user',
45 choices = [ (c['l10n_country'], c['code']) for c in countries ],
46 columns = [_('Country'), _('Code')],
47 data = [ c['code'] for c in countries ]
48 )
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 # province/state related widgets / functions
154 #============================================================
156
157 if parent is None:
158 parent = wx.GetApp().GetTopWindow()
159
160 provs = gmDemographicRecord.get_provinces()
161
162 gmCfgWidgets.configure_string_from_list_option (
163 parent = parent,
164 message = _('Select the default region/province/state/territory for new persons.\n'),
165 option = 'person.create.default_region',
166 bias = 'user',
167 choices = [ (p['l10n_country'], p['l10n_state'], p['code_state']) for p in provs ],
168 columns = [_('Country'), _('Region'), _('Code')],
169 data = [ p['state'] for p in provs ]
170 )
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 #edit_callback = edit,
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
364
366
367 try:
368 data = kwargs['province']
369 del kwargs['province']
370 except KeyError:
371 data = None
372
373 wxgProvinceEAPnl.wxgProvinceEAPnl.__init__(self, *args, **kwargs)
374 gmEditArea.cGenericEditAreaMixin.__init__(self)
375
376 self.mode = 'new'
377 self.data = data
378 if data is not None:
379 self.mode = 'edit'
380
381 self.__init_ui()
382 #----------------------------------------------------------------
385 #----------------------------------------------------------------
386 # generic Edit Area mixin API
387 #----------------------------------------------------------------
389
390 validity = True
391
392 if self._PRW_province.GetData() is None:
393 if self._PRW_province.GetValue().strip() == u'':
394 validity = False
395 self._PRW_province.display_as_valid(False)
396 else:
397 self._PRW_province.display_as_valid(True)
398 else:
399 self._PRW_province.display_as_valid(True)
400
401 if self._PRW_province.GetData() is None:
402 if self._TCTRL_code.GetValue().strip() == u'':
403 validity = False
404 self._TCTRL_code.SetBackgroundColour(gmPhraseWheel.color_prw_invalid)
405 else:
406 self._TCTRL_code.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
407
408 if self._PRW_country.GetData() is None:
409 validity = False
410 self._PRW_country.display_as_valid(False)
411 else:
412 self._PRW_country.display_as_valid(True)
413
414 return validity
415 #----------------------------------------------------------------
417 gmDemographicRecord.create_province (
418 name = self._PRW_province.GetValue().strip(),
419 code = self._TCTRL_code.GetValue().strip(),
420 country = self._PRW_country.GetData()
421 )
422
423 # EA is refreshed automatically after save, so need this ...
424 self.data = {
425 'l10n_state' : self._PRW_province.GetValue().strip(),
426 'code_state' : self._TCTRL_code.GetValue().strip(),
427 'l10n_country' : self._PRW_country.GetValue().strip(),
428 'code_country' : self._PRW_country.GetData().strip()
429 }
430
431 return True
432 #----------------------------------------------------------------
434 # update self.data and save the changes
435 #self.data[''] =
436 #self.data[''] =
437 #self.data[''] =
438 #self.data.save()
439
440 # do nothing for now (IOW, don't support updates)
441 return True
442 #----------------------------------------------------------------
444 self._PRW_province.SetText()
445 self._TCTRL_code.SetValue(u'')
446 self._PRW_country.SetText()
447
448 self._PRW_province.SetFocus()
449 #----------------------------------------------------------------
451 self._PRW_province.SetText(self.data['l10n_state'], self.data['code_state'])
452 self._TCTRL_code.SetValue(self.data['code_state'])
453 self._PRW_country.SetText(self.data['l10n_country'], self.data['code_country'])
454
455 self._PRW_province.SetFocus()
456 #----------------------------------------------------------------
463
464 #============================================================
465 # other address parts phrasewheels and widgets
466 #============================================================
468
470 # FIXME: add possible context
471 query = u"""(
472 SELECT DISTINCT ON (list_label)
473 postcode AS data,
474 postcode || ' (' || name || ')' AS list_label,
475 postcode AS field_label
476 FROM dem.street
477 WHERE
478 postcode %(fragment_condition)s
479 ORDER BY list_label
480 LIMIT 20
481
482 ) UNION (
483
484 SELECT DISTINCT ON (list_label)
485 postcode AS data,
486 postcode || ' (' || name || ')' AS list_label,
487 postcode AS field_label
488 FROM dem.urb
489 WHERE
490 postcode %(fragment_condition)s
491 ORDER BY list_label
492 LIMIT 20
493 )"""
494 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
495 mp.setThresholds(2, 3, 15)
496 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
497 self.SetToolTipString(_("Type or select a zip code (postcode).\n\nUse e.g. '?' if unknown."))
498 self.matcher = mp
499 #============================================================
501
503 context = {
504 u'ctxt_zip': {
505 u'where_part': u'AND zip ILIKE %(zip)s',
506 u'placeholder': u'zip'
507 }
508 }
509 query = u"""
510 SELECT
511 data,
512 field_label,
513 list_label
514 FROM (
515
516 SELECT DISTINCT ON (data)
517 street AS data,
518 street AS field_label,
519 street || ' (' || zip || ', ' || urb || coalesce(', ' || suburb, '') || ', ' || l10n_country || ')' AS list_label,
520 1 AS rank
521 FROM dem.v_zip2data
522 WHERE
523 street %(fragment_condition)s
524 %(ctxt_zip)s
525
526 UNION ALL
527
528 SELECT DISTINCT ON (data)
529 name AS data,
530 name AS field_label,
531 name || ' (' || postcode || coalesce(', ' || suburb, '') || ')' AS list_label,
532 2 AS rank
533 FROM dem.street
534 WHERE
535 name %(fragment_condition)s
536
537 ) AS matching_streets
538 ORDER BY rank, field_label
539 LIMIT 50"""
540 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
541 mp.setThresholds(3, 5, 8)
542 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
543 self.unset_context(context = u'zip')
544
545 self.SetToolTipString(_('Type or select a street.'))
546 self.capitalisation_mode = gmTools.CAPS_FIRST
547 self.matcher = mp
548 #============================================================
550
552
553 query = """
554 SELECT DISTINCT ON (suburb) suburb, suburb
555 FROM dem.street
556 WHERE suburb %(fragment_condition)s
557 ORDER BY suburb
558 LIMIT 50
559 """
560 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
561 mp.setThresholds(2, 3, 6)
562 gmPhraseWheel.cPhraseWheel.__init__ (
563 self,
564 *args,
565 **kwargs
566 )
567
568 self.SetToolTipString(_('Type or select the suburb.'))
569 self.capitalisation_mode = gmTools.CAPS_FIRST
570 self.matcher = mp
571 #============================================================
573
575 context = {
576 u'ctxt_zip': {
577 u'where_part': u'and zip ilike %(zip)s',
578 u'placeholder': u'zip'
579 }
580 }
581 query = u"""
582 SELECT DISTINCT ON (rank, data)
583 data,
584 field_label,
585 list_label
586 FROM (
587
588 SELECT
589 urb AS data,
590 urb AS field_label,
591 urb || ' (' || zip || ', ' || state || ', ' || l10n_country || ')' AS list_label,
592 1 AS rank
593 FROM dem.v_zip2data
594 WHERE
595 urb %(fragment_condition)s
596 %(ctxt_zip)s
597
598 UNION ALL
599
600 SELECT
601 name AS data,
602 name AS field_label,
603 name || ' (' || postcode ||')' AS list_label,
604 2 AS rank
605 FROM dem.urb
606 WHERE
607 name %(fragment_condition)s
608
609 ) AS matching_urbs
610 ORDER BY rank, data
611 LIMIT 50"""
612 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
613 mp.setThresholds(3, 5, 7)
614 gmPhraseWheel.cPhraseWheel.__init__ (
615 self,
616 *args,
617 **kwargs
618 )
619 self.unset_context(context = u'zip')
620
621 self.SetToolTipString(_('Type or select a city/town/village/dwelling.'))
622 self.capitalisation_mode = gmTools.CAPS_FIRST
623 self.matcher = mp
624 #============================================================
625 # address type related widgets
626 #============================================================
628
630
631 query = u"""
632 SELECT id, type FROM ((
633 SELECT id, _(name) AS type, 1 AS rank
634 FROM dem.address_type
635 WHERE _(name) %(fragment_condition)s
636 ) UNION (
637 SELECT id, name AS type, 2 AS rank
638 FROM dem.address_type
639 WHERE name %(fragment_condition)s
640 )) AS ur
641 order by
642 ur.rank, ur.type
643 """
644 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
645 mp.setThresholds(1, 2, 4)
646 mp.word_separators = u'[ \t]+'
647 gmPhraseWheel.cPhraseWheel.__init__ (
648 self,
649 *args,
650 **kwargs
651 )
652 self.matcher = mp
653 self.SetToolTipString(_('Select the type of address.'))
654 # self.capitalisation_mode = gmTools.CAPS_FIRST
655 self.selection_only = True
656 #--------------------------------------------------------
657 # def GetData(self, can_create=False):
658 # if self.data is None:
659 # if can_create:
660 # self.data = gmDocuments.create_document_type(self.GetValue().strip())['pk_doc_type'] # FIXME: error handling
661 # return self.data
662
663 #============================================================
664 # address phrasewheels and widgets
665 #============================================================
667
668 if parent is None:
669 parent = wx.GetApp().GetTopWindow()
670
671 #------------------------------------------------------------
672 def calculate_tooltip(address):
673 return u'\n'.join(address.format())
674 #------------------------------------------------------------
675 def delete(address):
676 return gmDemographicRecord.delete_address(pk_address = address['pk_address'])
677 #------------------------------------------------------------
678 def refresh(lctrl):
679 adrs = gmDemographicRecord.get_addresses(order_by = u'l10n_country, urb, street, number, subunit')
680 items = [ [
681 a['street'],
682 gmTools.coalesce(a['notes_street'], u''),
683 a['number'],
684 gmTools.coalesce(a['subunit'], u''),
685 a['postcode'],
686 a['urb'],
687 gmTools.coalesce(a['suburb'], u''),
688 a['l10n_state'],
689 a['l10n_country'],
690 gmTools.coalesce(a['notes_subunit'], u'')
691 ] for a in adrs
692 ]
693 lctrl.set_string_items(items)
694 lctrl.set_data(adrs)
695
696 #------------------------------------------------------------
697 cols = [
698 _('Street'),
699 _('Street info'),
700 _('Number'),
701 _('Subunit'),
702 _('Postal code'),
703 _('Community'),
704 _('Suburb'),
705 _('Region'),
706 _('Country'),
707 _('Comment')
708 ]
709 return gmListWidgets.get_choices_from_list (
710 parent = parent,
711 caption = _('Showing addresses registered in GNUmed.'),
712 columns = cols,
713 single_selection = True,
714 refresh_callback = refresh,
715 delete_callback = delete,
716 list_tooltip_callback = calculate_tooltip
717 )
718
719 #============================================================
720 from Gnumed.wxGladeWidgets import wxgGenericAddressEditAreaPnl
721
722 -class cAddressEAPnl(wxgGenericAddressEditAreaPnl.wxgGenericAddressEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
723
725
726 try:
727 data = kwargs['address']
728 del kwargs['address']
729 except KeyError:
730 data = None
731
732 self.address_holder = None
733 self.__type_is_editable = True
734 self.__address_is_searchable = False
735
736 wxgGenericAddressEditAreaPnl.wxgGenericAddressEditAreaPnl.__init__(self, *args, **kwargs)
737 gmEditArea.cGenericEditAreaMixin.__init__(self)
738
739 self.type_is_editable = True
740 self.address_is_searchable = False
741
742 # Code using this mixin should set mode and data
743 # after instantiating the class:
744 self.mode = 'new'
745 self.data = data
746 if data is not None:
747 self.mode = 'edit'
748
749 self.__init_ui()
750 #----------------------------------------------------------------
752 self._PRW_zip.add_callback_on_lose_focus(self._on_zip_set)
753 self._PRW_country.add_callback_on_lose_focus(self._on_country_set)
754 #----------------------------------------------------------------
755 # generic Edit Area mixin API
756 #----------------------------------------------------------------
758
759 validity = True
760
761 # if any field is filled, all must be filled, so track that
762 is_any_field_filled = False
763
764 # check by string
765 required_fields = [
766 self._PRW_urb,
767 self._TCTRL_number,
768 self._PRW_street,
769 self._PRW_zip
770 ]
771 if self.__type_is_editable:
772 required_fields.insert(0, self._PRW_type)
773 for field in required_fields:
774 if len(field.GetValue().strip()) == 0:
775 if is_any_field_filled:
776 self.display_ctrl_as_valid(field, False)
777 field.SetFocus()
778 gmGuiHelpers.gm_show_error (
779 _('Address details must be filled in completely or not at all.'),
780 _('Saving contact data')
781 )
782 validity = False
783 else:
784 is_any_field_filled = True
785 self.display_ctrl_as_valid(field, True)
786
787 # check by data
788 required_fields = (
789 self._PRW_country,
790 self._PRW_state
791 )
792 for field in required_fields:
793 if field.GetData() is None:
794 if is_any_field_filled:
795 self.display_ctrl_as_valid(field, False)
796 field.SetFocus()
797 gmGuiHelpers.gm_show_error (
798 _('Address details must be filled in completely or not at all.'),
799 _('Saving contact data')
800 )
801 validity = False
802 else:
803 is_any_field_filled = True
804 self.display_ctrl_as_valid(field, True)
805
806 return validity
807 #----------------------------------------------------------------
809 try:
810 # will create or return address
811 address = gmDemographicRecord.create_address (
812 country = self._PRW_country.GetData(),
813 state = self._PRW_state.GetData(),
814 urb = self._PRW_urb.GetValue().strip(),
815 suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), u''),
816 postcode = self._PRW_zip.GetValue().strip(),
817 street = self._PRW_street.GetValue().strip(),
818 number = self._TCTRL_number.GetValue().strip(),
819 subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), u'')
820 )
821 except:
822 _log.exception('cannot save address')
823 gmGuiHelpers.gm_show_error (
824 _('Cannot save address.\n\n'
825 'Does the state [%s]\n'
826 'exist in country [%s] ?'
827 ) % (
828 self._PRW_state.GetValue().strip(),
829 self._PRW_country.GetValue().strip()
830 ),
831 _('Saving address')
832 )
833 return False
834
835 # link address to holder (there better be one)
836 linked_address = self.address_holder.link_address(id_type = self._PRW_type.GetData(), address = address)
837 if linked_address['pk_address'] != address['pk_address']:
838 raise ValueError('problem linking address to person or org')
839
840 address['notes_street'] = gmTools.none_if(self._TCTRL_notes_street.GetValue().strip(), u'')
841 address['notes_subunit'] = gmTools.none_if(self._TCTRL_notes_subunit.GetValue().strip(), u'')
842 address.save()
843
844 linked_address.refetch_payload()
845 self.data = linked_address
846
847 return True
848 #----------------------------------------------------------------
850 # do not update existing address, rather
851 # create new one or get corresponding
852 # address should it exist
853 try:
854 address = gmDemographicRecord.create_address (
855 country = self._PRW_country.GetData(),
856 state = self._PRW_state.GetData(),
857 urb = self._PRW_urb.GetValue().strip(),
858 suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), u''),
859 postcode = self._PRW_zip.GetValue().strip(),
860 street = self._PRW_street.GetValue().strip(),
861 number = self._TCTRL_number.GetValue().strip(),
862 subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), u'')
863 )
864 except:
865 _log.exception('cannot save address')
866 gmGuiHelpers.gm_show_error (
867 _('Cannot save address.\n\n'
868 'Does the state [%s]\n'
869 'exist in country [%s] ?'
870 ) % (
871 self._PRW_state.GetValue().strip(),
872 self._PRW_country.GetValue().strip()
873 ),
874 _('Saving address')
875 )
876 return False
877
878 # link address to holder (there better be one)
879 linked_address = self.address_holder.link_address(id_type = self._PRW_type.GetData(), address = address)
880 if linked_address['pk_address'] != address['pk_address']:
881 raise ValueError('problem linking address to person or org')
882
883 address['notes_street'] = gmTools.none_if(self._TCTRL_notes_street.GetValue().strip(), u'')
884 address['notes_subunit'] = gmTools.none_if(self._TCTRL_notes_subunit.GetValue().strip(), u'')
885 address.save()
886
887 linked_address.refetch_payload()
888 self.data = linked_address
889
890 return True
891 #----------------------------------------------------------------
893 self._PRW_type.SetText(u'', None)
894 self._PRW_zip.SetText(u'', None)
895 self._PRW_street.SetText(u'', None)
896 self._TCTRL_notes_street.SetValue(u'')
897 self._TCTRL_number.SetValue(u'')
898 self._TCTRL_subunit.SetValue(u'')
899 self._PRW_suburb.SetText(u'', None)
900 self._PRW_urb.SetText(u'', None)
901 self._PRW_state.SetText(u'', None)
902 self._PRW_country.SetText(u'', None)
903 self._TCTRL_notes_subunit.SetValue(u'')
904
905 if self.__type_is_editable:
906 self._PRW_type.SetFocus()
907 else:
908 self._PRW_zip.SetFocus()
909 #----------------------------------------------------------------
911 self._refresh_as_new()
912
913 self._PRW_zip.SetText(self.data['postcode'])
914 self._PRW_street.SetText(self.data['street'], data = self.data['street'])
915 self._PRW_suburb.SetText(gmTools.coalesce(self.data['suburb'], ''))
916 self._PRW_urb.SetText(self.data['urb'], data = self.data['urb'])
917 self._PRW_state.SetText(self.data['l10n_state'], data = self.data['code_state'])
918 self._PRW_country.SetText(self.data['l10n_country'], data = self.data['code_country'])
919
920 if self.__type_is_editable:
921 self._PRW_type.SetFocus()
922 else:
923 self._TCTRL_number.SetFocus()
924 #----------------------------------------------------------------
926 if self.__type_is_editable:
927 self._PRW_type.SetText(self.data['l10n_address_type'])
928 else:
929 self._PRW_type.SetText(u'', None)
930 self._PRW_zip.SetText(self.data['postcode'])
931 self._PRW_street.SetText(self.data['street'], data = self.data['street'])
932 self._TCTRL_notes_street.SetValue(gmTools.coalesce(self.data['notes_street'], ''))
933 self._TCTRL_number.SetValue(self.data['number'])
934 self._TCTRL_subunit.SetValue(gmTools.coalesce(self.data['subunit'], ''))
935 self._PRW_suburb.SetText(gmTools.coalesce(self.data['suburb'], ''))
936 self._PRW_urb.SetText(self.data['urb'], data = self.data['urb'])
937 self._PRW_state.SetText(self.data['l10n_state'], data = self.data['code_state'])
938 self._PRW_country.SetText(self.data['l10n_country'], data = self.data['code_country'])
939 self._TCTRL_notes_subunit.SetValue(gmTools.coalesce(self.data['notes_subunit'], ''))
940
941 if self.__type_is_editable:
942 self._PRW_type.SetFocus()
943 else:
944 self._PRW_zip.SetFocus()
945 #----------------------------------------------------------------
946 # event handling
947 #----------------------------------------------------------------
949 """Set the street, town, state and country according to entered zip code."""
950 zip_code = self._PRW_zip.GetValue()
951 if zip_code.strip() == u'':
952 self._PRW_street.unset_context(context = u'zip')
953 self._PRW_urb.unset_context(context = u'zip')
954 self._PRW_state.unset_context(context = u'zip')
955 self._PRW_country.unset_context(context = u'zip')
956 else:
957 self._PRW_street.set_context(context = u'zip', val = zip_code)
958 self._PRW_urb.set_context(context = u'zip', val = zip_code)
959 self._PRW_state.set_context(context = u'zip', val = zip_code)
960 self._PRW_country.set_context(context = u'zip', val = zip_code)
961 #----------------------------------------------------------------
963 """Set the states according to entered country."""
964 country = self._PRW_country.GetData()
965 if country is None:
966 self._PRW_state.unset_context(context = 'country')
967 else:
968 self._PRW_state.set_context(context = 'country', val = country)
969 #----------------------------------------------------------------
970 # properties
971 #----------------------------------------------------------------
974
976 self.__type_is_editable = type_is_editable
977 self._PRW_type.Enable(type_is_editable)
978 self._PRW_type.Show(type_is_editable)
979 self._LBL_type.Show(type_is_editable)
980
981 type_is_editable = property(_get_type_is_editable, _set_type_is_editable)
982 #----------------------------------------------------------------
985
987 # FIXME: always set to FALSE when self.mode == 'new' ?
988 self.__address_is_searchable = address_is_searchable
989 self._PRW_address_searcher.Enable(address_is_searchable)
990 self._PRW_address_searcher.Show(address_is_searchable)
991 self._LBL_search.Show(address_is_searchable)
992
993 address_is_searchable = property(_get_address_is_searchable, _set_address_is_searchable)
994 #----------------------------------------------------------------
996 return self.data
997
1000
1001 address = property(_get_address, _set_address)
1002
1003 #============================================================
1005
1007
1008 query = u"""
1009 SELECT * FROM (
1010 (SELECT
1011 pk_address AS data,
1012 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1013 || urb || coalesce(' (' || suburb || ')', '') || ', '
1014 || postcode || ', '
1015 || code_country
1016 ) AS field_label,
1017 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1018 || urb || coalesce(' (' || suburb || ')', '') || ', '
1019 || postcode || ', '
1020 || l10n_state || ', '
1021 || l10n_country
1022 || coalesce(', ' || notes_street, '')
1023 || coalesce(', ' || notes_subunit, '')
1024 ) AS list_label
1025 FROM
1026 dem.v_address
1027 WHERE
1028 street %(fragment_condition)s
1029
1030 ) UNION (
1031
1032 SELECT
1033 pk_address AS data,
1034 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1035 || urb || coalesce(' (' || suburb || ')', '') || ', '
1036 || postcode || ', '
1037 || code_country
1038 ) AS field_label,
1039 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1040 || urb || coalesce(' (' || suburb || ')', '') || ', '
1041 || postcode || ', '
1042 || l10n_state || ', '
1043 || l10n_country
1044 || coalesce(', ' || notes_street, '')
1045 || coalesce(', ' || notes_subunit, '')
1046 ) AS list_label
1047 FROM
1048 dem.v_address
1049 WHERE
1050 postcode_street %(fragment_condition)s
1051
1052 ) UNION (
1053
1054 SELECT
1055 pk_address AS data,
1056 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1057 || urb || coalesce(' (' || suburb || ')', '') || ', '
1058 || postcode || ', '
1059 || code_country
1060 ) AS field_label,
1061 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1062 || urb || coalesce(' (' || suburb || ')', '') || ', '
1063 || postcode || ', '
1064 || l10n_state || ', '
1065 || l10n_country
1066 || coalesce(', ' || notes_street, '')
1067 || coalesce(', ' || notes_subunit, '')
1068 ) AS list_label
1069 FROM
1070 dem.v_address
1071 WHERE
1072 postcode_urb %(fragment_condition)s
1073 )
1074 ) AS matching_addresses
1075 ORDER BY list_label
1076 LIMIT 50"""
1077
1078 gmMatchProvider.cMatchProvider_SQL2.__init__(self, queries = query)
1079
1080 self.setThresholds(2, 4, 6)
1081 # self.word_separators = u'[ \t]+'
1082
1083 self._SQL_data2match = u"""
1084 SELECT
1085 pk_address AS data,
1086 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1087 || urb || coalesce(' (' || suburb || ')', '') || ', '
1088 || postcode || ', '
1089 || code_country
1090 ) AS field_label,
1091 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1092 || urb || coalesce(' (' || suburb || ')', '') || ', '
1093 || postcode || ', '
1094 || l10n_state || ', '
1095 || l10n_country
1096 || coalesce(', ' || notes_street, '')
1097 || coalesce(', ' || notes_subunit, '')
1098 ) AS list_label
1099 FROM
1100 dem.v_address
1101 WHERE
1102 pk_address = %(pk)s
1103 """
1104
1105 #============================================================
1107
1109
1110 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
1111 self.matcher = cAddressMatchProvider()
1112 self.SetToolTipString(_('Select an address by postcode or street name.'))
1113 self.selection_only = True
1114 self.__address = None
1115 self.__old_pk = None
1116 #--------------------------------------------------------
1122 #--------------------------------------------------------
1125 #--------------------------------------------------------
1126 # properties
1127 #--------------------------------------------------------
1129 pk = self.GetData()
1130 if pk is None:
1131 self.__address = None
1132 return None
1133 if self.__address is None:
1134 self.__old_pk = pk
1135 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
1136 else:
1137 if pk != self.__old_pk:
1138 self.__old_pk = pk
1139 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
1140 return self.__address
1141
1143 if address is None:
1144 self.__old_pk = None
1145 self.__address = None
1146 self.SetText(u'', None)
1147 return
1148 if isinstance(address, gmDemographicRecord.cAddress):
1149 self.__old_pk = address['pk_address']
1150 self.__address = address
1151 pk = self.__old_pk
1152 else:
1153 self.__old_pk = None
1154 self.__address = None
1155 pk = address
1156 match = self.matcher.get_match_by_data(data = pk)
1157 if match is None:
1158 raise ValueError(u'[%s]: cannot match address [#%s]' % (self.__class__.__name__, pk))
1159 self.SetText(match['field_label'], pk)
1160
1161 address = property(__get_address, __set_address)
1162 #--------------------------------------------------------
1164 pk = self.GetData()
1165 if pk is None:
1166 self.__address = None
1167 return None
1168 if self.__address is None:
1169 self.__old_pk = pk
1170 self.__address = gmDemographicRecord.cPatientAddress(aPK_obj = pk)
1171 else:
1172 if pk != self.__old_pk:
1173 self.__old_pk = pk
1174 self.__address = gmDemographicRecord.cPatientAddress(aPK_obj = pk)
1175 return self.__address
1176
1177 person_address = property(__get_person_address, lambda x:x)
1178 #================================================================
1179 # main
1180 #----------------------------------------------------------------
1181 if __name__ == '__main__':
1182
1183 if len(sys.argv) < 2:
1184 sys.exit()
1185
1186 if sys.argv[1] != 'test':
1187 sys.exit()
1188
1189 from Gnumed.pycommon import gmI18N
1190 gmI18N.activate_locale()
1191 gmI18N.install_domain()
1192 from Gnumed.business import gmPersonSearch
1193
1194 #--------------------------------------------------------
1196 app = wx.PyWidgetTester(size = (200, 50))
1197 pw = cCountryPhraseWheel(app.frame, -1)
1198 app.frame.Show(True)
1199 app.MainLoop()
1200 #--------------------------------------------------------
1202 app = wx.PyWidgetTester(size = (200, 50))
1203 pw = cStateSelectionPhraseWheel(app.frame, -1)
1204 pw.set_context(context = u'zip', val = u'04318')
1205 pw.set_context(context = u'country', val = u'Deutschland')
1206 app.frame.Show(True)
1207 app.MainLoop()
1208 #--------------------------------------------------------
1210 app = wx.PyWidgetTester(size = (200, 50))
1211 pw = cZipcodePhraseWheel(app.frame, -1)
1212 app.frame.Show(True)
1213 app.MainLoop()
1214 #--------------------------------------------------------
1216 app = wx.PyWidgetTester(size = (200, 50))
1217 pw = cStreetPhraseWheel(app.frame, -1)
1218 # pw.set_context(context = u'zip', val = u'04318')
1219 app.frame.Show(True)
1220 app.MainLoop()
1221 #--------------------------------------------------------
1223 app = wx.PyWidgetTester(size = (200, 50))
1224 pw = cSuburbPhraseWheel(app.frame, -1)
1225 app.frame.Show(True)
1226 app.MainLoop()
1227 #--------------------------------------------------------
1229 app = wx.PyWidgetTester(size = (200, 50))
1230 pw = cUrbPhraseWheel(app.frame, -1)
1231 app.frame.Show(True)
1232 pw.set_context(context = u'zip', val = u'04317')
1233 app.MainLoop()
1234 #--------------------------------------------------------
1236 app = wx.PyWidgetTester(size = (200, 50))
1237 pw = cAddressTypePhraseWheel(app.frame, -1)
1238 app.frame.Show(True)
1239 app.MainLoop()
1240 #--------------------------------------------------------
1242 app = wx.PyWidgetTester(size = (200, 50))
1243 pw = cAddressPhraseWheel(app.frame, -1)
1244 app.frame.Show(True)
1245 app.MainLoop()
1246 #--------------------------------------------------------
1248 app = wx.PyWidgetTester(size = (600, 400))
1249 app.SetWidget(cAddressEditAreaPnl, address = gmDemographicRecord.cAddress(aPK_obj = 1))
1250 app.MainLoop()
1251 #--------------------------------------------------------
1252 #test_address_type_prw()
1253 #test_zipcode_prw()
1254 #test_state_prw()
1255 #test_street_prw()
1256 #test_suburb_prw()
1257 #test_country_prw()
1258 #test_urb_prw()
1259 #test_address_ea_pnl()
1260 test_address_prw()
1261
1262 #================================================================
1263
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Oct 5 03:57:33 2013 | http://epydoc.sourceforge.net |