1
2 """Medication handling code.
3
4 license: GPL
5 """
6
7 __version__ = "$Revision: 1.21 $"
8 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
9
10 import sys, logging, csv, codecs, os, re as regex, subprocess
11
12
13 if __name__ == '__main__':
14 sys.path.insert(0, '../../')
15 from Gnumed.pycommon import gmBusinessDBObject, gmPG2, gmShellAPI, gmTools
16 from Gnumed.pycommon import gmDispatcher, gmDateTime, gmHooks
17 from Gnumed.business import gmATC, gmAllergy
18
19
20 _log = logging.getLogger('gm.meds')
21 _log.info(__version__)
22
23
27
28 gmDispatcher.connect(_on_substance_intake_modified, u'substance_intake_mod_db')
29
30
32
33 if search_term is None:
34 return u'http://www.dosing.de'
35
36 terms = []
37 names = []
38
39 if isinstance(search_term, cBrandedDrug):
40 if search_term['atc_code'] is not None:
41 terms.append(search_term['atc_code'])
42
43 elif isinstance(search_term, cSubstanceIntakeEntry):
44 names.append(search_term['substance'])
45 if search_term['atc_brand'] is not None:
46 terms.append(search_term['atc_brand'])
47 if search_term['atc_substance'] is not None:
48 terms.append(search_term['atc_substance'])
49
50 elif search_term is not None:
51 names.append(u'%s' % search_term)
52 terms.extend(gmATC.text2atc(text = u'%s' % search_term, fuzzy = True))
53
54 for name in names:
55 if name.endswith('e'):
56 terms.append(name[:-1])
57 else:
58 terms.append(name)
59
60
61
62
63 url_template = u'http://www.google.de/search?hl=de&source=hp&q=site%%3Adosing.de+%s&btnG=Google-Suche'
64 url = url_template % u'+OR+'.join(terms)
65
66 _log.debug(u'renal insufficiency URL: %s', url)
67
68 return url
69
70
71 -def create_data_source(long_name=None, short_name=None, version=None, source=None, language=None):
72
73 args = {
74 'lname': long_name,
75 'sname': short_name,
76 'ver': version,
77 'src': source,
78 'lang': language
79 }
80
81 cmd = u"""select pk from ref.data_source where name_long = %(lname)s and name_short = %(sname)s and version = %(ver)s"""
82 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
83 if len(rows) > 0:
84 return rows[0]['pk']
85
86 cmd = u"""
87 INSERT INTO ref.data_source (name_long, name_short, version, source, lang)
88 VALUES (
89 %(lname)s,
90 %(sname)s,
91 %(ver)s,
92 %(src)s,
93 %(lang)s
94 )
95 returning pk
96 """
97 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
98
99 return rows[0]['pk']
100
101
102
103
104
105
106
108 """Iterator over a Gelbe Liste/MMI v8.2 CSV file."""
109
110 version = u'Gelbe Liste/MMI v8.2 CSV file interface'
111 default_transfer_file_windows = r"c:\rezept.txt"
112
113 default_encoding = 'cp1250'
114 csv_fieldnames = [
115 u'name',
116 u'packungsgroesse',
117 u'darreichungsform',
118 u'packungstyp',
119 u'festbetrag',
120 u'avp',
121 u'hersteller',
122 u'rezepttext',
123 u'pzn',
124 u'status_vertrieb',
125 u'status_rezeptpflicht',
126 u'status_fachinfo',
127 u'btm',
128 u'atc',
129 u'anzahl_packungen',
130 u'zuzahlung_pro_packung',
131 u'einheit',
132 u'schedule_morgens',
133 u'schedule_mittags',
134 u'schedule_abends',
135 u'schedule_nachts',
136 u'status_dauermedikament',
137 u'status_hausliste',
138 u'status_negativliste',
139 u'ik_nummer',
140 u'status_rabattvertrag',
141 u'wirkstoffe',
142 u'wirkstoffmenge',
143 u'wirkstoffeinheit',
144 u'wirkstoffmenge_bezug',
145 u'wirkstoffmenge_bezugseinheit',
146 u'status_import',
147 u'status_lifestyle',
148 u'status_ausnahmeliste',
149 u'packungsmenge',
150 u'apothekenpflicht',
151 u'status_billigere_packung',
152 u'rezepttyp',
153 u'besonderes_arzneimittel',
154 u't_rezept_pflicht',
155 u'erstattbares_medizinprodukt',
156 u'hilfsmittel',
157 u'hzv_rabattkennung',
158 u'hzv_preis'
159 ]
160 boolean_fields = [
161 u'status_rezeptpflicht',
162 u'status_fachinfo',
163 u'btm',
164 u'status_dauermedikament',
165 u'status_hausliste',
166 u'status_negativliste',
167 u'status_rabattvertrag',
168 u'status_import',
169 u'status_lifestyle',
170 u'status_ausnahmeliste',
171 u'apothekenpflicht',
172 u'status_billigere_packung',
173 u'besonderes_arzneimittel',
174 u't_rezept_pflicht',
175 u'erstattbares_medizinprodukt',
176 u'hilfsmittel'
177 ]
178
198
201
203 line = self.csv_lines.next()
204
205 for field in cGelbeListeCSVFile.boolean_fields:
206 line[field] = (line[field].strip() == u'T')
207
208
209 if line['wirkstoffe'].strip() == u'':
210 line['wirkstoffe'] = []
211 else:
212 line['wirkstoffe'] = [ wirkstoff.strip() for wirkstoff in line['wirkstoffe'].split(u';') ]
213
214 return line
215
216 - def close(self, truncate=True):
217 try: self.csv_file.close()
218 except: pass
219
220 if truncate:
221 try: os.open(self.filename, 'wb').close
222 except: pass
223
225
226
228 self.patient = None
229 self.custom_path_to_binary = None
230
232 raise NotImplementedError
233
235 raise NotImplementedError
236
238 raise NotImplementedError
239
241 raise NotImplementedError
242
244 raise NotImplementedError
245
247 raise NotImplementedError
248
250 raise NotImplementedError
251
253
254 version = u'FreeDiams v0.4.2 interface'
255 default_encoding = 'utf8'
256 default_dob_format = '%Y/%m/%d'
257
258 map_gender2mf = {
259 'm': u'M',
260 'f': u'F',
261 'tf': u'H',
262 'tm': u'H',
263 'h': u'H'
264 }
265
277
279
280
281 if not self.__detect_binary():
282 return False
283
284 freediams = subprocess.Popen (
285 args = u'--version',
286 executable = self.path_to_binary,
287 stdout = subprocess.PIPE,
288 stderr = subprocess.PIPE,
289
290 universal_newlines = True
291 )
292 data, errors = freediams.communicate()
293 ver = regex.search('FreeDiams\s\d.\d.\d', data).group().split()[1]
294 _log.debug('FreeDiams %s', ver)
295
296 return version
297
299 return create_data_source (
300 long_name = u'"FreeDiams" Drug Database Frontend',
301 short_name = u'FreeDiams',
302 version = self.get_data_source_version(),
303 source = u'http://ericmaeker.fr/FreeMedForms/di-manual/index.html',
304 language = u'fr'
305 )
306
308 """http://ericmaeker.fr/FreeMedForms/di-manual/en/html/ligne_commandes.html"""
309
310 if not self.__detect_binary():
311 return False
312
313 self.__create_gm2fd_file()
314 open(self.__fd2gm_filename, 'wb').close()
315
316 args = u'--exchange-in="%s"' % (self.__gm2fd_filename)
317
318 cmd = r'%s %s' % (self.path_to_binary, args)
319
320
321
322
323
324
325
326
327
328 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
329 _log.error('problem switching to the FreeDiams drug database')
330 return False
331
332 return True
333
336
338 """FreeDiams ONLY use CIS.
339
340 CIS stands for Unique Speciality Identifier (eg bisoprolol 5 mg, gel).
341 CIS is AFSSAPS specific, but pharmacist can retreive drug name with the CIS.
342 AFSSAPS is the French FDA.
343
344 CIP stands for Unique Presentation Identifier (eg 30 pills plaq)
345 CIP if you want to specify the packaging of the drug (30 pills
346 thermoformed tablet...) -- actually not really usefull for french
347 doctors.
348 """
349 self.switch_to_frontend()
350
351
352
355
359
360
361
363
364 if self.path_to_binary is not None:
365 return True
366
367 found, cmd = gmShellAPI.find_first_binary(binaries = [
368 r'/usr/bin/freediams',
369 r'freediams',
370 r'/Applications/FreeDiams.app/Contents/MacOs/FreeDiams',
371 r'c:\programs\freediams\freediams.exe',
372 r'freediams.exe'
373 ])
374
375 if found:
376 self.path_to_binary = cmd
377 return True
378
379 try:
380 self.custom_path_to_binary
381 except AttributeError:
382 _log.error('cannot find FreeDiams binary, no custom path set')
383 return False
384
385 found, cmd = gmShellAPI.detect_external_binary(binary = self.custom_path_to_binary)
386 if found:
387 self.path_to_binary = cmd
388 return True
389
390 _log.error('cannot find FreeDiams binary')
391 return False
392
394
395 xml_file = codecs.open(self.__gm2fd_filename, 'wb', 'utf8')
396 if self.patient is None:
397 xml_file.close()
398 return
399
400 name = self.patient.get_active_name()
401 if self.patient['dob'] is None:
402 dob = u''
403 else:
404 dob = self.patient['dob'].strftime(cFreeDiamsInterface.default_dob_format)
405
406 emr = self.patient.get_emr()
407 allgs = emr.get_allergies()
408 atcs = [ a['atc_code'] for a in allgs if a['atc_code'] is not None ]
409 inns = [ a['allergene'] for a in allgs ]
410
411
412 uids = [ a['substance_code'] for a in allgs if a['substance_code'] is not None ]
413
414
415 xml = u"""<?xml version="1.0" encoding="UTF-8"?>
416
417 <FreeDiams_In version="0.4.2">
418 <EMR name="GNUmed" uid="unused"/>
419 <ConfigFile value="%s"/>
420 <OutFile value="%s" format="html_xml"/>
421 <Ui editmode="select-only" blockPatientDatas="1"/>
422 <Patient>
423 <Identity name="%s" surname="%s" uid="%s" dob="%s" gender="%s"/>
424 <ATCAllergies value="%s"/>
425 <InnAllergies value="%s"/>
426 <DrugsUidAllergies value="%s"/>
427 </Patient>
428 </FreeDiams_In>
429
430 <!--
431 <InnIntolerances value=""/>
432 <ATCIntolerances value="B05B"/>
433 <DrugsUidIntolerances value="68586203;62869109"/>
434 # FIXME: search by LOINC code and add (as soon as supported by FreeDiams ...)
435 <Creatinine value="12" unit="mg/l or mmol/l"/>
436 <Weight value="70" unit="kg or pd" />
437 <Height value="170" unit="cm or "/>
438 <ICD10 value="J11.0;A22;Z23"/>
439 -->
440 """ % (
441 self.__fd4gm_config_file,
442 self.__fd2gm_filename,
443 name['firstnames'], name['lastnames'], self.patient.ID, dob, cFreeDiamsInterface.map_gender2mf[self.patient['gender']],
444 u';'.join(atcs),
445 u';'.join(inns),
446 u';'.join(uids)
447 )
448
449 xml_file = codecs.open(self.__gm2fd_filename, 'wb', 'utf8')
450 xml_file.write(xml)
451 xml_file.close()
452
454
455
456
457
458
459
460 from xml.etree import ElementTree as etree
461
462 fd2gm_xml = etree.ElementTree()
463 fd2gm_xml.parse(self.__fd2gm_filename)
464
465 print fd2gm_xml
466
467
469 """Support v8.2 CSV file interface only."""
470
471 version = u'Gelbe Liste/MMI v8.2 interface'
472 default_encoding = 'cp1250'
473 bdt_line_template = u'%03d6210#%s\r\n'
474 bdt_line_base_length = 8
475
477
478 cDrugDataSourceInterface.__init__(self)
479
480 _log.info(u'%s (native Windows)', cGelbeListeWindowsInterface.version)
481
482 self.path_to_binary = r'C:\Programme\MMI PHARMINDEX\glwin.exe'
483 self.args = r'-KEEPBACKGROUND -PRESCRIPTIONFILE %s -CLOSETOTRAY'
484
485 paths = gmTools.gmPaths()
486
487 self.default_csv_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'rezept.txt')
488 self.default_csv_filename_arg = os.path.join(paths.home_dir, '.gnumed', 'tmp')
489 self.interactions_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'gm2mmi.bdt')
490 self.data_date_filename = r'C:\Programme\MMI PHARMINDEX\datadate.txt'
491
492 self.__data_date = None
493 self.__online_update_date = None
494
495
496
498
499 if self.__data_date is not None:
500 if not force_reload:
501 return {
502 'data': self.__data_date,
503 'online_update': self.__online_update_date
504 }
505
506 open(self.data_date_filename, 'wb').close()
507
508 cmd = u'%s -DATADATE' % self.path_to_binary
509 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = True):
510 _log.error('problem querying the MMI drug database for version information')
511 self.__data_date = None
512 self.__online_update_date = None
513 return {
514 'data': u'?',
515 'online_update': u'?'
516 }
517
518 try:
519 version_file = open(self.data_date_filename, 'rU')
520 except StandardError:
521 _log.error('problem querying the MMI drug database for version information')
522 _log.exception('cannot open MMI drug database version file [%s]', self.data_date_filename)
523 self.__data_date = None
524 self.__online_update_date = None
525 return {
526 'data': u'?',
527 'online_update': u'?'
528 }
529
530 self.__data_date = version_file.readline()[:10]
531 self.__online_update_date = version_file.readline()[:10]
532 version_file.close()
533
534 return {
535 'data': self.__data_date,
536 'online_update': self.__online_update_date
537 }
538
540 versions = self.get_data_source_version()
541
542 return create_data_source (
543 long_name = u'Medikamentendatenbank "mmi PHARMINDEX" (Gelbe Liste)',
544 short_name = u'GL/MMI',
545 version = u'Daten: %s, Preise (Onlineupdate): %s' % (versions['data'], versions['online_update']),
546 source = u'Medizinische Medien Informations GmbH, Am Forsthaus Gravenbruch 7, 63263 Neu-Isenburg',
547 language = u'de'
548 )
549
551
552
553 open(self.default_csv_filename, 'wb').close()
554
555 if cmd is None:
556 cmd = (u'%s %s' % (self.path_to_binary, self.args)) % self.default_csv_filename_arg
557
558 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
559 _log.error('problem switching to the MMI drug database')
560
561
562
563
564 return True
565
575
577
578 selected_drugs = self.select_drugs()
579 if selected_drugs is None:
580 return None
581
582 new_substances = []
583
584 for drug in selected_drugs:
585 atc = None
586 if len(drug['wirkstoffe']) == 1:
587 atc = drug['atc']
588 for wirkstoff in drug['wirkstoffe']:
589 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc))
590
591 selected_drugs.close()
592
593 return new_substances
594
596
597 selected_drugs = self.select_drugs()
598 if selected_drugs is None:
599 return None
600
601 data_src_pk = self.create_data_source_entry()
602
603 new_drugs = []
604 new_substances = []
605
606 for entry in selected_drugs:
607
608 _log.debug('importing drug: %s %s', entry['name'], entry['darreichungsform'])
609
610 if entry[u'hilfsmittel']:
611 _log.debug('skipping Hilfsmittel')
612 continue
613
614 if entry[u'erstattbares_medizinprodukt']:
615 _log.debug('skipping sonstiges Medizinprodukt')
616 continue
617
618
619 drug = create_branded_drug(brand_name = entry['name'], preparation = entry['darreichungsform'])
620 if drug is None:
621 drug = get_drug_by_brand(brand_name = entry['name'], preparation = entry['darreichungsform'])
622 new_drugs.append(drug)
623
624
625 drug['is_fake'] = False
626 drug['atc_code'] = entry['atc']
627 drug['external_code_type'] = u'DE-PZN'
628 drug['external_code'] = entry['pzn']
629 drug['fk_data_source'] = data_src_pk
630 drug.save()
631
632
633 atc = None
634 if len(entry['wirkstoffe']) == 1:
635 atc = entry['atc']
636 for wirkstoff in entry['wirkstoffe']:
637 drug.add_component(substance = wirkstoff, atc = atc)
638
639
640 atc = None
641 if len(entry['wirkstoffe']) == 1:
642 atc = entry['atc']
643 for wirkstoff in entry['wirkstoffe']:
644 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc))
645
646 return new_drugs, new_substances
647
676
695
697
699 cGelbeListeWindowsInterface.__init__(self)
700
701 _log.info(u'%s (WINE extension)', cGelbeListeWindowsInterface.version)
702
703
704 self.path_to_binary = r'wine "C:\Programme\MMI PHARMINDEX\glwin.exe"'
705 self.args = r'"-PRESCRIPTIONFILE %s -KEEPBACKGROUND"'
706
707 paths = gmTools.gmPaths()
708
709 self.default_csv_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'mmi2gm.csv')
710 self.default_csv_filename_arg = r'c:\windows\temp\mmi2gm.csv'
711 self.interactions_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'gm2mmi.bdt')
712 self.data_date_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'Programme', 'MMI PHARMINDEX', 'datadate.txt')
713
715 """empirical CSV interface"""
716
719
721
722 try:
723 csv_file = open(filename, 'rb')
724 except:
725 _log.exception('cannot access [%s]', filename)
726 csv_file = None
727
728 field_names = u'PZN Handelsname Form Abpackungsmenge Einheit Preis1 Hersteller Preis2 rezeptpflichtig Festbetrag Packungszahl Packungsgr\xf6\xdfe'.split()
729
730 if csv_file is None:
731 return False
732
733 csv_lines = csv.DictReader (
734 csv_file,
735 fieldnames = field_names,
736 delimiter = ';'
737 )
738
739 for line in csv_lines:
740 print "--------------------------------------------------------------------"[:31]
741 for key in field_names:
742 tmp = ('%s ' % key)[:30]
743 print '%s: %s' % (tmp, line[key])
744
745 csv_file.close()
746
747
748
749
750
751
752
753
754
755
756
757
758 drug_data_source_interfaces = {
759 'Deutschland: Gelbe Liste/MMI (Windows)': cGelbeListeWindowsInterface,
760 'Deutschland: Gelbe Liste/MMI (WINE)': cGelbeListeWineInterface,
761 'FreeDiams (France, US, Canada)': cFreeDiamsInterface
762 }
763
764
765
767 cmd = u'select * from clin.consumed_substance order by description'
768 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}])
769 return rows
770
772 cmd = u'select * from clin.consumed_substance WHERE pk = %(pk)s'
773 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'pk': pk}}])
774 if len(rows) == 0:
775 return None
776 return rows[0]
777
779
780 substance = substance.strip()
781
782 if atc is not None:
783 atc = atc.strip()
784
785 args = {'desc': substance, 'atc': atc}
786
787 cmd = u'select pk, atc_code, description from clin.consumed_substance where description = %(desc)s'
788 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
789
790 if len(rows) == 0:
791 cmd = u'insert into clin.consumed_substance (description, atc_code) values (%(desc)s, gm.nullify_empty_string(%(atc)s)) returning pk, atc_code, description'
792 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
793
794 gmATC.propagate_atc(substance = substance, atc = atc)
795
796 row = rows[0]
797
798
799 row[1] = args['atc']
800 return row
801
803 args = {'pk': substance}
804 cmd = u"""
805 delete from clin.consumed_substance
806 where
807 pk = %(pk)s and not exists (
808 select 1 from clin.substance_intake
809 where fk_substance = %(pk)s
810 )"""
811 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
812
813 -class cSubstanceIntakeEntry(gmBusinessDBObject.cBusinessDBObject):
814 """Represents a substance currently taken by a patient."""
815
816 _cmd_fetch_payload = u"select * from clin.v_pat_substance_intake where pk_substance_intake = %s"
817 _cmds_store_payload = [
818 u"""update clin.substance_intake set
819 clin_when = %(started)s,
820 discontinued = %(discontinued)s,
821 discontinue_reason = gm.nullify_empty_string(%(discontinue_reason)s),
822 strength = gm.nullify_empty_string(%(strength)s),
823 preparation = %(preparation)s,
824 schedule = gm.nullify_empty_string(%(schedule)s),
825 aim = gm.nullify_empty_string(%(aim)s),
826 narrative = gm.nullify_empty_string(%(notes)s),
827 intake_is_approved_of = %(intake_is_approved_of)s,
828
829 -- is_long_term = %(is_long_term)s,
830 is_long_term = (
831 case
832 when (
833 (%(is_long_term)s is False)
834 and
835 (%(duration)s is NULL)
836 ) is True then null
837 else %(is_long_term)s
838 end
839 )::boolean,
840 duration = (
841 case
842 when %(is_long_term)s is True then null
843 else %(duration)s
844 end
845 )::interval,
846
847 fk_brand = %(pk_brand)s,
848 fk_substance = %(pk_substance)s,
849 fk_episode = %(pk_episode)s
850 where
851 pk = %(pk_substance_intake)s and
852 xmin = %(xmin_substance_intake)s
853 returning
854 xmin as xmin_substance_intake
855 """
856 ]
857 _updatable_fields = [
858 u'started',
859 u'discontinued',
860 u'discontinue_reason',
861 u'preparation',
862 u'strength',
863 u'intake_is_approved_of',
864 u'schedule',
865 u'duration',
866 u'aim',
867 u'is_long_term',
868 u'notes',
869 u'pk_brand',
870 u'pk_substance',
871 u'pk_episode'
872 ]
873
874 - def format(self, left_margin=0, date_format='%Y-%m-%d'):
875
876 if self._payload[self._idx['duration']] is None:
877 duration = gmTools.bool2subst (
878 self._payload[self._idx['is_long_term']],
879 _('long-term'),
880 _('short-term'),
881 _('?short-term')
882 )
883 else:
884 duration = gmDateTime.format_interval (
885 self._payload[self._idx['duration']],
886 accuracy_wanted = gmDateTime.acc_days
887 )
888
889 line = u'%s%s (%s %s): %s %s %s (%s)' % (
890 u' ' * left_margin,
891 self._payload[self._idx['started']].strftime(date_format),
892 gmTools.u_right_arrow,
893 duration,
894 self._payload[self._idx['substance']],
895 gmTools.coalesce(self._payload[self._idx['strength']], u''),
896 self._payload[self._idx['preparation']],
897 gmTools.bool2subst(self._payload[self._idx['is_currently_active']], _('ongoing'), _('inactive'), _('?ongoing'))
898 )
899
900 return line
901
902 - def turn_into_allergy(self, encounter_id=None, allergy_type='allergy'):
903 allg = gmAllergy.create_allergy (
904 allergene = self._payload[self._idx['substance']],
905 allg_type = allergy_type,
906 episode_id = self._payload[self._idx['pk_episode']],
907 encounter_id = encounter_id
908 )
909 allg['substance'] = gmTools.coalesce (
910 self._payload[self._idx['brand']],
911 self._payload[self._idx['substance']]
912 )
913 allg['reaction'] = self._payload[self._idx['discontinue_reason']]
914 allg['atc_code'] = gmTools.coalesce(self._payload[self._idx['atc_substance']], self._payload[self._idx['atc_brand']])
915 if self._payload[self._idx['external_code_brand']] is not None:
916 allg['substance_code'] = u'%s::::%s' % (self._payload[self._idx['external_code_type_brand']], self._payload[self._idx['external_code_brand']])
917 allg['allergene'] = self._payload[self._idx['substance']]
918 comps = [ c['description'] for c in self.containing_drug.components ]
919 if len(comps) == 0:
920 allg['generics'] = self._payload[self._idx['substance']]
921 else:
922 allg['generics'] = u'; '.join(comps)
923
924 allg.save()
925 return allg
926
927
928
929 - def _get_ddd(self):
930
931 try: self.__ddd
932 except AttributeError: self.__ddd = None
933
934 if self.__ddd is not None:
935 return self.__ddd
936
937 if self._payload[self._idx['atc_substance']] is not None:
938 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_substance']])
939 if len(ddd) != 0:
940 self.__ddd = ddd[0]
941 else:
942 if self._payload[self._idx['atc_brand']] is not None:
943 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_brand']])
944 if len(ddd) != 0:
945 self.__ddd = ddd[0]
946
947 return self.__ddd
948
949 ddd = property(_get_ddd, lambda x:x)
950
952 drug = self.containing_drug
953
954 if drug is None:
955 return None
956
957 return drug.external_code
958
959 external_code = property(_get_external_code, lambda x:x)
960
962 drug = self.containing_drug
963
964 if drug is None:
965 return None
966
967 return drug.external_code_type
968
969 external_code_type = property(_get_external_code_type, lambda x:x)
970
972 if self._payload[self._idx['pk_brand']] is None:
973 return None
974
975 return cBrandedDrug(aPK_obj = self._payload[self._idx['pk_brand']])
976
977 containing_drug = property(_get_containing_drug, lambda x:x)
978
980 tests = [
981
982 ' 1-1-1-1 ',
983
984 '1-1-1-1',
985 '22-1-1-1',
986 '1/3-1-1-1',
987 '/4-1-1-1'
988 ]
989 pattern = "^(\d\d|/\d|\d/\d|\d)[\s-]{1,5}\d{0,2}[\s-]{1,5}\d{0,2}[\s-]{1,5}\d{0,2}$"
990 for test in tests:
991 print test.strip(), ":", regex.match(pattern, test.strip())
992
994
995 args = {
996 'enc': encounter,
997 'epi': episode,
998 'prep': preparation,
999 'subst': create_used_substance(substance = substance, atc = atc)['pk']
1000 }
1001
1002 cmd = u"""
1003 insert into clin.substance_intake (
1004 fk_encounter,
1005 fk_episode,
1006 fk_substance,
1007 preparation,
1008 intake_is_approved_of
1009 ) values (
1010 %(enc)s,
1011 %(epi)s,
1012 %(subst)s,
1013 gm.nullify_empty_string(%(prep)s),
1014 False
1015 )
1016 returning pk
1017 """
1018 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
1019 return cSubstanceIntakeEntry(aPK_obj = rows[0][0])
1020
1022 cmd = u'delete from clin.substance_intake where pk = %(pk)s'
1023 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': substance}}])
1024
1058
1059
1137
1139 """Represents a drug as marketed by a manufacturer."""
1140
1141 _cmd_fetch_payload = u"select *, xmin from ref.branded_drug where pk = %s"
1142 _cmds_store_payload = [
1143 u"""update ref.branded_drug set
1144 description = %(description)s,
1145 preparation = %(preparation)s,
1146 atc_code = gm.nullify_empty_string(%(atc_code)s),
1147 external_code = gm.nullify_empty_string(%(external_code)s),
1148 external_code_type = gm.nullify_empty_string(%(external_code_type)s),
1149 is_fake = %(is_fake)s,
1150 fk_data_source = %(fk_data_source)s
1151 where
1152 pk = %(pk)s and
1153 xmin = %(xmin)s
1154 returning
1155 xmin
1156 """
1157 ]
1158 _updatable_fields = [
1159 u'description',
1160 u'preparation',
1161 u'atc_code',
1162 u'is_fake',
1163 u'external_code',
1164 u'external_code_type',
1165 u'fk_data_source'
1166 ]
1167
1169 if self._payload[self._idx['external_code']] is None:
1170 return None
1171
1172 return self._payload[self._idx['external_code']]
1173
1174 external_code = property(_get_external_code, lambda x:x)
1175
1177
1178
1179 if self._payload[self._idx['external_code_type']] is None:
1180 return None
1181
1182 return self._payload[self._idx['external_code_type']]
1183
1184 external_code_type = property(_get_external_code_type, lambda x:x)
1185
1187 cmd = u'select * from ref.substance_in_brand where fk_brand = %(brand)s'
1188 args = {'brand': self._payload[self._idx['pk']]}
1189 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1190 return rows
1191
1192 components = property(_get_components, lambda x:x)
1193
1195 cmd = u'SELECT EXISTS (SELECT 1 FROM clin.vaccine WHERE fk_brand = %(fk_brand)s)'
1196 args = {'fk_brand': self._payload[self._idx['pk']]}
1197 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1198 return rows[0][0]
1199
1200 is_vaccine = property(_get_is_vaccine, lambda x:x)
1201
1203
1204
1205 atc = gmATC.propagate_atc(substance = substance, atc = atc)
1206
1207 args = {
1208 'brand': self.pk_obj,
1209 'desc': substance,
1210 'atc': atc
1211 }
1212
1213
1214 cmd = u"""
1215 SELECT pk
1216 FROM ref.substance_in_brand
1217 WHERE
1218 fk_brand = %(brand)s
1219 AND
1220 ((description = %(desc)s) OR ((atc_code = %(atc)s) IS TRUE))
1221 """
1222 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1223 if len(rows) > 0:
1224 return
1225
1226
1227 cmd = u"""
1228 INSERT INTO ref.substance_in_brand (fk_brand, description, atc_code)
1229 VALUES (%(brand)s, %(desc)s, %(atc)s)
1230 """
1231 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
1232
1235
1237 cmd = u'SELECT * FROM ref.v_substance_in_brand ORDER BY brand, substance'
1238 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
1239 return rows
1240
1242
1243 cmd = u'SELECT pk FROM ref.branded_drug ORDER BY description'
1244 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
1245
1246 return [ cBrandedDrug(aPK_obj = r['pk']) for r in rows ]
1247
1249 args = {'brand': brand_name, 'prep': preparation}
1250
1251 cmd = u'SELECT pk FROM ref.branded_drug WHERE description = %(brand)s AND preparation = %(prep)s'
1252 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1253
1254 if len(rows) == 0:
1255 return None
1256
1257 return cBrandedDrug(aPK_obj = rows[0]['pk'])
1258
1260
1261 if preparation is None:
1262 preparation = _('units')
1263
1264 if preparation.strip() == u'':
1265 preparation = _('units')
1266
1267 drug = get_drug_by_brand(brand_name = brand_name, preparation = preparation)
1268
1269 if drug is not None:
1270 if return_existing:
1271 return drug
1272 return None
1273
1274 cmd = u'insert into ref.branded_drug (description, preparation) values (%(brand)s, %(prep)s) returning pk'
1275 args = {'brand': brand_name, 'prep': preparation}
1276 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
1277
1278 return cBrandedDrug(aPK_obj = rows[0]['pk'])
1279
1283
1285 cmd = u'delete from ref.substance_in_brand where fk_brand = %(brand)s and pk = %(comp)s'
1286 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'brand': brand, 'comp': component}}])
1287
1288
1289
1290 if __name__ == "__main__":
1291
1292 if len(sys.argv) < 2:
1293 sys.exit()
1294
1295 if sys.argv[1] != 'test':
1296 sys.exit()
1297
1298 from Gnumed.pycommon import gmLog2
1299 from Gnumed.pycommon import gmI18N
1300 from Gnumed.business import gmPerson
1301
1302 gmI18N.activate_locale()
1303
1304
1310
1312 mmi_file = cGelbeListeCSVFile(filename = sys.argv[2])
1313 for drug in mmi_file:
1314 print "-------------"
1315 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])
1316 for stoff in drug['wirkstoffe']:
1317 print " Wirkstoff:", stoff
1318 print drug
1319 mmi_file.close()
1320
1324
1326 mmi = cGelbeListeWineInterface()
1327 mmi_file = mmi.select_drugs()
1328 for drug in mmi_file:
1329 print "-------------"
1330 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])
1331 for stoff in drug['wirkstoffe']:
1332 print " Wirkstoff:", stoff
1333 print drug
1334 mmi_file.close()
1335
1339
1341 mmi = cGelbeListeInterface()
1342 print mmi
1343 print "interface definition:", mmi.version
1344
1345 diclofenac = '7587712'
1346 phenprocoumon = '4421744'
1347 mmi.check_drug_interactions(drug_ids_list = [diclofenac, phenprocoumon])
1348
1349
1350
1357
1358
1359
1361 drug = create_substance_intake (
1362 substance = u'Whiskey',
1363 atc = u'no ATC available',
1364 encounter = 1,
1365 episode = 1,
1366 preparation = 'a nice glass'
1367 )
1368 print drug
1369
1374
1375
1376
1377
1378
1379
1380
1381 test_fd_switch_to()
1382
1383
1384
1385
1386