| 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 'ctxt_zip': {
58 'where_part': 'and zip ilike %(zip)s',
59 'placeholder': 'zip'
60 }
61 }
62 query = """
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 = """
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 = 'zip')
148 self.SetToolTip(_('Type or select a country.'))
149 self.capitalisation_mode = gmTools.CAPS_FIRST
150 self.selection_only = True
151
152 #============================================================
153 # region related widgets / functions
154 #============================================================
156
157 if parent is None:
158 parent = wx.GetApp().GetTopWindow()
159
160 regs = gmDemographicRecord.get_regions()
161
162 gmCfgWidgets.configure_string_from_list_option (
163 parent = parent,
164 message = _('Select the default region (state/province/county/territory/arrondissement/prefecture/department/kanton/...) for new persons.\n'),
165 option = 'person.create.default_region',
166 bias = 'user',
167 choices = [ (r['l10n_country'], r['l10n_region'], r['code_region']) for r in regs ],
168 columns = [_('Country'), _('Region'), _('Code')],
169 data = [ r['region'] for r in regs ]
170 )
171 #============================================================
173 ea = cProvinceEAPnl(parent, -1, region = region)
174 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = (region is not None))
175 dlg.SetTitle(gmTools.coalesce(region, _('Adding region'), _('Editing region')))
176 result = dlg.ShowModal()
177 dlg.DestroyLater()
178 return (result == wx.ID_OK)
179 #============================================================
181
182 msg = _(
183 'Are you sure you want to delete this region ?\n'
184 '\n'
185 'Deletion will only work if this region 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 region'),
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 region 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.DestroyLater()
212 return False
213
214 include_urbs = dlg.checkbox_is_checked()
215 dlg.DestroyLater()
216
217 return gmDemographicRecord.delete_region(region = region, delete_urbs = include_urbs)
218 #============================================================
220
221 if parent is None:
222 parent = wx.GetApp().GetTopWindow()
223
224 #------------------------------------------------------------
225 def delete(region=None):
226 return delete_region(parent = parent, region = region['pk_region'])
227 #------------------------------------------------------------
228 def edit(region=None):
229 return edit_region(parent = parent, region = region)
230 #------------------------------------------------------------
231 def refresh(lctrl):
232 wx.BeginBusyCursor()
233 provinces = gmDemographicRecord.get_regions()
234 lctrl.set_string_items([ (p['l10n_country'], p['l10n_region']) for p in provinces ])
235 lctrl.set_data(provinces)
236 wx.EndBusyCursor()
237 #------------------------------------------------------------
238 msg = _(
239 'This list shows the regions known to GNUmed.\n'
240 '\n'
241 'In your jurisdiction "region" may correspond to either of "state",\n'
242 '"county", "province", "territory", "arrondissement", "department,"\n'
243 '"prefecture", "kanton", or some such term.\n'
244 )
245
246 gmListWidgets.get_choices_from_list (
247 parent = parent,
248 msg = msg,
249 caption = _('Editing regions ...'),
250 columns = [_('Country'), _('Region')],
251 single_selection = True,
252 new_callback = edit,
253 #edit_callback = edit,
254 delete_callback = delete,
255 refresh_callback = refresh
256 )
257 #============================================================
259
261
262 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
263
264 context = {
265 'ctxt_country_name': {
266 'where_part': 'AND l10n_country ILIKE %(country_name)s OR country ILIKE %(country_name)s',
267 'placeholder': 'country_name'
268 },
269 'ctxt_zip': {
270 'where_part': 'AND zip ilike %(zip)s',
271 'placeholder': 'zip'
272 },
273 'ctxt_country_code': {
274 'where_part': 'AND country IN (SELECT code FROM dem.country WHERE _(name) ILIKE %(country_name)s OR name ILIKE %(country_name)s)',
275 'placeholder': 'country_name'
276 }
277 }
278
279 query = """
280 SELECT
281 data,
282 field_label,
283 list_label
284 FROM (
285 SELECT DISTINCT ON (field_label)
286 data,
287 field_label,
288 list_label,
289 rank
290 FROM (
291 -- 1: find regions based on name, context: zip and country name
292 SELECT
293 code_region AS data,
294 region AS field_label,
295 region || ' (' || code_region || '), ' || l10n_country || ' (' || code_country || ')' AS list_label,
296 1 AS rank
297 FROM dem.v_zip2data
298 WHERE
299 region %(fragment_condition)s
300 %(ctxt_country_name)s
301 %(ctxt_zip)s
302
303 UNION ALL
304
305 -- 2: find regions based on code, context: zip and country name
306 SELECT
307 code_region AS data,
308 region AS field_label,
309 code_region || ': ' || region || ' (' || l10n_country || ', ' || code_country || ')' AS list_label,
310 2 AS rank
311 FROM dem.v_zip2data
312 WHERE
313 code_region %(fragment_condition)s
314 %(ctxt_country_name)s
315 %(ctxt_zip)s
316
317 UNION ALL
318
319 -- 3: find regions based on name, context: country
320 SELECT
321 code AS data,
322 name AS field_label,
323 name || ' (' || code || '), ' || country AS list_label,
324 3 AS rank
325 FROM dem.region
326 WHERE
327 name %(fragment_condition)s
328 %(ctxt_country_code)s
329
330 UNION ALL
331
332 -- 4: find regions based on code, context: country
333 SELECT
334 code AS data,
335 name AS field_label,
336 code || ': ' || name || ', ' || country AS list_label,
337 3 AS rank
338 FROM dem.region
339 WHERE
340 code %(fragment_condition)s
341 %(ctxt_country_code)s
342
343 ) AS candidate_regions
344 ) AS distinct_matches
345 ORDER BY rank, list_label
346 LIMIT 50"""
347
348 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
349 mp.setThresholds(2, 5, 6)
350 mp.word_separators = '[ \t]+'
351 self.matcher = mp
352
353 self.unset_context(context = 'zip')
354 self.unset_context(context = 'country_name')
355 self.SetToolTip(_('Type or select a region (state/province/county/territory/arrondissement/prefecture/department/kanton/...).'))
356 self.capitalisation_mode = gmTools.CAPS_FIRST
357 self.selection_only = True
358 #====================================================================
359 from Gnumed.wxGladeWidgets import wxgProvinceEAPnl
360
362
364
365 try:
366 data = kwargs['region']
367 del kwargs['region']
368 except KeyError:
369 data = None
370
371 wxgProvinceEAPnl.wxgProvinceEAPnl.__init__(self, *args, **kwargs)
372 gmEditArea.cGenericEditAreaMixin.__init__(self)
373
374 self.mode = 'new'
375 self.data = data
376 if data is not None:
377 self.mode = 'edit'
378
379 self.__init_ui()
380 #----------------------------------------------------------------
383 #----------------------------------------------------------------
384 # generic Edit Area mixin API
385 #----------------------------------------------------------------
387
388 validity = True
389
390 if self._PRW_region.GetData() is None:
391 if self._PRW_region.GetValue().strip() == '':
392 validity = False
393 self._PRW_region.display_as_valid(False)
394 else:
395 self._PRW_region.display_as_valid(True)
396 else:
397 self._PRW_region.display_as_valid(True)
398
399 if self._PRW_region.GetData() is None:
400 if self._TCTRL_code.GetValue().strip() == '':
401 validity = False
402 self._TCTRL_code.SetBackgroundColour(gmPhraseWheel.color_prw_invalid)
403 else:
404 self._TCTRL_code.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
405
406 if self._PRW_country.GetData() is None:
407 validity = False
408 self._PRW_country.display_as_valid(False)
409 else:
410 self._PRW_country.display_as_valid(True)
411
412 return validity
413 #----------------------------------------------------------------
415 gmDemographicRecord.create_region (
416 name = self._PRW_region.GetValue().strip(),
417 code = self._TCTRL_code.GetValue().strip(),
418 country = self._PRW_country.GetData()
419 )
420
421 # EA is refreshed automatically after save, so need this ...
422 self.data = {
423 'l10n_region' : self._PRW_region.GetValue().strip(),
424 'code_region' : self._TCTRL_code.GetValue().strip(),
425 'l10n_country' : self._PRW_country.GetValue().strip(),
426 'code_country' : self._PRW_country.GetData().strip()
427 }
428
429 return True
430 #----------------------------------------------------------------
432 # update self.data and save the changes
433 #self.data[''] =
434 #self.data[''] =
435 #self.data[''] =
436 #self.data.save()
437
438 # do nothing for now (IOW, don't support updates)
439 return True
440 #----------------------------------------------------------------
442 self._PRW_region.SetText()
443 self._TCTRL_code.SetValue('')
444 self._PRW_country.SetText()
445
446 self._PRW_region.SetFocus()
447 #----------------------------------------------------------------
449 self._PRW_region.SetText(self.data['l10n_region'], self.data['code_region'])
450 self._TCTRL_code.SetValue(self.data['code_region'])
451 self._PRW_country.SetText(self.data['l10n_country'], self.data['code_country'])
452
453 self._PRW_region.SetFocus()
454 #----------------------------------------------------------------
461
462 #============================================================
463 # other address parts phrasewheels and widgets
464 #============================================================
466
468 # FIXME: add possible context
469 query = """(
470 SELECT DISTINCT ON (list_label)
471 postcode AS data,
472 postcode || ' (' || name || ')' AS list_label,
473 postcode AS field_label
474 FROM dem.street
475 WHERE
476 postcode %(fragment_condition)s
477 ORDER BY list_label
478 LIMIT 20
479
480 ) UNION (
481
482 SELECT DISTINCT ON (list_label)
483 postcode AS data,
484 postcode || ' (' || name || ')' AS list_label,
485 postcode AS field_label
486 FROM dem.urb
487 WHERE
488 postcode %(fragment_condition)s
489 ORDER BY list_label
490 LIMIT 20
491 )"""
492 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
493 mp.setThresholds(2, 3, 15)
494 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
495 self.SetToolTip(_("Type or select a zip code (postcode).\n\nUse e.g. '?' if unknown."))
496 self.matcher = mp
497 #============================================================
499
501 context = {
502 'ctxt_zip': {
503 'where_part': 'AND zip ILIKE %(zip)s',
504 'placeholder': 'zip'
505 }
506 }
507 query = """
508 SELECT
509 data,
510 field_label,
511 list_label
512 FROM (
513
514 SELECT DISTINCT ON (data)
515 street AS data,
516 street AS field_label,
517 street || ' (' || zip || ', ' || urb || coalesce(', ' || suburb, '') || ', ' || l10n_country || ')' AS list_label,
518 1 AS rank
519 FROM dem.v_zip2data
520 WHERE
521 street %(fragment_condition)s
522 %(ctxt_zip)s
523
524 UNION ALL
525
526 SELECT DISTINCT ON (data)
527 name AS data,
528 name AS field_label,
529 name || ' (' || coalesce(postcode, '') || coalesce(', ' || suburb, '') || ')' AS list_label,
530 2 AS rank
531 FROM dem.street
532 WHERE
533 name %(fragment_condition)s
534
535 ) AS matching_streets
536 ORDER BY rank, field_label
537 LIMIT 50"""
538 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
539 mp.setThresholds(3, 5, 8)
540 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
541 self.unset_context(context = 'zip')
542
543 self.SetToolTip(_('Type or select a street.'))
544 self.capitalisation_mode = gmTools.CAPS_FIRST
545 self.matcher = mp
546 #============================================================
548
550
551 query = """
552 SELECT DISTINCT ON (suburb) suburb, suburb
553 FROM dem.street
554 WHERE suburb %(fragment_condition)s
555 ORDER BY suburb
556 LIMIT 50
557 """
558 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
559 mp.setThresholds(2, 3, 6)
560 gmPhraseWheel.cPhraseWheel.__init__ (
561 self,
562 *args,
563 **kwargs
564 )
565
566 self.SetToolTip(_('Type or select the suburb.'))
567 self.capitalisation_mode = gmTools.CAPS_FIRST
568 self.matcher = mp
569 #============================================================
571
573 context = {
574 'ctxt_zip': {
575 'where_part': 'and zip ilike %(zip)s',
576 'placeholder': 'zip'
577 }
578 }
579 query = """
580 SELECT DISTINCT ON (rank, data)
581 data,
582 field_label,
583 list_label
584 FROM (
585
586 SELECT
587 urb AS data,
588 urb AS field_label,
589 urb || ' (' || zip || ', ' || region || ', ' || l10n_country || ')' AS list_label,
590 1 AS rank
591 FROM dem.v_zip2data
592 WHERE
593 urb %(fragment_condition)s
594 %(ctxt_zip)s
595
596 UNION ALL
597
598 SELECT
599 name AS data,
600 name AS field_label,
601 name || ' (' || postcode ||')' AS list_label,
602 2 AS rank
603 FROM dem.urb
604 WHERE
605 name %(fragment_condition)s
606
607 ) AS matching_urbs
608 ORDER BY rank, data
609 LIMIT 50"""
610 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
611 mp.setThresholds(3, 5, 7)
612 gmPhraseWheel.cPhraseWheel.__init__ (
613 self,
614 *args,
615 **kwargs
616 )
617 self.unset_context(context = 'zip')
618
619 self.SetToolTip(_('Type or select a city/town/village/dwelling.'))
620 self.capitalisation_mode = gmTools.CAPS_FIRST
621 self.matcher = mp
622 #============================================================
623 # address type related widgets
624 #============================================================
626
628
629 query = """
630 SELECT id, type FROM ((
631 SELECT id, _(name) AS type, 1 AS rank
632 FROM dem.address_type
633 WHERE _(name) %(fragment_condition)s
634 ) UNION (
635 SELECT id, name AS type, 2 AS rank
636 FROM dem.address_type
637 WHERE name %(fragment_condition)s
638 )) AS ur
639 order by
640 ur.rank, ur.type
641 """
642 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
643 mp.setThresholds(1, 2, 4)
644 mp.word_separators = '[ \t]+'
645 gmPhraseWheel.cPhraseWheel.__init__ (
646 self,
647 *args,
648 **kwargs
649 )
650 self.matcher = mp
651 self.SetToolTip(_('Select the type of address.'))
652 # self.capitalisation_mode = gmTools.CAPS_FIRST
653 self.selection_only = True
654 #--------------------------------------------------------
655 # def GetData(self, can_create=False):
656 # if self.data is None:
657 # if can_create:
658 # self.data = gmDocuments.create_document_type(self.GetValue().strip())['pk_doc_type'] # FIXME: error handling
659 # return self.data
660
661 #============================================================
662 # address phrasewheels and widgets
663 #============================================================
665
666 if parent is None:
667 parent = wx.GetApp().GetTopWindow()
668
669 #------------------------------------------------------------
670 def calculate_tooltip(address):
671 return '\n'.join(address.format())
672 #------------------------------------------------------------
673 def delete(address):
674 return gmDemographicRecord.delete_address(pk_address = address['pk_address'])
675 #------------------------------------------------------------
676 def refresh(lctrl):
677 adrs = gmDemographicRecord.get_addresses(order_by = 'l10n_country, urb, street, number, subunit')
678 items = [ [
679 a['street'],
680 gmTools.coalesce(a['notes_street'], ''),
681 a['number'],
682 gmTools.coalesce(a['subunit'], ''),
683 a['postcode'],
684 a['urb'],
685 gmTools.coalesce(a['suburb'], ''),
686 a['l10n_region'],
687 a['l10n_country'],
688 gmTools.coalesce(a['notes_subunit'], '')
689 ] for a in adrs
690 ]
691 lctrl.set_string_items(items)
692 lctrl.set_data(adrs)
693
694 #------------------------------------------------------------
695 cols = [
696 _('Street'),
697 _('Street info'),
698 _('Number'),
699 _('Subunit'),
700 _('Postal code'),
701 _('Community'),
702 _('Suburb'),
703 _('Region'),
704 _('Country'),
705 _('Comment')
706 ]
707 return gmListWidgets.get_choices_from_list (
708 parent = parent,
709 caption = _('Showing addresses registered in GNUmed.'),
710 columns = cols,
711 single_selection = True,
712 refresh_callback = refresh,
713 delete_callback = delete,
714 list_tooltip_callback = calculate_tooltip
715 )
716
717 #============================================================
718 from Gnumed.wxGladeWidgets import wxgGenericAddressEditAreaPnl
719
720 -class cAddressEAPnl(wxgGenericAddressEditAreaPnl.wxgGenericAddressEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
721
723
724 try:
725 data = kwargs['address']
726 del kwargs['address']
727 except KeyError:
728 data = None
729
730 self.address_holder = None
731 self.__type_is_editable = True
732 self.__address_is_searchable = False
733
734 wxgGenericAddressEditAreaPnl.wxgGenericAddressEditAreaPnl.__init__(self, *args, **kwargs)
735 gmEditArea.cGenericEditAreaMixin.__init__(self)
736
737 self.type_is_editable = True
738 self.address_is_searchable = False
739
740 # Code using this mixin should set mode and data
741 # after instantiating the class:
742 self.mode = 'new'
743 self.data = data
744 if data is not None:
745 self.mode = 'edit'
746
747 self.__init_ui()
748 #----------------------------------------------------------------
750 self._PRW_zip.add_callback_on_lose_focus(self._on_zip_set)
751 self._PRW_country.add_callback_on_lose_focus(self._on_country_set)
752 #----------------------------------------------------------------
753 # generic Edit Area mixin API
754 #----------------------------------------------------------------
756
757 validity = True
758
759 # if any field is filled, all must be filled, so track that
760 is_any_field_filled = False
761
762 # check by string
763 required_fields = [
764 self._PRW_urb,
765 self._TCTRL_number,
766 self._PRW_street,
767 self._PRW_zip
768 ]
769 if self.__type_is_editable:
770 required_fields.insert(0, self._PRW_type)
771 for field in required_fields:
772 if len(field.GetValue().strip()) == 0:
773 if is_any_field_filled:
774 self.display_ctrl_as_valid(field, False)
775 field.SetFocus()
776 gmGuiHelpers.gm_show_error (
777 _('Address details must be filled in completely or not at all.'),
778 _('Saving contact data')
779 )
780 validity = False
781 else:
782 is_any_field_filled = True
783 self.display_ctrl_as_valid(field, True)
784
785 # check by data
786 required_fields = (
787 self._PRW_country,
788 self._PRW_state
789 )
790 for field in required_fields:
791 if field.GetData() is None:
792 if is_any_field_filled:
793 self.display_ctrl_as_valid(field, False)
794 field.SetFocus()
795 gmGuiHelpers.gm_show_error (
796 _('Address details must be filled in completely or not at all.'),
797 _('Saving contact data')
798 )
799 validity = False
800 else:
801 is_any_field_filled = True
802 self.display_ctrl_as_valid(field, True)
803
804 return validity
805 #----------------------------------------------------------------
807 try:
808 # will create or return address
809 address = gmDemographicRecord.create_address (
810 country_code = self._PRW_country.GetData(),
811 region_code = self._PRW_state.GetData(),
812 urb = self._PRW_urb.GetValue().strip(),
813 suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), ''),
814 postcode = self._PRW_zip.GetValue().strip(),
815 street = self._PRW_street.GetValue().strip(),
816 number = self._TCTRL_number.GetValue().strip(),
817 subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), '')
818 )
819 except Exception:
820 _log.exception('cannot save address')
821 gmGuiHelpers.gm_show_error (
822 _('Cannot save address.\n\n'
823 'Does the region [%s]\n'
824 'exist in country [%s] ?'
825 ) % (
826 self._PRW_state.GetValue().strip(),
827 self._PRW_country.GetValue().strip()
828 ),
829 _('Saving address')
830 )
831 return False
832
833 # link address to holder (there better be one)
834 linked_address = self.address_holder.link_address(id_type = self._PRW_type.GetData(), address = address)
835 if linked_address['pk_address'] != address['pk_address']:
836 raise ValueError('problem linking address to person or org')
837
838 address['notes_street'] = gmTools.none_if(self._TCTRL_notes_street.GetValue().strip(), '')
839 address['notes_subunit'] = gmTools.none_if(self._TCTRL_notes_subunit.GetValue().strip(), '')
840 address.save()
841
842 linked_address.refetch_payload()
843 self.data = linked_address
844
845 return True
846 #----------------------------------------------------------------
848 # do not update existing address, rather
849 # create new one or get corresponding
850 # address should it exist
851 try:
852 created_or_loaded_address = gmDemographicRecord.create_address (
853 country_code = self._PRW_country.GetData(),
854 region_code = self._PRW_state.GetData(),
855 urb = self._PRW_urb.GetValue().strip(),
856 suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), ''),
857 postcode = self._PRW_zip.GetValue().strip(),
858 street = self._PRW_street.GetValue().strip(),
859 number = self._TCTRL_number.GetValue().strip(),
860 subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), '')
861 )
862 except Exception:
863 _log.exception('cannot save address')
864 gmGuiHelpers.gm_show_error (
865 _('Cannot save address.\n\n'
866 'Does the region [%s]\n'
867 'exist in country [%s] ?'
868 ) % (
869 self._PRW_state.GetValue().strip(),
870 self._PRW_country.GetValue().strip()
871 ),
872 _('Saving address')
873 )
874 return False
875
876 # link address to holder (there better be one)
877 linked_address = self.address_holder.link_address(id_type = self._PRW_type.GetData(), address = created_or_loaded_address)
878 if linked_address['pk_address'] != created_or_loaded_address['pk_address']:
879 raise ValueError('problem linking address to person or org')
880
881 created_or_loaded_address['notes_street'] = gmTools.none_if(self._TCTRL_notes_street.GetValue().strip(), '')
882 created_or_loaded_address['notes_subunit'] = gmTools.none_if(self._TCTRL_notes_subunit.GetValue().strip(), '')
883 created_or_loaded_address.save_payload()
884 linked_address.refetch_payload()
885 self.data = linked_address
886
887 return True
888 #----------------------------------------------------------------
890 self._PRW_type.SetText('', None)
891 self._PRW_zip.SetText('', None)
892 self._PRW_street.SetText('', None)
893 self._TCTRL_notes_street.SetValue('')
894 self._TCTRL_number.SetValue('')
895 self._TCTRL_subunit.SetValue('')
896 self._PRW_suburb.SetText('', None)
897 self._PRW_urb.SetText('', None)
898 self._PRW_state.SetText('', None)
899 self._PRW_country.SetText('', None)
900 self._TCTRL_notes_subunit.SetValue('')
901
902 if self.__type_is_editable:
903 self._PRW_type.SetFocus()
904 else:
905 self._PRW_zip.SetFocus()
906 #----------------------------------------------------------------
908 self._refresh_as_new()
909
910 self._PRW_zip.SetText(self.data['postcode'])
911 self._PRW_street.SetText(self.data['street'], data = self.data['street'])
912 self._PRW_suburb.SetText(gmTools.coalesce(self.data['suburb'], ''))
913 self._PRW_urb.SetText(self.data['urb'], data = self.data['urb'])
914 self._PRW_state.SetText(self.data['l10n_region'], data = self.data['code_region'])
915 self._PRW_country.SetText(self.data['l10n_country'], data = self.data['code_country'])
916
917 if self.__type_is_editable:
918 self._PRW_type.SetFocus()
919 else:
920 self._TCTRL_number.SetFocus()
921 #----------------------------------------------------------------
923 if self.__type_is_editable:
924 self._PRW_type.SetText(self.data['l10n_address_type'])
925 else:
926 self._PRW_type.SetText('', None)
927 self._PRW_zip.SetText(self.data['postcode'])
928 self._PRW_street.SetText(self.data['street'], data = self.data['street'])
929 self._TCTRL_notes_street.SetValue(gmTools.coalesce(self.data['notes_street'], ''))
930 self._TCTRL_number.SetValue(self.data['number'])
931 self._TCTRL_subunit.SetValue(gmTools.coalesce(self.data['subunit'], ''))
932 self._PRW_suburb.SetText(gmTools.coalesce(self.data['suburb'], ''))
933 self._PRW_urb.SetText(self.data['urb'], data = self.data['urb'])
934 self._PRW_state.SetText(self.data['l10n_region'], data = self.data['code_region'])
935 self._PRW_country.SetText(self.data['l10n_country'], data = self.data['code_country'])
936 self._TCTRL_notes_subunit.SetValue(gmTools.coalesce(self.data['notes_subunit'], ''))
937
938 if self.__type_is_editable:
939 self._PRW_type.SetFocus()
940 else:
941 self._PRW_zip.SetFocus()
942 #----------------------------------------------------------------
943 # event handling
944 #----------------------------------------------------------------
946 """Set the street, town, region and country according to entered zip code."""
947 zip_code = self._PRW_zip.GetValue()
948 if zip_code.strip() == '':
949 self._PRW_street.unset_context(context = 'zip')
950 self._PRW_urb.unset_context(context = 'zip')
951 self._PRW_state.unset_context(context = 'zip')
952 self._PRW_country.unset_context(context = 'zip')
953 else:
954 self._PRW_street.set_context(context = 'zip', val = zip_code)
955 self._PRW_urb.set_context(context = 'zip', val = zip_code)
956 self._PRW_state.set_context(context = 'zip', val = zip_code)
957 self._PRW_country.set_context(context = 'zip', val = zip_code)
958 #----------------------------------------------------------------
960 """Set the regions according to entered country."""
961 country = self._PRW_country.GetData()
962 if country is None:
963 self._PRW_state.unset_context(context = 'country')
964 else:
965 self._PRW_state.set_context(context = 'country', val = country)
966 #----------------------------------------------------------------
967 # properties
968 #----------------------------------------------------------------
971
973 self.__type_is_editable = type_is_editable
974 self._PRW_type.Enable(type_is_editable)
975 self._PRW_type.Show(type_is_editable)
976 self._LBL_type.Show(type_is_editable)
977
978 type_is_editable = property(_get_type_is_editable, _set_type_is_editable)
979 #----------------------------------------------------------------
982
984 # FIXME: always set to FALSE when self.mode == 'new' ?
985 self.__address_is_searchable = address_is_searchable
986 self._PRW_address_searcher.Enable(address_is_searchable)
987 self._PRW_address_searcher.Show(address_is_searchable)
988 self._LBL_search.Show(address_is_searchable)
989
990 address_is_searchable = property(_get_address_is_searchable, _set_address_is_searchable)
991 #----------------------------------------------------------------
993 return self.data
994
997
998 address = property(_get_address, _set_address)
999
1000 #============================================================
1002
1004
1005 query = """
1006 SELECT * FROM (
1007 (SELECT
1008 pk_address AS data,
1009 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1010 || urb || coalesce(' (' || suburb || ')', '') || ', '
1011 || postcode || ', '
1012 || code_country
1013 ) AS field_label,
1014 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1015 || urb || coalesce(' (' || suburb || ')', '') || ', '
1016 || postcode || ', '
1017 || l10n_region || ', '
1018 || l10n_country
1019 || coalesce(', ' || notes_street, '')
1020 || coalesce(', ' || notes_subunit, '')
1021 ) AS list_label
1022 FROM
1023 dem.v_address
1024 WHERE
1025 street %(fragment_condition)s
1026
1027 ) UNION (
1028
1029 SELECT
1030 pk_address AS data,
1031 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1032 || urb || coalesce(' (' || suburb || ')', '') || ', '
1033 || postcode || ', '
1034 || code_country
1035 ) AS field_label,
1036 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1037 || urb || coalesce(' (' || suburb || ')', '') || ', '
1038 || postcode || ', '
1039 || l10n_region || ', '
1040 || l10n_country
1041 || coalesce(', ' || notes_street, '')
1042 || coalesce(', ' || notes_subunit, '')
1043 ) AS list_label
1044 FROM
1045 dem.v_address
1046 WHERE
1047 postcode_street %(fragment_condition)s
1048
1049 ) UNION (
1050
1051 SELECT
1052 pk_address AS data,
1053 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1054 || urb || coalesce(' (' || suburb || ')', '') || ', '
1055 || postcode || ', '
1056 || code_country
1057 ) AS field_label,
1058 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1059 || urb || coalesce(' (' || suburb || ')', '') || ', '
1060 || postcode || ', '
1061 || l10n_region || ', '
1062 || l10n_country
1063 || coalesce(', ' || notes_street, '')
1064 || coalesce(', ' || notes_subunit, '')
1065 ) AS list_label
1066 FROM
1067 dem.v_address
1068 WHERE
1069 postcode_urb %(fragment_condition)s
1070 )
1071 ) AS matching_addresses
1072 ORDER BY list_label
1073 LIMIT 50"""
1074
1075 gmMatchProvider.cMatchProvider_SQL2.__init__(self, queries = query)
1076
1077 self.setThresholds(2, 4, 6)
1078 # self.word_separators = u'[ \t]+'
1079
1080 self._SQL_data2match = """
1081 SELECT
1082 pk_address AS data,
1083 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1084 || urb || coalesce(' (' || suburb || ')', '') || ', '
1085 || postcode || ', '
1086 || code_country
1087 ) AS field_label,
1088 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
1089 || urb || coalesce(' (' || suburb || ')', '') || ', '
1090 || postcode || ', '
1091 || l10n_region || ', '
1092 || l10n_country
1093 || coalesce(', ' || notes_street, '')
1094 || coalesce(', ' || notes_subunit, '')
1095 ) AS list_label
1096 FROM
1097 dem.v_address
1098 WHERE
1099 pk_address = %(pk)s
1100 """
1101
1102 #============================================================
1104
1106
1107 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
1108 self.matcher = cAddressMatchProvider()
1109 self.SetToolTip(_('Select an address by postcode or street name.'))
1110 self.selection_only = True
1111 self.__address = None
1112 self.__old_pk = None
1113 #--------------------------------------------------------
1119 #--------------------------------------------------------
1122 #--------------------------------------------------------
1123 # properties
1124 #--------------------------------------------------------
1126 pk = self.GetData()
1127 if pk is None:
1128 self.__address = None
1129 return None
1130 if self.__address is None:
1131 self.__old_pk = pk
1132 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
1133 else:
1134 if pk != self.__old_pk:
1135 self.__old_pk = pk
1136 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
1137 return self.__address
1138
1140 if address is None:
1141 self.__old_pk = None
1142 self.__address = None
1143 self.SetText('', None)
1144 return
1145 if isinstance(address, (gmDemographicRecord.cAddress, gmDemographicRecord.cPatientAddress)):
1146 self.__old_pk = address['pk_address']
1147 self.__address = address
1148 pk = self.__old_pk
1149 else:
1150 self.__old_pk = None
1151 self.__address = None
1152 pk = address
1153 match = self.matcher.get_match_by_data(data = pk)
1154 if match is None:
1155 raise ValueError('[%s]: cannot match address [#%s]' % (self.__class__.__name__, pk))
1156 self.SetText(match['field_label'], pk)
1157
1158 address = property(__get_address, __set_address)
1159 #--------------------------------------------------------
1161 pk = self.GetData()
1162 if pk is None:
1163 self.__address = None
1164 return None
1165 if self.__address is None:
1166 self.__old_pk = pk
1167 self.__address = gmDemographicRecord.cPatientAddress(aPK_obj = pk)
1168 else:
1169 if pk != self.__old_pk:
1170 self.__old_pk = pk
1171 self.__address = gmDemographicRecord.cPatientAddress(aPK_obj = pk)
1172 return self.__address
1173
1174 person_address = property(__get_person_address, lambda x:x)
1175
1176 #============================================================
1177 from Gnumed.wxGladeWidgets import wxgAddressSelectionDlg
1178
1180
1182 wxgAddressSelectionDlg.wxgAddressSelectionDlg.__init__(self, *args, **kwargs)
1183 self._PRW_address_searcher.SetFocus()
1184 #--------------------------------------------------------
1186 return self._PRW_address_searcher.address
1187
1188 address = property(_get_address, lambda x:x)
1189 #--------------------------------------------------------
1192
1193 message = property(lambda x:x, _set_message)
1194 #--------------------------------------------------------
1198
1199 #================================================================
1200 # main
1201 #----------------------------------------------------------------
1202 if __name__ == '__main__':
1203
1204 if len(sys.argv) < 2:
1205 sys.exit()
1206
1207 if sys.argv[1] != 'test':
1208 sys.exit()
1209
1210 from Gnumed.pycommon import gmI18N
1211 gmI18N.activate_locale()
1212 gmI18N.install_domain()
1213 from Gnumed.business import gmPersonSearch
1214
1215 #--------------------------------------------------------
1217 app = wx.PyWidgetTester(size = (200, 50))
1218 pw = cCountryPhraseWheel(app.frame, -1)
1219 app.frame.Show(True)
1220 app.MainLoop()
1221 #--------------------------------------------------------
1223 app = wx.PyWidgetTester(size = (200, 50))
1224 pw = cStateSelectionPhraseWheel(app.frame, -1)
1225 pw.set_context(context = 'zip', val = '04318')
1226 pw.set_context(context = 'country', val = 'Deutschland')
1227 app.frame.Show(True)
1228 app.MainLoop()
1229 #--------------------------------------------------------
1231 app = wx.PyWidgetTester(size = (200, 50))
1232 pw = cZipcodePhraseWheel(app.frame, -1)
1233 app.frame.Show(True)
1234 app.MainLoop()
1235 #--------------------------------------------------------
1237 app = wx.PyWidgetTester(size = (200, 50))
1238 pw = cStreetPhraseWheel(app.frame, -1)
1239 # pw.set_context(context = u'zip', val = u'04318')
1240 app.frame.Show(True)
1241 app.MainLoop()
1242 #--------------------------------------------------------
1244 app = wx.PyWidgetTester(size = (200, 50))
1245 pw = cSuburbPhraseWheel(app.frame, -1)
1246 app.frame.Show(True)
1247 app.MainLoop()
1248 #--------------------------------------------------------
1250 app = wx.PyWidgetTester(size = (200, 50))
1251 pw = cUrbPhraseWheel(app.frame, -1)
1252 app.frame.Show(True)
1253 pw.set_context(context = 'zip', val = '04317')
1254 app.MainLoop()
1255 #--------------------------------------------------------
1257 app = wx.PyWidgetTester(size = (200, 50))
1258 pw = cAddressTypePhraseWheel(app.frame, -1)
1259 app.frame.Show(True)
1260 app.MainLoop()
1261 #--------------------------------------------------------
1263 app = wx.PyWidgetTester(size = (200, 50))
1264 pw = cAddressPhraseWheel(app.frame, -1)
1265 app.frame.Show(True)
1266 app.MainLoop()
1267 #--------------------------------------------------------
1269 app = wx.PyWidgetTester(size = (600, 400))
1270 app.SetWidget(cAddressEditAreaPnl, address = gmDemographicRecord.cAddress(aPK_obj = 1))
1271 app.MainLoop()
1272 #--------------------------------------------------------
1273 #test_address_type_prw()
1274 #test_zipcode_prw()
1275 #test_region_prw()
1276 #test_street_prw()
1277 #test_suburb_prw()
1278 #test_country_prw()
1279 #test_urb_prw()
1280 #test_address_ea_pnl()
1281 test_address_prw()
1282
1283 #================================================================
1284
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Feb 29 02:55:27 2020 | http://epydoc.sourceforge.net |