| 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.DestroyLater()
220 return True
221 dlg.DestroyLater()
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.StatusText = _('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.StatusText = _('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.StatusText = _('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.DestroyLater()
481 return True
482 dlg.DestroyLater()
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.StatusText = _('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(), function4value = ('strip', None)),
641 dose_unit = gmTools.coalesce(self._PRW_dose_unit.GetData(), self._PRW_dose_unit.GetValue().strip(), function4value = ('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.StatusText = _('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(), function4value = ('strip', None))
659 self.data['dose_unit'] = gmTools.coalesce(self._PRW_dose_unit.GetData(), self._PRW_dose_unit.GetValue().strip(), function4value = ('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.StatusText = _('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.DestroyLater()
757 return True
758 dlg.DestroyLater()
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.StatusText = _('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.StatusText = _('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.DestroyLater()
937 return True
938 dlg.DestroyLater()
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.DestroyLater()
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.StatusText = _('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.StatusText = _('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 doses = self.__component_doses,
1213 return_existing = True
1214 )
1215 drug['is_fake_product'] = self._CHBOX_is_fake.GetValue()
1216 drug['atc'] = self._PRW_atc.GetData()
1217 code = self._TCTRL_external_code.GetValue().strip()
1218 if code != '':
1219 drug['external_code'] = code
1220 drug['external_code_type'] = self._PRW_external_code_type.GetData().strip()
1221
1222 drug.save()
1223
1224 # if len(self.__component_doses) > 0:
1225 # drug.set_substance_doses_as_components(substance_doses = self.__component_doses)
1226
1227 self.data = drug
1228
1229 return True
1230
1231 #----------------------------------------------------------------
1233 self.data['product'] = self._PRW_product_name.GetValue().strip()
1234 self.data['preparation'] = gmTools.coalesce (
1235 self._PRW_preparation.GetData(),
1236 self._PRW_preparation.GetValue()
1237 ).strip()
1238 self.data['is_fake_product'] = self._CHBOX_is_fake.GetValue()
1239 self.data['atc'] = self._PRW_atc.GetData()
1240 code = self._TCTRL_external_code.GetValue().strip()
1241 if code != '':
1242 self.data['external_code'] = code
1243 self.data['external_code_type'] = self._PRW_external_code_type.GetData().strip()
1244 success, data = self.data.save()
1245 if not success:
1246 err, msg = data
1247 _log.error('problem saving')
1248 _log.error('%s', err)
1249 _log.error('%s', msg)
1250 return (success is True)
1251
1252 #----------------------------------------------------------------
1254 self._PRW_product_name.SetText('', None)
1255 self._PRW_preparation.SetText('', None)
1256 self._CHBOX_is_fake.SetValue(False)
1257 self._TCTRL_components.SetValue('')
1258 self._PRW_atc.SetText('', None)
1259 self._TCTRL_external_code.SetValue('')
1260 self._PRW_external_code_type.SetText('', None)
1261
1262 self._PRW_product_name.SetFocus()
1263
1264 self.__component_substances = []
1265
1266 #----------------------------------------------------------------
1269
1270 #----------------------------------------------------------------
1272 self._PRW_product_name.SetText(self.data['product'], self.data['pk_drug_product'])
1273 self._PRW_preparation.SetText(self.data['preparation'], self.data['preparation'])
1274 self._CHBOX_is_fake.SetValue(self.data['is_fake_product'])
1275 comp_str = ''
1276 if len(self.data['components']) > 0:
1277 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'] ])
1278 self._TCTRL_components.SetValue(comp_str)
1279 self._PRW_atc.SetText(gmTools.coalesce(self.data['atc'], ''), self.data['atc'])
1280 self._TCTRL_external_code.SetValue(gmTools.coalesce(self.data['external_code'], ''))
1281 t = gmTools.coalesce(self.data['external_code_type'], '')
1282 self._PRW_external_code_type.SetText(t, t)
1283
1284 self._PRW_product_name.SetFocus()
1285
1286 self.__component_doses = self.data.components_as_doses
1287
1288 #----------------------------------------------------------------
1289 # event handler
1290 #----------------------------------------------------------------
1304
1305 #------------------------------------------------------------
1307
1309
1310 query = """
1311 SELECT
1312 pk
1313 AS data,
1314 (description || ' (' || preparation || ')' || coalesce(' [' || atc_code || ']', ''))
1315 AS list_label,
1316 (description || ' (' || preparation || ')' || coalesce(' [' || atc_code || ']', ''))
1317 AS field_label
1318 FROM ref.drug_product
1319 WHERE description %(fragment_condition)s
1320 ORDER BY list_label
1321 LIMIT 50"""
1322
1323 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query)
1324 mp.setThresholds(2, 3, 4)
1325 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
1326 self.SetToolTip(_(
1327 'The product name of the drug.\n'
1328 '\n'
1329 'Note: a product name will need to be linked to\n'
1330 'one or more components before it can be used,\n'
1331 'except in the case of fake (generic) vaccines.'
1332 ))
1333 self.matcher = mp
1334 self.selection_only = False
1335
1336 #============================================================
1337 # single-component generic drugs
1338 # drug name is forced to substance + amount + unit + dose_unit
1339 #------------------------------------------------------------
1340 -def edit_single_component_generic_drug(parent=None, drug=None, single_entry=False, fields=None, return_drug=False):
1341
1342 # if drug is not None:
1343 # if drug.is_in_use_by_patients:
1344 # gmGuiHelpers.gm_show_info (
1345 # aTitle = _('Editing single-component generic drug'),
1346 # aMessage = _(
1347 # 'Cannot edit the single-component generic drug\n'
1348 # '\n'
1349 # ' "%s" (%s)\n'
1350 # '\n'
1351 # 'because it is currently taken by patients.\n'
1352 # ) % (drug['product'], drug['l10n_preparation'])
1353 # )
1354 # return False
1355
1356 if parent is None:
1357 parent = wx.GetApp().GetTopWindow()
1358
1359 # #--------------------------------------------
1360 # def manage_substances(drug):
1361 # manage_substance_doses(parent = parent)
1362
1363 #--------------------------------------------
1364 ea = cSingleComponentGenericDrugEAPnl(parent, -1)
1365 ea.data = drug
1366 ea.mode = gmTools.coalesce(drug, 'new', 'edit')
1367 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry)
1368 if fields is not None:
1369 ea.set_fields(fields)
1370 dlg.SetTitle(gmTools.coalesce(drug, _('Adding new single-component generic drug'), _('Editing single-component generic drug')))
1371 # dlg.left_extra_button = (
1372 # _('Substances'),
1373 # _('Manage substances'),
1374 # manage_substances
1375 # )
1376 if dlg.ShowModal() == wx.ID_OK:
1377 drug = ea.data
1378 dlg.DestroyLater()
1379 if return_drug:
1380 return drug
1381 return True
1382 dlg.DestroyLater()
1383 if return_drug:
1384 return None
1385 return False
1386
1387 #------------------------------------------------------------
1389
1390 if parent is None:
1391 parent = wx.GetApp().GetTopWindow()
1392
1393 #------------------------------------------------------------
1394 def add_from_db(drug):
1395 drug_db = get_drug_database(parent = parent)
1396 if drug_db is None:
1397 return False
1398 drug_db.import_drugs()
1399 return True
1400
1401 #------------------------------------------------------------
1402 def get_tooltip(product=None):
1403 return product.format(include_component_details = True)
1404
1405 #------------------------------------------------------------
1406 def edit(product):
1407 if product is not None:
1408 if product.is_vaccine:
1409 gmGuiHelpers.gm_show_info (
1410 aTitle = _('Editing medication'),
1411 aMessage = _(
1412 'Cannot edit the medication\n'
1413 '\n'
1414 ' "%s" (%s)\n'
1415 '\n'
1416 'because it is a vaccine. Please edit it\n'
1417 'from the vaccine management section !\n'
1418 ) % (product['product'], product['l10n_preparation'])
1419 )
1420 return False
1421
1422 return edit_drug_product(parent = parent, drug_product = product, single_entry = True)
1423
1424 #------------------------------------------------------------
1425 def delete(product):
1426 if product.is_vaccine:
1427 gmGuiHelpers.gm_show_info (
1428 aTitle = _('Deleting medication'),
1429 aMessage = _(
1430 'Cannot delete the medication\n'
1431 '\n'
1432 ' "%s" (%s)\n'
1433 '\n'
1434 'because it is a vaccine. Please delete it\n'
1435 'from the vaccine management section !\n'
1436 ) % (product['product'], product['l10n_preparation'])
1437 )
1438 return False
1439 gmMedication.delete_drug_product(pk_drug_product = product['pk_drug_product'])
1440 return True
1441
1442 #------------------------------------------------------------
1443 def new():
1444 return edit_drug_product(parent = parent, drug_product = None, single_entry = False)
1445
1446 #------------------------------------------------------------
1447 def refresh(lctrl):
1448 drugs = gmMedication.get_drug_products()
1449 items = [ [
1450 '%s%s' % (
1451 d['product'],
1452 gmTools.bool2subst(d['is_fake_product'], ' (%s)' % _('fake'), '')
1453 ),
1454 d['l10n_preparation'],
1455 gmTools.coalesce(d['atc'], ''),
1456 '; '.join([ '%s %s%s' % (
1457 c['substance'],
1458 c['amount'],
1459 gmMedication.format_units(c['unit'], c['dose_unit'])
1460 ) for c in d['components']]),
1461 gmTools.coalesce(d['external_code'], '', '%%s [%s]' % d['external_code_type']),
1462 d['pk_drug_product']
1463 ] for d in drugs ]
1464 lctrl.set_string_items(items)
1465 lctrl.set_data(drugs)
1466
1467 #------------------------------------------------------------
1468 gmListWidgets.get_choices_from_list (
1469 parent = parent,
1470 caption = _('Drug products currently known to GNUmed.'),
1471 columns = [_('Name'), _('Preparation'), _('ATC'), _('Components'), _('Code'), '#'],
1472 single_selection = True,
1473 ignore_OK_button = ignore_OK_button,
1474 refresh_callback = refresh,
1475 new_callback = new,
1476 edit_callback = edit,
1477 delete_callback = delete,
1478 list_tooltip_callback = get_tooltip,
1479 #left_extra_button = (_('Import'), _('Import substances and products from a drug database.'), add_from_db)
1480 #, middle_extra_button = (_('Clone'), _('Clone selected drug into a new entry for editing.'), clone_from_existing)
1481 #, right_extra_button = (_('Reassign'), _('Reassign all patients taking the selected drug to another drug.'), reassign_patients)
1482 )
1483
1484 #------------------------------------------------------------
1485 from Gnumed.wxGladeWidgets import wxgSingleComponentGenericDrugEAPnl
1486
1487 -class cSingleComponentGenericDrugEAPnl(wxgSingleComponentGenericDrugEAPnl.wxgSingleComponentGenericDrugEAPnl, gmEditArea.cGenericEditAreaMixin):
1488
1490
1491 try:
1492 data = kwargs['drug']
1493 del kwargs['drug']
1494 except KeyError:
1495 data = None
1496
1497 wxgSingleComponentGenericDrugEAPnl.wxgSingleComponentGenericDrugEAPnl.__init__(self, *args, **kwargs)
1498 gmEditArea.cGenericEditAreaMixin.__init__(self)
1499
1500 self.mode = 'new'
1501 self.data = data
1502 if data is not None:
1503 self.mode = 'edit'
1504
1505 self.__init_ui()
1506
1507 #----------------------------------------------------------------
1509 self._PRW_substance.add_callback_on_modified(callback = self._on_name_field_modified)
1510 self._PRW_substance.add_callback_on_selection(callback = self._on_name_field_modified)
1511 self._TCTRL_amount.add_callback_on_modified(callback = self._on_name_field_modified)
1512 self._PRW_unit.add_callback_on_modified(callback = self._on_name_field_modified)
1513 self._PRW_unit.add_callback_on_selection(callback = self._on_name_field_modified)
1514 self._PRW_dose_unit.add_callback_on_modified(callback = self._on_name_field_modified)
1515 self._PRW_dose_unit.add_callback_on_selection(callback = self._on_name_field_modified)
1516
1517 #----------------------------------------------------------------
1518 # generic Edit Area mixin API
1519 #----------------------------------------------------------------
1521
1522 validity = True
1523
1524 if self._PRW_preparation.Value.strip() == '':
1525 validity = False
1526 self._PRW_preparation.display_as_valid(False)
1527 self.StatusText = _('Drug form is missing.')
1528 self._PRW_preparation.SetFocus()
1529 else:
1530 self._PRW_preparation.display_as_valid(True)
1531
1532 if self._PRW_unit.GetData() is None:
1533 validity = False
1534 self._PRW_unit.display_as_valid(False)
1535 self.StatusText = _('Unit for amount is missing.')
1536 self._PRW_unit.SetFocus()
1537 else:
1538 self._PRW_unit.display_as_valid(True)
1539
1540 if self._TCTRL_amount.GetValue().strip() == '':
1541 validity = False
1542 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = False)
1543 self.StatusText = _('Amount is missing.')
1544 self._TCTRL_amount.SetFocus()
1545 else:
1546 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = True)
1547
1548 if self._PRW_substance.GetData() is None:
1549 val = self._PRW_substance.Value.strip()
1550 if val != '' and gmATC.exists_as_atc(val):
1551 subst = gmMedication.create_substance(substance = val)
1552 self._PRW_substance.SetText(subst['substance'], subst['pk_substance'])
1553 self._PRW_substance.display_as_valid(True)
1554 else:
1555 validity = False
1556 self._PRW_substance.display_as_valid(False)
1557 self.StatusText = _('Substance is missing.')
1558 self._PRW_substance.SetFocus()
1559 else:
1560 self._PRW_substance.display_as_valid(True)
1561
1562 return validity
1563
1564 #----------------------------------------------------------------
1566
1567 dose = gmMedication.create_substance_dose (
1568 pk_substance = self._PRW_substance.GetData(),
1569 amount = self._TCTRL_amount.Value.strip(),
1570 unit = self._PRW_unit.GetData(),
1571 dose_unit = self._PRW_dose_unit.GetData()
1572 )
1573 dose_unit = self._PRW_dose_unit.GetValue().strip()
1574 if dose_unit != '':
1575 dose_unit = '/' + dose_unit
1576 name = '%s %s%s%s' % (
1577 self._PRW_substance.GetValue().strip(),
1578 self._TCTRL_amount.Value.strip(),
1579 self._PRW_unit.GetValue().strip(),
1580 dose_unit
1581 )
1582 drug = gmMedication.create_drug_product (
1583 product_name = name,
1584 preparation = self._PRW_preparation.GetValue().strip(),
1585 return_existing = True,
1586 doses = [dose]
1587 )
1588 drug['is_fake_product'] = True
1589 drug.save()
1590 self.data = drug
1591 return True
1592
1593 #----------------------------------------------------------------
1596 # self.data[''] = self._CHBOX_xxx.GetValue()
1597 # self.data.save()
1598 # return True
1599
1600 #----------------------------------------------------------------
1602 self._LBL_drug_name.SetLabel('')
1603 self._PRW_substance.SetText('', None)
1604 self._TCTRL_amount.SetValue('')
1605 self._PRW_unit.SetText('', None)
1606 self._PRW_dose_unit.SetText('', None)
1607 self._PRW_preparation.SetText('', None)
1608
1609 #----------------------------------------------------------------
1612
1613 #----------------------------------------------------------------
1616
1617 #----------------------------------------------------------------
1619 try:
1620 self._PRW_substance.SetText(fields['substance']['value'], fields['substance']['data'])
1621 except KeyError:
1622 _log.error('cannot set field [substance] from <%s>', fields)
1623
1624 #----------------------------------------------------------------
1626 dose_unit = self._PRW_dose_unit.GetValue().strip()
1627 if dose_unit != '':
1628 dose_unit = '/' + dose_unit
1629 name = '%s %s%s%s' % (
1630 self._PRW_substance.GetValue().strip(),
1631 self._TCTRL_amount.Value.strip(),
1632 self._PRW_unit.GetValue().strip(),
1633 dose_unit
1634 )
1635 self._LBL_drug_name.SetLabel('"%s"' % name.strip())
1636
1637 #============================================================
1638 # main
1639 #------------------------------------------------------------
1640 if __name__ == '__main__':
1641
1642 if len(sys.argv) < 2:
1643 sys.exit()
1644
1645 if sys.argv[1] != 'test':
1646 sys.exit()
1647
1648 from Gnumed.business import gmPersonSearch
1649
1650 pat = gmPersonSearch.ask_for_patient()
1651 if pat is None:
1652 sys.exit()
1653 gmPerson.set_active_patient(patient = pat)
1654
1655 #----------------------------------------
1656 app = wx.PyWidgetTester(size = (600, 300))
1657 app.SetWidget(cSubstancePhraseWheel, -1)
1658 app.MainLoop()
1659 #manage_substance_intakes()
1660 edit_single_component_generic_drug (
1661 single_entry = True,
1662 fields = {'substance': {'value': val, 'data': None}},
1663 return_drug = True
1664 )
1665
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sun Jul 28 01:55:29 2019 | http://epydoc.sourceforge.net |