| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
2
3 #from __future__ import print_function
4
5 __doc__ = """GNUmed drug / substance reference widgets."""
6
7 #================================================================
8 __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
9 __license__ = "GPL v2 or later"
10
11 import logging
12 import sys
13 import os.path
14 import decimal
15
16
17 import wx
18
19
20 if __name__ == '__main__':
21 sys.path.insert(0, '../../')
22 from Gnumed.pycommon import gmI18N
23 gmI18N.activate_locale()
24 gmI18N.install_domain(domain = 'gnumed')
25
26 from Gnumed.pycommon import gmDispatcher
27 from Gnumed.pycommon import gmCfg
28 from Gnumed.pycommon import gmShellAPI
29 from Gnumed.pycommon import gmTools
30 from Gnumed.pycommon import gmMatchProvider
31
32 from Gnumed.business import gmPerson
33 from Gnumed.business import gmPraxis
34 from Gnumed.business import gmMedication
35 from Gnumed.business import gmDrugDataSources
36 from Gnumed.business import gmATC
37
38 from Gnumed.wxpython import gmGuiHelpers
39 from Gnumed.wxpython import gmEditArea
40 from Gnumed.wxpython import gmCfgWidgets
41 from Gnumed.wxpython import gmListWidgets
42 from Gnumed.wxpython import gmPhraseWheel
43
44
45 _log = logging.getLogger('gm.ui')
46
47 #============================================================
48 # generic drug database access
49 #------------------------------------------------------------
51 gmCfgWidgets.configure_string_from_list_option (
52 parent = parent,
53 message = _(
54 '\n'
55 'Please select the default drug data source from the list below.\n'
56 '\n'
57 'Note that to actually use it you need to have the database installed, too.'
58 ),
59 option = 'external.drug_data.default_source',
60 bias = 'user',
61 default_value = None,
62 choices = gmDrugDataSources.drug_data_source_interfaces.keys(),
63 columns = [_('Drug data source')],
64 data = gmDrugDataSources.drug_data_source_interfaces.keys(),
65 caption = _('Configuring default drug data source')
66 )
67
68 #============================================================
70 dbcfg = gmCfg.cCfgSQL()
71
72 # load from option
73 default_db = dbcfg.get2 (
74 option = 'external.drug_data.default_source',
75 workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
76 bias = 'workplace'
77 )
78
79 # not configured -> try to configure
80 if default_db is None:
81 gmDispatcher.send('statustext', msg = _('No default drug database configured.'), beep = True)
82 configure_drug_data_source(parent = parent)
83 default_db = dbcfg.get2 (
84 option = 'external.drug_data.default_source',
85 workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
86 bias = 'workplace'
87 )
88 # still not configured -> return
89 if default_db is None:
90 gmGuiHelpers.gm_show_error (
91 aMessage = _('There is no default drug database configured.'),
92 aTitle = _('Jumping to drug database')
93 )
94 return None
95
96 # now it MUST be configured (either newly or previously)
97 # but also *validly* ?
98 try:
99 drug_db = gmDrugDataSources.drug_data_source_interfaces[default_db]()
100 except KeyError:
101 # not valid
102 _log.error('faulty default drug data source configuration: %s', default_db)
103 # try to configure
104 configure_drug_data_source(parent = parent)
105 default_db = dbcfg.get2 (
106 option = 'external.drug_data.default_source',
107 workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
108 bias = 'workplace'
109 )
110 # deconfigured or aborted (and thusly still misconfigured) ?
111 try:
112 drug_db = gmDrugDataSources.drug_data_source_interfaces[default_db]()
113 except KeyError:
114 _log.error('still faulty default drug data source configuration: %s', default_db)
115 return None
116
117 if patient is not None:
118 drug_db.patient = patient
119
120 return drug_db
121
122 #============================================================
124 drug_db = get_drug_database(patient = patient)
125 if drug_db is None:
126 return
127 drug_db.switch_to_frontend(blocking = False)
128
129 #============================================================
131
132 if import_drugs and (emr is None):
133 gmDispatcher.send('statustext', msg = _('Cannot import drugs from IFAP into chart without chart.'))
134 return False
135
136 dbcfg = gmCfg.cCfgSQL()
137
138 ifap_cmd = dbcfg.get2 (
139 option = 'external.ifap-win.shell_command',
140 workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
141 bias = 'workplace',
142 default = 'wine "C:\Ifapwin\WIAMDB.EXE"'
143 )
144 found, binary = gmShellAPI.detect_external_binary(ifap_cmd)
145 if not found:
146 gmDispatcher.send('statustext', msg = _('Cannot call IFAP via [%s].') % ifap_cmd)
147 return False
148 ifap_cmd = binary
149
150 if import_drugs:
151 transfer_file = os.path.expanduser(dbcfg.get2 (
152 option = 'external.ifap-win.transfer_file',
153 workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
154 bias = 'workplace',
155 default = '~/.wine/drive_c/Ifapwin/ifap2gnumed.csv'
156 ))
157 # file must exist for Ifap to write into it
158 try:
159 f = io.open(transfer_file, mode = 'wt').close()
160 except IOError:
161 _log.exception('Cannot create IFAP <-> GNUmed transfer file [%s]', transfer_file)
162 gmDispatcher.send('statustext', msg = _('Cannot create IFAP <-> GNUmed transfer file [%s].') % transfer_file)
163 return False
164
165 wx.BeginBusyCursor()
166 gmShellAPI.run_command_in_shell(command = ifap_cmd, blocking = import_drugs)
167 wx.EndBusyCursor()
168
169 if import_drugs:
170 # COMMENT: this file must exist PRIOR to invoking IFAP
171 # COMMENT: or else IFAP will not write data into it ...
172 try:
173 csv_file = io.open(transfer_file, mode = 'rt', encoding = 'latin1') # FIXME: encoding unknown
174 except:
175 _log.exception('cannot access [%s]', fname)
176 csv_file = None
177
178 if csv_file is not None:
179 import csv
180 csv_lines = csv.DictReader (
181 csv_file,
182 fieldnames = 'PZN Handelsname Form Abpackungsmenge Einheit Preis1 Hersteller Preis2 rezeptpflichtig Festbetrag Packungszahl Packungsgr\xf6\xdfe'.split(),
183 delimiter = ';'
184 )
185 # dummy episode for now
186 epi = emr.add_episode(episode_name = _('Current medication'))
187 for line in csv_lines:
188 narr = '%sx %s %s %s (\u2258 %s %s) von %s (%s)' % (
189 line['Packungszahl'].strip(),
190 line['Handelsname'].strip(),
191 line['Form'].strip(),
192 line['Packungsgr\xf6\xdfe'].strip(),
193 line['Abpackungsmenge'].strip(),
194 line['Einheit'].strip(),
195 line['Hersteller'].strip(),
196 line['PZN'].strip()
197 )
198 emr.add_clin_narrative(note = narr, soap_cat = 's', episode = epi)
199 csv_file.close()
200
201 return True
202
203 #============================================================
204 # substances widgets
205 #------------------------------------------------------------
207
208 if substance is not None:
209 if substance.is_in_use_by_patients:
210 gmDispatcher.send(signal = 'statustext', msg = _('Cannot edit this substance. It is in use.'), beep = True)
211 return False
212
213 ea = cSubstanceEAPnl(parent, -1)
214 ea.data = substance
215 ea.mode = gmTools.coalesce(substance, 'new', 'edit')
216 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry)
217 dlg.SetTitle(gmTools.coalesce(substance, _('Adding new substance'), _('Editing substance')))
218 if dlg.ShowModal() == wx.ID_OK:
219 dlg.Destroy()
220 return True
221 dlg.Destroy()
222 return False
223
224 #------------------------------------------------------------
226
227 if parent is None:
228 parent = wx.GetApp().GetTopWindow()
229
230 #------------------------------------------------------------
231 def add_from_db(substance):
232 drug_db = get_drug_database(parent = parent)
233 if drug_db is None:
234 return False
235 drug_db.import_drugs()
236 return True
237
238 #------------------------------------------------------------
239 def edit(substance=None):
240 return edit_substance(parent = parent, substance = substance, single_entry = (substance is not None))
241
242 #------------------------------------------------------------
243 def delete(substance):
244 if substance.is_in_use_by_patients:
245 gmDispatcher.send(signal = 'statustext', msg = _('Cannot delete this substance. It is in use.'), beep = True)
246 return False
247 return gmMedication.delete_substance(pk_substance = substance['pk_substance'])
248
249 #------------------------------------------------------------
250 def get_item_tooltip(substance):
251 if not isinstance(substance, gmMedication.cSubstance):
252 return None
253 return substance.format()
254
255 #------------------------------------------------------------
256 def refresh(lctrl):
257 substs = gmMedication.get_substances(order_by = 'substance')
258 items = [ [
259 s['substance'],
260 gmTools.coalesce(s['atc'], ''),
261 gmTools.coalesce(s['intake_instructions'], ''),
262 s['pk_substance']
263 ] for s in substs ]
264 lctrl.set_string_items(items)
265 lctrl.set_data(substs)
266
267 #------------------------------------------------------------
268 gmListWidgets.get_choices_from_list (
269 parent = parent,
270 caption = _('Substances registered with GNUmed.'),
271 columns = [_('Substance'), 'ATC', _('Instructions'), '#'],
272 single_selection = True,
273 new_callback = edit,
274 edit_callback = edit,
275 delete_callback = delete,
276 refresh_callback = refresh,
277 left_extra_button = (_('Import'), _('Import substances from a drug database.'), add_from_db),
278 list_tooltip_callback = get_item_tooltip
279 )
280
281 #------------------------------------------------------------
282 from Gnumed.wxGladeWidgets import wxgSubstanceEAPnl
283
285
287
288 try:
289 data = kwargs['substance']
290 del kwargs['substance']
291 except KeyError:
292 data = None
293
294 wxgSubstanceEAPnl.wxgSubstanceEAPnl.__init__(self, *args, **kwargs)
295 gmEditArea.cGenericEditAreaMixin.__init__(self)
296
297 # Code using this mixin should set mode and data
298 # after instantiating the class:
299 self.mode = 'new'
300 self.data = data
301 if data is not None:
302 self.mode = 'edit'
303
304 self.__init_ui()
305
306 #----------------------------------------------------------------
308 self._LCTRL_loincs.set_columns([_('LOINC'), _('Interval'), _('Comment')])
309
310 #----------------------------------------------------------------
311 # generic Edit Area mixin API
312 #----------------------------------------------------------------
314
315 validity = True
316
317 if self._TCTRL_substance.GetValue().strip() == '':
318 validity = False
319 self.display_tctrl_as_valid(tctrl = self._TCTRL_substance, valid = False)
320 self._TCTRL_substance.SetFocus()
321 else:
322 self.display_tctrl_as_valid(tctrl = self._TCTRL_substance, valid = True)
323
324 if validity is False:
325 self.status_message = _('Cannot save: Substance name missing.')
326
327 return validity
328
329 #----------------------------------------------------------------
331 subst = gmMedication.create_substance (
332 substance = self._TCTRL_substance.GetValue().strip(),
333 atc = self._PRW_atc.GetData()
334 )
335 subst['intake_instructions'] = self._TCTRL_instructions.GetValue().strip()
336 success, data = subst.save()
337 if not success:
338 err, msg = data
339 _log.error(err)
340 _log.error(msg)
341 self.status_message = _('Error saving substance. %s') % msg
342 return False
343
344 loincs = self._LCTRL_loincs.item_data
345 if len(loincs) > 0:
346 subst.loincs = loincs
347
348 self.data = subst
349 return True
350
351 #----------------------------------------------------------------
353 self.data['substance'] = self._TCTRL_substance.GetValue().strip()
354 self.data['atc'] = self._PRW_atc.GetData()
355 self.data['intake_instructions'] = self._TCTRL_instructions.GetValue().strip()
356 success, data = self.data.save()
357 if not success:
358 err, msg = data
359 _log.error(err)
360 _log.error(msg)
361 self.status_message = _('Error saving substance. %s') % msg
362 return False
363
364 loincs = self._LCTRL_loincs.item_data
365 if len(loincs) > 0:
366 self.data.loincs = loincs
367
368 return True
369
370 #----------------------------------------------------------------
372 self._TCTRL_substance.SetValue('')
373 self._PRW_atc.SetText('', None)
374 self._TCTRL_instructions.SetValue('')
375 self._PRW_loinc.SetText('', None)
376 self._LCTRL_loincs.set_string_items()
377
378 self._TCTRL_substance.SetFocus()
379
380 #----------------------------------------------------------------
382 self._TCTRL_substance.SetValue(self.data['substance'])
383 self._PRW_atc.SetText(gmTools.coalesce(self.data['atc'], ''), self.data['atc'])
384 self._TCTRL_instructions.SetValue(gmTools.coalesce(self.data['intake_instructions'], ''))
385 self._PRW_loinc.SetText('', None)
386 if len(self.data['loincs']) == 0:
387 self._LCTRL_loincs.set_string_items()
388 else:
389 self._LCTRL_loincs.set_string_items([ [l['loinc'], gmTools.coalesce(l['max_age_str'], ''), gmTools.coalesce(l['comment'], '')] for l in self.data['loincs' ]])
390 self._LCTRL_loincs.set_data([ l['loinc'] for l in self.data['loincs'] ])
391
392 self._TCTRL_substance.SetFocus()
393
394 #----------------------------------------------------------------
397
398 #----------------------------------------------------------------
399 # event handlers
400 #----------------------------------------------------------------
413
414 #----------------------------------------------------------------
417
418 #------------------------------------------------------------
420
422
423 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
424 query = """
425 SELECT DISTINCT ON (list_label)
426 list_label,
427 field_label,
428 data
429 FROM (
430 SELECT
431 description AS list_label,
432 description AS field_label,
433 pk AS data
434 FROM ref.substance
435 WHERE
436 description %(fragment_condition)s
437
438 UNION ALL
439
440 SELECT
441 term AS list_label,
442 term AS field_label,
443 NULL::integer AS data
444 FROM ref.atc
445 WHERE
446 term %(fragment_condition)s
447
448 ) AS candidates
449 ORDER BY list_label
450 LIMIT 50
451 """
452 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query)
453 mp.setThresholds(1, 2, 4)
454 # mp.word_separators = '[ \t=+&:@]+'
455 self.SetToolTip(_('The substance name.'))
456 self.matcher = mp
457 self.selection_only = False
458 self.phrase_separators = None
459
460 #--------------------------------------------------------
463
464 #============================================================
465 # substance dose widgets
466 #------------------------------------------------------------
468
469 if substance_dose is not None:
470 if substance_dose.is_in_use_by_patients:
471 gmDispatcher.send(signal = 'statustext', msg = _('Cannot edit this substance. It is in use.'), beep = True)
472 return False
473
474 ea = cSubstanceDoseEAPnl(parent, -1)
475 ea.data = substance_dose
476 ea.mode = gmTools.coalesce(substance_dose, 'new', 'edit')
477 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry)
478 dlg.SetTitle(gmTools.coalesce(substance_dose, _('Adding new substance dose'), _('Editing substance dose')))
479 if dlg.ShowModal() == wx.ID_OK:
480 dlg.Destroy()
481 return True
482 dlg.Destroy()
483 return False
484
485 #------------------------------------------------------------
487
488 if parent is None:
489 parent = wx.GetApp().GetTopWindow()
490
491 #------------------------------------------------------------
492 def add_from_db(substance):
493 drug_db = get_drug_database(parent = parent)
494 if drug_db is None:
495 return False
496 drug_db.import_drugs()
497 return True
498
499 #------------------------------------------------------------
500 def edit(substance_dose=None):
501 return edit_substance_dose(parent = parent, substance_dose = substance_dose, single_entry = (substance_dose is not None))
502
503 #------------------------------------------------------------
504 def delete(substance_dose):
505 if substance_dose.is_in_use_by_patients:
506 gmDispatcher.send(signal = 'statustext', msg = _('Cannot delete this substance. It is in use.'), beep = True)
507 return False
508 return gmMedication.delete_substance_dose(pk_dose = substance_dose['pk_dose'])
509
510 #------------------------------------------------------------
511 def refresh(lctrl):
512 if vaccine_indications_only:
513 substs = [ s for s in gmMedication.get_substance_doses(order_by = 'substance') if gmTools.coalesce(s['atc_substance'], '').startswith('J07') ]
514 else:
515 substs = gmMedication.get_substance_doses(order_by = 'substance')
516 items = [ [
517 s['substance'],
518 s['amount'],
519 s.formatted_units,
520 gmTools.coalesce(s['atc_substance'], ''),
521 gmTools.coalesce(s['intake_instructions'], ''),
522 s['pk_dose']
523 ] for s in substs ]
524 lctrl.set_string_items(items)
525 lctrl.set_data(substs)
526
527 #------------------------------------------------------------
528 def get_item_tooltip(substance_dose):
529 if not isinstance(substance_dose, gmMedication.cSubstanceDose):
530 return None
531 return substance_dose.format(include_loincs = True)
532
533 #------------------------------------------------------------
534 return gmListWidgets.get_choices_from_list (
535 parent = parent,
536 caption = _('Substance doses registered with GNUmed.'),
537 columns = [_('Substance'), _('Amount'), _('Unit'), 'ATC', _('Instructions'), '#'],
538 single_selection = False,
539 can_return_empty = False,
540 new_callback = edit,
541 edit_callback = edit,
542 delete_callback = delete,
543 refresh_callback = refresh,
544 left_extra_button = (_('Import'), _('Import substance doses from a drug database.'), add_from_db),
545 list_tooltip_callback = get_item_tooltip
546 )
547
548 #------------------------------------------------------------
549 from Gnumed.wxGladeWidgets import wxgSubstanceDoseEAPnl
550
551 -class cSubstanceDoseEAPnl(wxgSubstanceDoseEAPnl.wxgSubstanceDoseEAPnl, gmEditArea.cGenericEditAreaMixin):
552
554
555 try:
556 data = kwargs['substance']
557 del kwargs['substance']
558 except KeyError:
559 data = None
560
561 wxgSubstanceDoseEAPnl.wxgSubstanceDoseEAPnl.__init__(self, *args, **kwargs)
562 gmEditArea.cGenericEditAreaMixin.__init__(self)
563
564 # Code using this mixin should set mode and data
565 # after instantiating the class:
566 self.mode = 'new'
567 self.data = data
568 if data is not None:
569 self.mode = 'edit'
570
571 self.__init_ui()
572
573 #----------------------------------------------------------------
575 self._PRW_substance.add_callback_on_modified(callback = self.__refresh_info)
576 self._PRW_substance.add_callback_on_selection(callback = self.__refresh_info)
577 self._TCTRL_amount.add_callback_on_modified(callback = self.__refresh_info)
578 self._PRW_unit.add_callback_on_modified(callback = self.__refresh_info)
579 self._PRW_unit.add_callback_on_selection(callback = self.__refresh_info)
580 self._PRW_dose_unit.add_callback_on_modified(callback = self.__refresh_info)
581 self._PRW_dose_unit.add_callback_on_selection(callback = self.__refresh_info)
582
583 #----------------------------------------------------------------
585 subst = self._PRW_substance.GetValue().strip()
586 if subst == '':
587 subst = '?'
588 amount = self._TCTRL_amount.GetValue().strip()
589 if amount == '':
590 amount = '?'
591 unit = self._PRW_unit.GetValue().strip()
592 if unit == '':
593 unit = '?'
594 dose_unit = self._PRW_dose_unit.GetValue().strip()
595 if dose_unit == '':
596 dose_unit = _('<delivery unit>')
597 self._LBL_info.SetLabel('%s %s %s / %s' % (subst, amount, unit, dose_unit))
598 self.Refresh()
599
600 #----------------------------------------------------------------
601 # generic Edit Area mixin API
602 #----------------------------------------------------------------
604
605 validity = True
606
607 if self._PRW_substance.GetValue().strip() == '':
608 validity = False
609 self._PRW_substance.display_as_valid(valid = False)
610 self._PRW_substance.SetFocus()
611 else:
612 self._PRW_substance.display_as_valid(valid = True)
613
614 try:
615 decimal.Decimal(self._TCTRL_amount.GetValue().strip().replace(',', '.'))
616 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = True)
617 except (TypeError, decimal.InvalidOperation):
618 validity = False
619 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = False)
620 self._TCTRL_amount.SetFocus()
621
622 if self._PRW_unit.GetValue().strip() == '':
623 validity = False
624 self._PRW_unit.display_as_valid(valid = False)
625 self._PRW_unit.SetFocus()
626 else:
627 self._PRW_unit.display_as_valid(valid = True)
628
629 if validity is False:
630 self.status_message = _('Cannot save substance dose. Missing essential input.')
631
632 return validity
633
634 #----------------------------------------------------------------
636 dose = gmMedication.create_substance_dose (
637 pk_substance = self._PRW_substance.GetData(),
638 substance = self._PRW_substance.GetValue().strip(),
639 amount = decimal.Decimal(self._TCTRL_amount.GetValue().strip().replace(',', '.')),
640 unit = gmTools.coalesce(self._PRW_unit.GetData(), self._PRW_unit.GetValue().strip(), function_initial = ('strip', None)),
641 dose_unit = gmTools.coalesce(self._PRW_dose_unit.GetData(), self._PRW_dose_unit.GetValue().strip(), function_initial = ('strip', None))
642 )
643 success, data = dose.save()
644 if not success:
645 err, msg = data
646 _log.error(err)
647 _log.error(msg)
648 self.status_message = _('Cannot create substance dose. %s') % msg
649 return False
650
651 self.data = dose
652 return True
653
654 #----------------------------------------------------------------
656 #self.data['pk_substance'] = self._PRW_substance.GetData()
657 self.data['amount'] = decimal.Decimal(self._TCTRL_amount.GetValue().strip().replace(',', '.'))
658 self.data['unit'] = gmTools.coalesce(self._PRW_unit.GetData(), self._PRW_unit.GetValue().strip(), function_initial = ('strip', None))
659 self.data['dose_unit'] = gmTools.coalesce(self._PRW_dose_unit.GetData(), self._PRW_dose_unit.GetValue().strip(), function_initial = ('strip', None))
660 success, data = self.data.save()
661
662 if not success:
663 err, msg = data
664 _log.error(err)
665 _log.error(msg)
666 self.status_message = _('Cannot save substance dose. %s') % msg
667 return False
668
669 return True
670
671 #----------------------------------------------------------------
673 self._PRW_substance.SetText('', None)
674 self._TCTRL_amount.SetValue('')
675 self._PRW_unit.SetText('', None)
676 self._PRW_dose_unit.SetText('', None)
677 self._LBL_info.SetLabel('')
678
679 self._PRW_substance.SetFocus()
680
681 #----------------------------------------------------------------
683 self._PRW_substance.SetText(self.data['substance'], self.data['pk_substance'])
684 self._PRW_substance.Disable()
685 self._TCTRL_amount.SetValue('%s' % self.data['amount'])
686 self._PRW_unit.SetText(self.data['unit'], self.data['unit'])
687 self._PRW_dose_unit.SetText(gmTools.coalesce(self.data['dose_unit'], ''), self.data['dose_unit'])
688
689 self._PRW_substance.SetFocus()
690
691 #----------------------------------------------------------------
694
695 #============================================================
696 # drug component widgets
697 #------------------------------------------------------------
699
700 if parent is None:
701 parent = wx.GetApp().GetTopWindow()
702
703 #------------------------------------------------------------
704 def edit(component=None):
705 substance_dose = gmMedication.cSubstanceDose(aPK_obj = component['pk_dose'])
706 return edit_substance_dose(parent = parent, substance_dose = substance_dose, single_entry = True)
707
708 #------------------------------------------------------------
709 def delete(component):
710 if component.is_in_use_by_patients:
711 gmDispatcher.send(signal = 'statustext', msg = _('Cannot remove this component from the drug. It is in use.'), beep = True)
712 return False
713 return component.containing_drug.remove_component(pk_component = component['pk_component'])
714
715 #------------------------------------------------------------
716 def refresh(lctrl):
717 comps = gmMedication.get_drug_components()
718 items = [ [
719 '%s%s' % (c['substance'], gmTools.coalesce(c['atc_substance'], '', ' [%s]')),
720 '%s %s' % (c['amount'], c.formatted_units),
721 '%s%s' % (c['product'], gmTools.coalesce(c['atc_drug'], '', ' [%s]')),
722 c['l10n_preparation'],
723 gmTools.coalesce(c['external_code'], '', '%%s [%s]' % c['external_code_type']),
724 c['pk_component']
725 ] for c in comps ]
726 lctrl.set_string_items(items)
727 lctrl.set_data(comps)
728
729 #------------------------------------------------------------
730 def get_item_tooltip(component):
731 if not isinstance(component, gmMedication.cDrugComponent):
732 return None
733 return component.format(include_loincs = True)
734
735 #------------------------------------------------------------
736 gmListWidgets.get_choices_from_list (
737 parent = parent,
738 caption = _('Drug components currently known to GNUmed'),
739 columns = [_('Component'), _('Strength'), _('Product name'), _('Preparation'), _('Code'), '#'],
740 single_selection = True,
741 #new_callback = edit,
742 edit_callback = edit,
743 delete_callback = delete,
744 refresh_callback = refresh,
745 list_tooltip_callback = get_item_tooltip
746 )
747
748 #------------------------------------------------------------
750 ea = cDrugComponentEAPnl(parent, -1)
751 ea.data = drug_component
752 ea.mode = gmTools.coalesce(drug_component, 'new', 'edit')
753 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry)
754 dlg.SetTitle(gmTools.coalesce(drug_component, _('Adding new drug component'), _('Editing drug component')))
755 if dlg.ShowModal() == wx.ID_OK:
756 dlg.Destroy()
757 return True
758 dlg.Destroy()
759 return False
760
761 #------------------------------------------------------------
762 from Gnumed.wxGladeWidgets import wxgDrugComponentEAPnl
763
764 -class cDrugComponentEAPnl(wxgDrugComponentEAPnl.wxgDrugComponentEAPnl, gmEditArea.cGenericEditAreaMixin):
765
767
768 try:
769 data = kwargs['component']
770 del kwargs['component']
771 except KeyError:
772 data = None
773
774 wxgDrugComponentEAPnl.wxgDrugComponentEAPnl.__init__(self, *args, **kwargs)
775 gmEditArea.cGenericEditAreaMixin.__init__(self)
776
777 # Code using this mixin should set mode and data
778 # after instantiating the class:
779 self.mode = 'new'
780 self.data = data
781 if data is not None:
782 self.mode = 'edit'
783
784 #self.__init_ui()
785 #----------------------------------------------------------------
786 # def __init_ui(self):
787 # # adjust phrasewheels etc
788 #----------------------------------------------------------------
789 # generic Edit Area mixin API
790 #----------------------------------------------------------------
792 if self.data is not None:
793 if self.data['is_in_use']:
794 self.status_message = _('Cannot edit drug component. It is in use.')
795 return False
796
797 validity = True
798
799 if self._PRW_substance.GetData() is None:
800 validity = False
801 self._PRW_substance.display_as_valid(False)
802 else:
803 self._PRW_substance.display_as_valid(True)
804
805 val = self._TCTRL_amount.GetValue().strip().replace(',', '.', 1)
806 try:
807 decimal.Decimal(val)
808 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = True)
809 except:
810 validity = False
811 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = False)
812
813 if self._PRW_unit.GetValue().strip() == '':
814 validity = False
815 self._PRW_unit.display_as_valid(False)
816 else:
817 self._PRW_unit.display_as_valid(True)
818
819 if validity is False:
820 self.status_message = _('Cannot save drug component. Invalid or missing essential input.')
821
822 return validity
823 #----------------------------------------------------------------
825 # save the data as a new instance
826 data = 1
827 data[''] = 1
828 data[''] = 1
829 # data.save()
830
831 # must be done very late or else the property access
832 # will refresh the display such that later field
833 # access will return empty values
834 # self.data = data
835 return False
836 return True
837 #----------------------------------------------------------------
839 self.data['pk_dose'] = self._PRW_substance.GetData()
840 self.data['amount'] = decimal.Decimal(self._TCTRL_amount.GetValue().strip().replace(',', '.', 1))
841 self.data['unit'] = self._PRW_unit.GetValue().strip()
842 return self.data.save()
843
844 #----------------------------------------------------------------
846 self._TCTRL_product_name.SetValue('')
847 self._TCTRL_components.SetValue('')
848 self._TCTRL_codes.SetValue('')
849 self._PRW_substance.SetText('', None)
850 self._TCTRL_amount.SetValue('')
851 self._PRW_unit.SetText('', None)
852
853 self._PRW_substance.SetFocus()
854
855 #----------------------------------------------------------------
857 self._TCTRL_product_name.SetValue('%s (%s)' % (self.data['product'], self.data['l10n_preparation']))
858 self._TCTRL_components.SetValue(' / '.join(self.data.containing_drug['components']))
859 details = []
860 if self.data['atc_drug'] is not None:
861 details.append('ATC: %s' % self.data['atc_drug'])
862 if self.data['external_code_product'] is not None:
863 details.append('%s: %s' % (self.data['external_code_type_product'], self.data['external_code_product']))
864 self._TCTRL_codes.SetValue('; '.join(details))
865
866 self._PRW_substance.SetText(self.data['substance'], self.data['pk_dose'])
867 self._TCTRL_amount.SetValue('%s' % self.data['amount'])
868 self._PRW_unit.SetText(self.data['unit'], self.data['unit'])
869
870 self._PRW_substance.SetFocus()
871
872 #----------------------------------------------------------------
882
883 #------------------------------------------------------------
885
887
888 mp = gmMedication.cDrugComponentMatchProvider()
889 mp.setThresholds(2, 3, 4)
890 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
891 self.SetToolTip(_('A drug component with optional strength.'))
892 self.matcher = mp
893 self.selection_only = False
894 #--------------------------------------------------------
896 return gmMedication.cDrugComponent(aPK_obj = self.GetData(as_instance = False, can_create = False))
897
898 #============================================================
899 # drug products widgets
900 #------------------------------------------------------------
902
903 if drug_product is not None:
904 if drug_product.is_in_use_by_patients:
905 gmGuiHelpers.gm_show_info (
906 aTitle = _('Editing drug'),
907 aMessage = _(
908 'Cannot edit the drug product\n'
909 '\n'
910 ' "%s" (%s)\n'
911 '\n'
912 'because it is currently taken by patients.\n'
913 ) % (drug_product['product'], drug_product['l10n_preparation'])
914 )
915 return False
916
917 if parent is None:
918 parent = wx.GetApp().GetTopWindow()
919
920 #--------------------------------------------
921 def manage_substances(drug):
922 manage_substance_doses(parent = parent)
923
924 #--------------------------------------------
925 ea = cDrugProductEAPnl(parent, -1)
926 ea.data = drug_product
927 ea.mode = gmTools.coalesce(drug_product, 'new', 'edit')
928 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry)
929 dlg.SetTitle(gmTools.coalesce(drug_product, _('Adding new drug product'), _('Editing drug product')))
930 dlg.left_extra_button = (
931 _('Substances'),
932 _('Manage substances'),
933 manage_substances
934 )
935 if dlg.ShowModal() == wx.ID_OK:
936 dlg.Destroy()
937 return True
938 dlg.Destroy()
939 return False
940
941 #------------------------------------------------------------
943
944 if parent is None:
945 parent = wx.GetApp().GetTopWindow()
946
947 #------------------------------------------------------------
948 def add_from_db(drug):
949 drug_db = get_drug_database(parent = parent)
950 if drug_db is None:
951 return False
952 drug_db.import_drugs()
953 return True
954
955 #------------------------------------------------------------
956 def get_tooltip(product=None):
957 return product.format(include_component_details = True)
958
959 #------------------------------------------------------------
960 def edit(product):
961 if product is not None:
962 if product.is_in_use_as_vaccine:
963 gmGuiHelpers.gm_show_info (
964 aTitle = _('Editing medication'),
965 aMessage = _(
966 'Cannot edit the vaccine product\n'
967 '\n'
968 ' "%s" (%s)\n'
969 '\n'
970 'because it is in use.'
971 ) % (product['product'], product['l10n_preparation'])
972 )
973 return False
974
975 return edit_drug_product(parent = parent, drug_product = product, single_entry = True)
976
977 #------------------------------------------------------------
978 def delete(product):
979 if not product.delete_associated_vaccine():
980 gmGuiHelpers.gm_show_info (
981 aTitle = _('Deleting vaccine'),
982 aMessage = _(
983 'Cannot delete the vaccine product\n'
984 '\n'
985 ' "%s" (%s)\n'
986 '\n'
987 'because it is in use.'
988 ) % (product['product'], product['l10n_preparation'])
989 )
990 return False
991
992 gmMedication.delete_drug_product(pk_drug_product = product['pk_drug_product'])
993 return True
994
995 #------------------------------------------------------------
996 def new():
997 return edit_drug_product(parent = parent, drug_product = None, single_entry = False)
998
999 #------------------------------------------------------------
1000 def refresh(lctrl):
1001 drugs = gmMedication.get_drug_products()
1002 items = [ [
1003 '%s%s' % (
1004 d['product'],
1005 gmTools.bool2subst(d['is_fake_product'], ' (%s)' % _('fake'), '')
1006 ),
1007 d['l10n_preparation'],
1008 gmTools.coalesce(d['atc'], ''),
1009 '; '.join([ '%s %s%s' % (
1010 c['substance'],
1011 c['amount'],
1012 gmMedication.format_units(c['unit'], c['dose_unit'])
1013 ) for c in d['components']]),
1014 gmTools.coalesce(d['external_code'], '', '%%s [%s]' % d['external_code_type']),
1015 d['pk_drug_product']
1016 ] for d in drugs ]
1017 lctrl.set_string_items(items)
1018 lctrl.set_data(drugs)
1019
1020 #------------------------------------------------------------
1021 gmListWidgets.get_choices_from_list (
1022 parent = parent,
1023 caption = _('Drug products currently known to GNUmed.'),
1024 columns = [_('Name'), _('Preparation'), _('ATC'), _('Components'), _('Code'), '#'],
1025 single_selection = True,
1026 ignore_OK_button = ignore_OK_button,
1027 refresh_callback = refresh,
1028 new_callback = new,
1029 edit_callback = edit,
1030 delete_callback = delete,
1031 list_tooltip_callback = get_tooltip,
1032 left_extra_button = (_('Import'), _('Import substances and products from a drug database.'), add_from_db)
1033 #, middle_extra_button = (_('Clone'), _('Clone selected drug into a new entry for editing.'), clone_from_existing)
1034 #, right_extra_button = (_('Reassign'), _('Reassign all patients taking the selected drug to another drug.'), reassign_patients)
1035 )
1036
1037 #------------------------------------------------------------
1039
1040 if product is not None:
1041 if product.is_in_use_by_patients:
1042 gmGuiHelpers.gm_show_info (
1043 aTitle = _('Managing components of a drug'),
1044 aMessage = _(
1045 'Cannot manage the components of the drug product\n'
1046 '\n'
1047 ' "%s" (%s)\n'
1048 '\n'
1049 'because it is currently taken by patients.\n'
1050 ) % (product['product'], product['l10n_preparation'])
1051 )
1052 return False
1053
1054 #--------------------------------------------------------
1055 if parent is None:
1056 parent = wx.GetApp().GetTopWindow()
1057
1058 #--------------------------------------------------------
1059 # def manage_substances():
1060 # pass
1061
1062 #--------------------------------------------------------
1063 if product is None:
1064 msg = _('Pick the substance doses which are components of this drug.')
1065 right_col = _('Components of drug')
1066 comp_doses = []
1067 else:
1068 right_col = '%s (%s)' % (product['product'], product['l10n_preparation'])
1069 msg = _(
1070 'Adjust the components of "%s"\n'
1071 '\n'
1072 'The drug must contain at least one component. Any given\n'
1073 'substance can only be included once per drug.'
1074 ) % right_col
1075 comp_doses = [ comp.substance_dose for comp in product.components ]
1076
1077 doses = gmMedication.get_substance_doses(order_by = 'substance')
1078 choices = [ '%s %s %s' % (d['substance'], d['amount'], d.formatted_units) for d in doses ]
1079 picks = [ '%s %s %s' % (d['substance'], d['amount'], d.formatted_units) for d in comp_doses ]
1080
1081 picker = gmListWidgets.cItemPickerDlg (
1082 parent,
1083 -1,
1084 title = _('Managing components of a drug ...'),
1085 msg = msg
1086 )
1087 picker.set_columns(['Substance doses'], [right_col])
1088 picker.set_choices(choices = choices, data = doses)
1089 picker.set_picks(picks = picks, data = comp_doses)
1090 # picker.extra_button = (
1091 # _('Substances'),
1092 # _('Manage list of substances'),
1093 # manage_substances
1094 # )
1095
1096 btn_pressed = picker.ShowModal()
1097 doses2set = picker.get_picks()
1098 picker.Destroy()
1099
1100 if btn_pressed != wx.ID_OK:
1101 return (False, None)
1102
1103 if product is not None:
1104 product.set_substance_doses_as_components(substance_doses = doses2set)
1105
1106 return (True, doses2set)
1107
1108 #------------------------------------------------------------
1109 from Gnumed.wxGladeWidgets import wxgDrugProductEAPnl
1110
1111 -class cDrugProductEAPnl(wxgDrugProductEAPnl.wxgDrugProductEAPnl, gmEditArea.cGenericEditAreaMixin):
1112
1114 try:
1115 data = kwargs['drug']
1116 del kwargs['drug']
1117 except KeyError:
1118 data = None
1119
1120 wxgDrugProductEAPnl.wxgDrugProductEAPnl.__init__(self, *args, **kwargs)
1121 gmEditArea.cGenericEditAreaMixin.__init__(self)
1122
1123 self.mode = 'new'
1124 self.data = data
1125 if data is not None:
1126 self.mode = 'edit'
1127 self.__component_doses = data.components_as_doses
1128
1129 #self.__init_ui()
1130 #----------------------------------------------------------------
1131 # def __init_ui(self):
1132 # adjust external type PRW
1133 #----------------------------------------------------------------
1134 # generic Edit Area mixin API
1135 #----------------------------------------------------------------
1137
1138 if self.data is not None:
1139 if self.data.is_in_use_by_patients:
1140 self.status_message = _('Cannot edit drug product. It is in use.')
1141 return False
1142
1143 validity = True
1144
1145 product_name = self._PRW_product_name.GetValue().strip()
1146 if product_name == '':
1147 validity = False
1148 self._PRW_product_name.display_as_valid(False)
1149 else:
1150 self._PRW_product_name.display_as_valid(True)
1151
1152 preparation = self._PRW_preparation.GetValue().strip()
1153 if preparation == '':
1154 validity = False
1155 self._PRW_preparation.display_as_valid(False)
1156 else:
1157 self._PRW_preparation.display_as_valid(True)
1158
1159 if validity is True:
1160 # dupe ?
1161 drug = gmMedication.get_drug_by_name(product_name = product_name, preparation = preparation)
1162 if drug is not None:
1163 if self.mode != 'edit':
1164 validity = False
1165 self._PRW_product_name.display_as_valid(False)
1166 self._PRW_preparation.display_as_valid(False)
1167 gmGuiHelpers.gm_show_error (
1168 title = _('Checking product data'),
1169 error = _(
1170 'The information you entered:\n'
1171 '\n'
1172 ' [%s %s]\n'
1173 '\n'
1174 'already exists as a drug product.'
1175 ) % (product_name, preparation)
1176 )
1177 else:
1178 # lacking components ?
1179 self._TCTRL_components.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND))
1180 if len(self.__component_doses) == 0:
1181 wants_empty = gmGuiHelpers.gm_show_question (
1182 title = _('Checking product data'),
1183 question = _(
1184 'You have not selected any substances\n'
1185 'as drug components.\n'
1186 '\n'
1187 'Without components you will not be able to\n'
1188 'use this drug for documenting patient care.\n'
1189 '\n'
1190 'Are you sure you want to save\n'
1191 'it without components ?'
1192 )
1193 )
1194 if not wants_empty:
1195 validity = False
1196 self.display_ctrl_as_valid(ctrl = self._TCTRL_components, valid = False)
1197
1198 if validity is False:
1199 self.status_message = _('Cannot save drug product. Invalid or missing essential input.')
1200
1201 return validity
1202
1203 #----------------------------------------------------------------
1205
1206 drug = gmMedication.create_drug_product (
1207 product_name = self._PRW_product_name.GetValue().strip(),
1208 preparation = gmTools.coalesce (
1209 self._PRW_preparation.GetData(),
1210 self._PRW_preparation.GetValue()
1211 ).strip(),
1212 return_existing = True
1213 )
1214 drug['is_fake_product'] = self._CHBOX_is_fake.GetValue()
1215 drug['atc'] = self._PRW_atc.GetData()
1216 code = self._TCTRL_external_code.GetValue().strip()
1217 if code != '':
1218 drug['external_code'] = code
1219 drug['external_code_type'] = self._PRW_external_code_type.GetData().strip()
1220
1221 drug.save()
1222
1223 if len(self.__component_doses) > 0:
1224 drug.set_substance_doses_as_components(substance_doses = self.__component_doses)
1225
1226 self.data = drug
1227
1228 return True
1229
1230 #----------------------------------------------------------------
1232 self.data['product'] = self._PRW_product_name.GetValue().strip()
1233 self.data['preparation'] = gmTools.coalesce (
1234 self._PRW_preparation.GetData(),
1235 self._PRW_preparation.GetValue()
1236 ).strip()
1237 self.data['is_fake_product'] = self._CHBOX_is_fake.GetValue()
1238 self.data['atc'] = self._PRW_atc.GetData()
1239 code = self._TCTRL_external_code.GetValue().strip()
1240 if code != '':
1241 self.data['external_code'] = code
1242 self.data['external_code_type'] = self._PRW_external_code_type.GetData().strip()
1243 success, data = self.data.save()
1244 if not success:
1245 err, msg = data
1246 _log.error('problem saving')
1247 _log.error('%s', err)
1248 _log.error('%s', msg)
1249 return (success is True)
1250
1251 #----------------------------------------------------------------
1253 self._PRW_product_name.SetText('', None)
1254 self._PRW_preparation.SetText('', None)
1255 self._CHBOX_is_fake.SetValue(False)
1256 self._TCTRL_components.SetValue('')
1257 self._PRW_atc.SetText('', None)
1258 self._TCTRL_external_code.SetValue('')
1259 self._PRW_external_code_type.SetText('', None)
1260
1261 self._PRW_product_name.SetFocus()
1262
1263 self.__component_substances = []
1264
1265 #----------------------------------------------------------------
1268
1269 #----------------------------------------------------------------
1271 self._PRW_product_name.SetText(self.data['product'], self.data['pk_drug_product'])
1272 self._PRW_preparation.SetText(self.data['preparation'], self.data['preparation'])
1273 self._CHBOX_is_fake.SetValue(self.data['is_fake_product'])
1274 comp_str = ''
1275 if len(self.data['components']) > 0:
1276 comp_str = '- %s' % '\n- '.join([ '%s %s%s' % (c['substance'], c['amount'], gmMedication.format_units(c['unit'], c['dose_unit'])) for c in self.data['components'] ])
1277 self._TCTRL_components.SetValue(comp_str)
1278 self._PRW_atc.SetText(gmTools.coalesce(self.data['atc'], ''), self.data['atc'])
1279 self._TCTRL_external_code.SetValue(gmTools.coalesce(self.data['external_code'], ''))
1280 t = gmTools.coalesce(self.data['external_code_type'], '')
1281 self._PRW_external_code_type.SetText(t, t)
1282
1283 self._PRW_product_name.SetFocus()
1284
1285 self.__component_doses = self.data.components_as_doses
1286
1287 #----------------------------------------------------------------
1288 # event handler
1289 #----------------------------------------------------------------
1303
1304 #------------------------------------------------------------
1306
1308
1309 query = """
1310 SELECT
1311 pk
1312 AS data,
1313 (description || ' (' || preparation || ')' || coalesce(' [' || atc_code || ']', ''))
1314 AS list_label,
1315 (description || ' (' || preparation || ')' || coalesce(' [' || atc_code || ']', ''))
1316 AS field_label
1317 FROM ref.drug_product
1318 WHERE description %(fragment_condition)s
1319 ORDER BY list_label
1320 LIMIT 50"""
1321
1322 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query)
1323 mp.setThresholds(2, 3, 4)
1324 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
1325 self.SetToolTip(_(
1326 'The product name of the drug.\n'
1327 '\n'
1328 'Note: a product name will need to be linked to\n'
1329 'one or more components before it can be used,\n'
1330 'except in the case of fake (generic) vaccines.'
1331 ))
1332 self.matcher = mp
1333 self.selection_only = False
1334
1335 #============================================================
1336 # single-component generic drugs
1337 # drug name is forced to substance + amount + unit + dose_unit
1338 #------------------------------------------------------------
1339 -def edit_single_component_generic_drug(parent=None, drug=None, single_entry=False, fields=None, return_drug=False):
1340
1341 # if drug is not None:
1342 # if drug.is_in_use_by_patients:
1343 # gmGuiHelpers.gm_show_info (
1344 # aTitle = _('Editing single-component generic drug'),
1345 # aMessage = _(
1346 # 'Cannot edit the single-component generic drug\n'
1347 # '\n'
1348 # ' "%s" (%s)\n'
1349 # '\n'
1350 # 'because it is currently taken by patients.\n'
1351 # ) % (drug['product'], drug['l10n_preparation'])
1352 # )
1353 # return False
1354
1355 if parent is None:
1356 parent = wx.GetApp().GetTopWindow()
1357
1358 # #--------------------------------------------
1359 # def manage_substances(drug):
1360 # manage_substance_doses(parent = parent)
1361
1362 #--------------------------------------------
1363 ea = cSingleComponentGenericDrugEAPnl(parent, -1)
1364 ea.data = drug
1365 ea.mode = gmTools.coalesce(drug, 'new', 'edit')
1366 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry)
1367 if fields is not None:
1368 ea.set_fields(fields)
1369 dlg.SetTitle(gmTools.coalesce(drug, _('Adding new single-component generic drug'), _('Editing single-component generic drug')))
1370 # dlg.left_extra_button = (
1371 # _('Substances'),
1372 # _('Manage substances'),
1373 # manage_substances
1374 # )
1375 if dlg.ShowModal() == wx.ID_OK:
1376 drug = ea.data
1377 dlg.Destroy()
1378 if return_drug:
1379 return drug
1380 return True
1381 dlg.Destroy()
1382 if return_drug:
1383 return None
1384 return False
1385
1386 #------------------------------------------------------------
1388
1389 if parent is None:
1390 parent = wx.GetApp().GetTopWindow()
1391
1392 #------------------------------------------------------------
1393 def add_from_db(drug):
1394 drug_db = get_drug_database(parent = parent)
1395 if drug_db is None:
1396 return False
1397 drug_db.import_drugs()
1398 return True
1399
1400 #------------------------------------------------------------
1401 def get_tooltip(product=None):
1402 return product.format(include_component_details = True)
1403
1404 #------------------------------------------------------------
1405 def edit(product):
1406 if product is not None:
1407 if product.is_vaccine:
1408 gmGuiHelpers.gm_show_info (
1409 aTitle = _('Editing medication'),
1410 aMessage = _(
1411 'Cannot edit the medication\n'
1412 '\n'
1413 ' "%s" (%s)\n'
1414 '\n'
1415 'because it is a vaccine. Please edit it\n'
1416 'from the vaccine management section !\n'
1417 ) % (product['product'], product['l10n_preparation'])
1418 )
1419 return False
1420
1421 return edit_drug_product(parent = parent, drug_product = product, single_entry = True)
1422
1423 #------------------------------------------------------------
1424 def delete(product):
1425 if product.is_vaccine:
1426 gmGuiHelpers.gm_show_info (
1427 aTitle = _('Deleting medication'),
1428 aMessage = _(
1429 'Cannot delete the medication\n'
1430 '\n'
1431 ' "%s" (%s)\n'
1432 '\n'
1433 'because it is a vaccine. Please delete it\n'
1434 'from the vaccine management section !\n'
1435 ) % (product['product'], product['l10n_preparation'])
1436 )
1437 return False
1438 gmMedication.delete_drug_product(pk_drug_product = product['pk_drug_product'])
1439 return True
1440
1441 #------------------------------------------------------------
1442 def new():
1443 return edit_drug_product(parent = parent, drug_product = None, single_entry = False)
1444
1445 #------------------------------------------------------------
1446 def refresh(lctrl):
1447 drugs = gmMedication.get_drug_products()
1448 items = [ [
1449 '%s%s' % (
1450 d['product'],
1451 gmTools.bool2subst(d['is_fake_product'], ' (%s)' % _('fake'), '')
1452 ),
1453 d['l10n_preparation'],
1454 gmTools.coalesce(d['atc'], ''),
1455 '; '.join([ '%s %s%s' % (
1456 c['substance'],
1457 c['amount'],
1458 gmMedication.format_units(c['unit'], c['dose_unit'])
1459 ) for c in d['components']]),
1460 gmTools.coalesce(d['external_code'], '', '%%s [%s]' % d['external_code_type']),
1461 d['pk_drug_product']
1462 ] for d in drugs ]
1463 lctrl.set_string_items(items)
1464 lctrl.set_data(drugs)
1465
1466 #------------------------------------------------------------
1467 gmListWidgets.get_choices_from_list (
1468 parent = parent,
1469 caption = _('Drug products currently known to GNUmed.'),
1470 columns = [_('Name'), _('Preparation'), _('ATC'), _('Components'), _('Code'), '#'],
1471 single_selection = True,
1472 ignore_OK_button = ignore_OK_button,
1473 refresh_callback = refresh,
1474 new_callback = new,
1475 edit_callback = edit,
1476 delete_callback = delete,
1477 list_tooltip_callback = get_tooltip,
1478 #left_extra_button = (_('Import'), _('Import substances and products from a drug database.'), add_from_db)
1479 #, middle_extra_button = (_('Clone'), _('Clone selected drug into a new entry for editing.'), clone_from_existing)
1480 #, right_extra_button = (_('Reassign'), _('Reassign all patients taking the selected drug to another drug.'), reassign_patients)
1481 )
1482
1483 #------------------------------------------------------------
1484 from Gnumed.wxGladeWidgets import wxgSingleComponentGenericDrugEAPnl
1485
1486 -class cSingleComponentGenericDrugEAPnl(wxgSingleComponentGenericDrugEAPnl.wxgSingleComponentGenericDrugEAPnl, gmEditArea.cGenericEditAreaMixin):
1487
1489
1490 try:
1491 data = kwargs['drug']
1492 del kwargs['drug']
1493 except KeyError:
1494 data = None
1495
1496 wxgSingleComponentGenericDrugEAPnl.wxgSingleComponentGenericDrugEAPnl.__init__(self, *args, **kwargs)
1497 gmEditArea.cGenericEditAreaMixin.__init__(self)
1498
1499 self.mode = 'new'
1500 self.data = data
1501 if data is not None:
1502 self.mode = 'edit'
1503
1504 self.__init_ui()
1505
1506 #----------------------------------------------------------------
1508 self._PRW_substance.add_callback_on_modified(callback = self._on_name_field_modified)
1509 self._PRW_substance.add_callback_on_selection(callback = self._on_name_field_modified)
1510 self._TCTRL_amount.add_callback_on_modified(callback = self._on_name_field_modified)
1511 self._PRW_unit.add_callback_on_modified(callback = self._on_name_field_modified)
1512 self._PRW_unit.add_callback_on_selection(callback = self._on_name_field_modified)
1513 self._PRW_dose_unit.add_callback_on_modified(callback = self._on_name_field_modified)
1514 self._PRW_dose_unit.add_callback_on_selection(callback = self._on_name_field_modified)
1515
1516 #----------------------------------------------------------------
1517 # generic Edit Area mixin API
1518 #----------------------------------------------------------------
1520
1521 validity = True
1522
1523 if self._PRW_preparation.Value.strip() == '':
1524 validity = False
1525 self._PRW_preparation.display_as_valid(False)
1526 self.status_message = _('Drug form is missing.')
1527 self._PRW_preparation.SetFocus()
1528 else:
1529 self._PRW_preparation.display_as_valid(True)
1530
1531 if self._PRW_unit.GetData() is None:
1532 validity = False
1533 self._PRW_unit.display_as_valid(False)
1534 self.status_message = _('Unit for amount is missing.')
1535 self._PRW_unit.SetFocus()
1536 else:
1537 self._PRW_unit.display_as_valid(True)
1538
1539 if self._TCTRL_amount.GetValue().strip() == '':
1540 validity = False
1541 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = False)
1542 self.status_message = _('Amount is missing.')
1543 self._TCTRL_amount.SetFocus()
1544 else:
1545 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = True)
1546
1547 if self._PRW_substance.GetData() is None:
1548 val = self._PRW_substance.Value.strip()
1549 if val != '' and gmATC.exists_as_atc(val):
1550 subst = gmMedication.create_substance(substance = val)
1551 self._PRW_substance.SetText(subst['substance'], subst['pk_substance'])
1552 self._PRW_substance.display_as_valid(True)
1553 else:
1554 validity = False
1555 self._PRW_substance.display_as_valid(False)
1556 self.status_message = _('Substance is missing.')
1557 self._PRW_substance.SetFocus()
1558 else:
1559 self._PRW_substance.display_as_valid(True)
1560
1561 return validity
1562
1563 #----------------------------------------------------------------
1565
1566 dose = gmMedication.create_substance_dose (
1567 pk_substance = self._PRW_substance.GetData(),
1568 amount = self._TCTRL_amount.Value.strip(),
1569 unit = self._PRW_unit.GetData(),
1570 dose_unit = self._PRW_dose_unit.GetData()
1571 )
1572 dose_unit = self._PRW_dose_unit.GetValue().strip()
1573 if dose_unit != '':
1574 dose_unit = '/' + dose_unit
1575 name = '%s %s%s%s' % (
1576 self._PRW_substance.GetValue().strip(),
1577 self._TCTRL_amount.Value.strip(),
1578 self._PRW_unit.GetValue().strip(),
1579 dose_unit
1580 )
1581 drug = gmMedication.create_drug_product (
1582 product_name = name,
1583 preparation = self._PRW_preparation.GetValue().strip(),
1584 return_existing = True
1585 )
1586 drug['is_fake_product'] = True
1587 drug.save()
1588 drug.set_substance_doses_as_components(substance_doses = [dose])
1589 self.data = drug
1590 return True
1591
1592 #----------------------------------------------------------------
1595 # self.data[''] = self._CHBOX_xxx.GetValue()
1596 # self.data.save()
1597 # return True
1598
1599 #----------------------------------------------------------------
1601 self._LBL_drug_name.SetLabel('')
1602 self._PRW_substance.SetText('', None)
1603 self._TCTRL_amount.SetValue('')
1604 self._PRW_unit.SetText('', None)
1605 self._PRW_dose_unit.SetText('', None)
1606 self._PRW_preparation.SetText('', None)
1607
1608 #----------------------------------------------------------------
1611
1612 #----------------------------------------------------------------
1615
1616 #----------------------------------------------------------------
1618 try:
1619 self._PRW_substance.SetText(fields['substance']['value'], fields['substance']['data'])
1620 except KeyError:
1621 _log.error('cannot set field [substance] from <%s>', fields)
1622
1623 #----------------------------------------------------------------
1625 dose_unit = self._PRW_dose_unit.GetValue().strip()
1626 if dose_unit != '':
1627 dose_unit = '/' + dose_unit
1628 name = '%s %s%s%s' % (
1629 self._PRW_substance.GetValue().strip(),
1630 self._TCTRL_amount.Value.strip(),
1631 self._PRW_unit.GetValue().strip(),
1632 dose_unit
1633 )
1634 self._LBL_drug_name.SetLabel('"%s"' % name.strip())
1635
1636 #============================================================
1637 # main
1638 #------------------------------------------------------------
1639 if __name__ == '__main__':
1640
1641 if len(sys.argv) < 2:
1642 sys.exit()
1643
1644 if sys.argv[1] != 'test':
1645 sys.exit()
1646
1647 from Gnumed.business import gmPersonSearch
1648
1649 pat = gmPersonSearch.ask_for_patient()
1650 if pat is None:
1651 sys.exit()
1652 gmPerson.set_active_patient(patient = pat)
1653
1654 #----------------------------------------
1655 app = wx.PyWidgetTester(size = (600, 300))
1656 app.SetWidget(cSubstancePhraseWheel, -1)
1657 app.MainLoop()
1658 #manage_substance_intakes()
1659 edit_single_component_generic_drug (
1660 single_entry = True,
1661 fields = {'substance': {'value': val, 'data': None}},
1662 return_drug = True
1663 )
1664
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Jan 25 02:55:27 2019 | http://epydoc.sourceforge.net |