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
226
227 has_unknown_fields = property(_get_has_unknown_fields, lambda x:x)
228
230
231
233 self.patient = None
234 self.custom_path_to_binary = None
235
237 raise NotImplementedError
238
240 raise NotImplementedError
241
243 raise NotImplementedError
244
246 raise NotImplementedError
247
249 raise NotImplementedError
250
252 raise NotImplementedError
253
255 raise NotImplementedError
256
258
259 version = u'FreeDiams v0.4.2 interface'
260 default_encoding = 'utf8'
261 default_dob_format = '%Y/%m/%d'
262
263 map_gender2mf = {
264 'm': u'M',
265 'f': u'F',
266 'tf': u'H',
267 'tm': u'H',
268 'h': u'H'
269 }
270
282
284
285
286 if not self.__detect_binary():
287 return False
288
289 freediams = subprocess.Popen (
290 args = u'--version',
291 executable = self.path_to_binary,
292 stdout = subprocess.PIPE,
293 stderr = subprocess.PIPE,
294
295 universal_newlines = True
296 )
297 data, errors = freediams.communicate()
298 ver = regex.search('FreeDiams\s\d.\d.\d', data).group().split()[1]
299 _log.debug('FreeDiams %s', ver)
300
301 return version
302
304 return create_data_source (
305 long_name = u'"FreeDiams" Drug Database Frontend',
306 short_name = u'FreeDiams',
307 version = self.get_data_source_version(),
308 source = u'http://ericmaeker.fr/FreeMedForms/di-manual/index.html',
309 language = u'fr'
310 )
311
313 """http://ericmaeker.fr/FreeMedForms/di-manual/en/html/ligne_commandes.html"""
314
315 if not self.__detect_binary():
316 return False
317
318 self.__create_gm2fd_file()
319 open(self.__fd2gm_filename, 'wb').close()
320
321 args = u'--exchange-in="%s"' % (self.__gm2fd_filename)
322
323 cmd = r'%s %s' % (self.path_to_binary, args)
324
325
326
327
328
329
330
331
332
333 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
334 _log.error('problem switching to the FreeDiams drug database')
335 return False
336
337 return True
338
341
343 """FreeDiams ONLY use CIS.
344
345 CIS stands for Unique Speciality Identifier (eg bisoprolol 5 mg, gel).
346 CIS is AFSSAPS specific, but pharmacist can retreive drug name with the CIS.
347 AFSSAPS is the French FDA.
348
349 CIP stands for Unique Presentation Identifier (eg 30 pills plaq)
350 CIP if you want to specify the packaging of the drug (30 pills
351 thermoformed tablet...) -- actually not really usefull for french
352 doctors.
353 """
354 self.switch_to_frontend()
355
356
357
360
364
365
366
368
369 if self.path_to_binary is not None:
370 return True
371
372 found, cmd = gmShellAPI.find_first_binary(binaries = [
373 r'/usr/bin/freediams',
374 r'freediams',
375 r'/Applications/FreeDiams.app/Contents/MacOs/FreeDiams',
376 r'c:\programs\freediams\freediams.exe',
377 r'freediams.exe'
378 ])
379
380 if found:
381 self.path_to_binary = cmd
382 return True
383
384 try:
385 self.custom_path_to_binary
386 except AttributeError:
387 _log.error('cannot find FreeDiams binary, no custom path set')
388 return False
389
390 found, cmd = gmShellAPI.detect_external_binary(binary = self.custom_path_to_binary)
391 if found:
392 self.path_to_binary = cmd
393 return True
394
395 _log.error('cannot find FreeDiams binary')
396 return False
397
399
400 xml_file = codecs.open(self.__gm2fd_filename, 'wb', 'utf8')
401 if self.patient is None:
402 xml_file.close()
403 return
404
405 name = self.patient.get_active_name()
406 if self.patient['dob'] is None:
407 dob = u''
408 else:
409 dob = self.patient['dob'].strftime(cFreeDiamsInterface.default_dob_format)
410
411 emr = self.patient.get_emr()
412 allgs = emr.get_allergies()
413 atcs = [ a['atc_code'] for a in allgs if a['atc_code'] is not None ]
414 inns = [ a['allergene'] for a in allgs ]
415
416
417 uids = [ a['substance_code'] for a in allgs if a['substance_code'] is not None ]
418
419
420 xml = u"""<?xml version="1.0" encoding="UTF-8"?>
421
422 <FreeDiams_In version="0.4.2">
423 <EMR name="GNUmed" uid="unused"/>
424 <ConfigFile value="%s"/>
425 <OutFile value="%s" format="html_xml"/>
426 <Ui editmode="select-only" blockPatientDatas="1"/>
427 <Patient>
428 <Identity name="%s" surname="%s" uid="%s" dob="%s" gender="%s"/>
429 <ATCAllergies value="%s"/>
430 <InnAllergies value="%s"/>
431 <DrugsUidAllergies value="%s"/>
432 </Patient>
433 </FreeDiams_In>
434
435 <!--
436 <InnIntolerances value=""/>
437 <ATCIntolerances value="B05B"/>
438 <DrugsUidIntolerances value="68586203;62869109"/>
439 # FIXME: search by LOINC code and add (as soon as supported by FreeDiams ...)
440 <Creatinine value="12" unit="mg/l or mmol/l"/>
441 <Weight value="70" unit="kg or pd" />
442 <Height value="170" unit="cm or "/>
443 <ICD10 value="J11.0;A22;Z23"/>
444 -->
445 """ % (
446 self.__fd4gm_config_file,
447 self.__fd2gm_filename,
448 name['firstnames'], name['lastnames'], self.patient.ID, dob, cFreeDiamsInterface.map_gender2mf[self.patient['gender']],
449 u';'.join(atcs),
450 u';'.join(inns),
451 u';'.join(uids)
452 )
453
454 xml_file = codecs.open(self.__gm2fd_filename, 'wb', 'utf8')
455 xml_file.write(xml)
456 xml_file.close()
457
459
460
461
462
463
464
465 from xml.etree import ElementTree as etree
466
467 fd2gm_xml = etree.ElementTree()
468 fd2gm_xml.parse(self.__fd2gm_filename)
469
470 print fd2gm_xml
471
472
474 """Support v8.2 CSV file interface only."""
475
476 version = u'Gelbe Liste/MMI v8.2 interface'
477 default_encoding = 'cp1250'
478 bdt_line_template = u'%03d6210#%s\r\n'
479 bdt_line_base_length = 8
480
482
483 cDrugDataSourceInterface.__init__(self)
484
485 _log.info(u'%s (native Windows)', cGelbeListeWindowsInterface.version)
486
487 self.path_to_binary = r'C:\Programme\MMI PHARMINDEX\glwin.exe'
488 self.args = r'-KEEPBACKGROUND -PRESCRIPTIONFILE %s -CLOSETOTRAY'
489
490 paths = gmTools.gmPaths()
491
492 self.default_csv_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'rezept.txt')
493 self.default_csv_filename_arg = os.path.join(paths.home_dir, '.gnumed', 'tmp')
494 self.interactions_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'gm2mmi.bdt')
495 self.data_date_filename = r'C:\Programme\MMI PHARMINDEX\datadate.txt'
496
497 self.__data_date = None
498 self.__online_update_date = None
499
500
501
503
504 if self.__data_date is not None:
505 if not force_reload:
506 return {
507 'data': self.__data_date,
508 'online_update': self.__online_update_date
509 }
510
511 open(self.data_date_filename, 'wb').close()
512
513 cmd = u'%s -DATADATE' % self.path_to_binary
514 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = True):
515 _log.error('problem querying the MMI drug database for version information')
516 self.__data_date = None
517 self.__online_update_date = None
518 return {
519 'data': u'?',
520 'online_update': u'?'
521 }
522
523 try:
524 version_file = open(self.data_date_filename, 'rU')
525 except StandardError:
526 _log.error('problem querying the MMI drug database for version information')
527 _log.exception('cannot open MMI drug database version file [%s]', self.data_date_filename)
528 self.__data_date = None
529 self.__online_update_date = None
530 return {
531 'data': u'?',
532 'online_update': u'?'
533 }
534
535 self.__data_date = version_file.readline()[:10]
536 self.__online_update_date = version_file.readline()[:10]
537 version_file.close()
538
539 return {
540 'data': self.__data_date,
541 'online_update': self.__online_update_date
542 }
543
545 versions = self.get_data_source_version()
546
547 return create_data_source (
548 long_name = u'Medikamentendatenbank "mmi PHARMINDEX" (Gelbe Liste)',
549 short_name = u'GL/MMI',
550 version = u'Daten: %s, Preise (Onlineupdate): %s' % (versions['data'], versions['online_update']),
551 source = u'Medizinische Medien Informations GmbH, Am Forsthaus Gravenbruch 7, 63263 Neu-Isenburg',
552 language = u'de'
553 )
554
556
557
558 open(self.default_csv_filename, 'wb').close()
559
560 if cmd is None:
561 cmd = (u'%s %s' % (self.path_to_binary, self.args)) % self.default_csv_filename_arg
562
563 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
564 _log.error('problem switching to the MMI drug database')
565
566
567
568
569 return True
570
580
582
583 selected_drugs = self.select_drugs()
584 if selected_drugs is None:
585 return None
586
587 new_substances = []
588
589 for drug in selected_drugs:
590 atc = None
591 if len(drug['wirkstoffe']) == 1:
592 atc = drug['atc']
593 for wirkstoff in drug['wirkstoffe']:
594 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc))
595
596 selected_drugs.close()
597
598 return new_substances
599
601
602 selected_drugs = self.select_drugs()
603 if selected_drugs is None:
604 return None
605
606 data_src_pk = self.create_data_source_entry()
607
608 new_drugs = []
609 new_substances = []
610
611 for entry in selected_drugs:
612
613 _log.debug('importing drug: %s %s', entry['name'], entry['darreichungsform'])
614
615 if entry[u'hilfsmittel']:
616 _log.debug('skipping Hilfsmittel')
617 continue
618
619 if entry[u'erstattbares_medizinprodukt']:
620 _log.debug('skipping sonstiges Medizinprodukt')
621 continue
622
623
624 drug = create_branded_drug(brand_name = entry['name'], preparation = entry['darreichungsform'])
625 if drug is None:
626 drug = get_drug_by_brand(brand_name = entry['name'], preparation = entry['darreichungsform'])
627 new_drugs.append(drug)
628
629
630 drug['is_fake'] = False
631 drug['atc_code'] = entry['atc']
632 drug['external_code_type'] = u'DE-PZN'
633 drug['external_code'] = entry['pzn']
634 drug['fk_data_source'] = data_src_pk
635 drug.save()
636
637
638 atc = None
639 if len(entry['wirkstoffe']) == 1:
640 atc = entry['atc']
641 for wirkstoff in entry['wirkstoffe']:
642 drug.add_component(substance = wirkstoff, atc = atc)
643
644
645 atc = None
646 if len(entry['wirkstoffe']) == 1:
647 atc = entry['atc']
648 for wirkstoff in entry['wirkstoffe']:
649 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc))
650
651 return new_drugs, new_substances
652
681
700
702
704 cGelbeListeWindowsInterface.__init__(self)
705
706 _log.info(u'%s (WINE extension)', cGelbeListeWindowsInterface.version)
707
708
709 self.path_to_binary = r'wine "C:\Programme\MMI PHARMINDEX\glwin.exe"'
710 self.args = r'"-PRESCRIPTIONFILE %s -KEEPBACKGROUND"'
711
712 paths = gmTools.gmPaths()
713
714 self.default_csv_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'mmi2gm.csv')
715 self.default_csv_filename_arg = r'c:\windows\temp\mmi2gm.csv'
716 self.interactions_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'gm2mmi.bdt')
717 self.data_date_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'Programme', 'MMI PHARMINDEX', 'datadate.txt')
718
720 """empirical CSV interface"""
721
724
726
727 try:
728 csv_file = open(filename, 'rb')
729 except:
730 _log.exception('cannot access [%s]', filename)
731 csv_file = None
732
733 field_names = u'PZN Handelsname Form Abpackungsmenge Einheit Preis1 Hersteller Preis2 rezeptpflichtig Festbetrag Packungszahl Packungsgr\xf6\xdfe'.split()
734
735 if csv_file is None:
736 return False
737
738 csv_lines = csv.DictReader (
739 csv_file,
740 fieldnames = field_names,
741 delimiter = ';'
742 )
743
744 for line in csv_lines:
745 print "--------------------------------------------------------------------"[:31]
746 for key in field_names:
747 tmp = ('%s ' % key)[:30]
748 print '%s: %s' % (tmp, line[key])
749
750 csv_file.close()
751
752
753
754
755
756
757
758
759
760
761
762
763 drug_data_source_interfaces = {
764 'Deutschland: Gelbe Liste/MMI (Windows)': cGelbeListeWindowsInterface,
765 'Deutschland: Gelbe Liste/MMI (WINE)': cGelbeListeWineInterface,
766 'FreeDiams (France, US, Canada)': cFreeDiamsInterface
767 }
768
769
770
772 cmd = u'select * from clin.consumed_substance order by description'
773 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}])
774 return rows
775
777 cmd = u'SELECT * FROM clin.consumed_substance WHERE pk = %(pk)s'
778 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'pk': pk}}])
779 if len(rows) == 0:
780 return None
781 return rows[0]
782
784
785 substance = substance.strip()
786
787 if atc is not None:
788 atc = atc.strip()
789
790 args = {'desc': substance, 'atc': atc}
791
792 cmd = u'select pk, atc_code, description from clin.consumed_substance where description = %(desc)s'
793 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
794
795 if len(rows) == 0:
796 cmd = u'insert into clin.consumed_substance (description, atc_code) values (%(desc)s, gm.nullify_empty_string(%(atc)s)) returning pk, atc_code, description'
797 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
798
799 gmATC.propagate_atc(substance = substance, atc = atc)
800
801 row = rows[0]
802
803
804 row[1] = args['atc']
805 return row
806
808 args = {'pk': substance}
809 cmd = u"""
810 delete from clin.consumed_substance
811 where
812 pk = %(pk)s and not exists (
813 select 1 from clin.substance_intake
814 where fk_substance = %(pk)s
815 )"""
816 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
817
818 -class cSubstanceIntakeEntry(gmBusinessDBObject.cBusinessDBObject):
819 """Represents a substance currently taken by a patient."""
820
821 _cmd_fetch_payload = u"select * from clin.v_pat_substance_intake where pk_substance_intake = %s"
822 _cmds_store_payload = [
823 u"""update clin.substance_intake set
824 clin_when = %(started)s,
825 discontinued = %(discontinued)s,
826 discontinue_reason = gm.nullify_empty_string(%(discontinue_reason)s),
827 strength = gm.nullify_empty_string(%(strength)s),
828 preparation = %(preparation)s,
829 schedule = gm.nullify_empty_string(%(schedule)s),
830 aim = gm.nullify_empty_string(%(aim)s),
831 narrative = gm.nullify_empty_string(%(notes)s),
832 intake_is_approved_of = %(intake_is_approved_of)s,
833
834 -- is_long_term = %(is_long_term)s,
835 is_long_term = (
836 case
837 when (
838 (%(is_long_term)s is False)
839 and
840 (%(duration)s is NULL)
841 ) is True then null
842 else %(is_long_term)s
843 end
844 )::boolean,
845 duration = (
846 case
847 when %(is_long_term)s is True then null
848 else %(duration)s
849 end
850 )::interval,
851
852 fk_brand = %(pk_brand)s,
853 fk_substance = %(pk_substance)s,
854 fk_episode = %(pk_episode)s
855 where
856 pk = %(pk_substance_intake)s and
857 xmin = %(xmin_substance_intake)s
858 returning
859 xmin as xmin_substance_intake
860 """
861 ]
862 _updatable_fields = [
863 u'started',
864 u'discontinued',
865 u'discontinue_reason',
866 u'preparation',
867 u'strength',
868 u'intake_is_approved_of',
869 u'schedule',
870 u'duration',
871 u'aim',
872 u'is_long_term',
873 u'notes',
874 u'pk_brand',
875 u'pk_substance',
876 u'pk_episode'
877 ]
878
879 - def format(self, left_margin=0, date_format='%Y-%m-%d'):
880
881 if self._payload[self._idx['duration']] is None:
882 duration = gmTools.bool2subst (
883 self._payload[self._idx['is_long_term']],
884 _('long-term'),
885 _('short-term'),
886 _('?short-term')
887 )
888 else:
889 duration = gmDateTime.format_interval (
890 self._payload[self._idx['duration']],
891 accuracy_wanted = gmDateTime.acc_days
892 )
893
894 line = u'%s%s (%s %s): %s %s %s (%s)' % (
895 u' ' * left_margin,
896 self._payload[self._idx['started']].strftime(date_format),
897 gmTools.u_right_arrow,
898 duration,
899 self._payload[self._idx['substance']],
900 gmTools.coalesce(self._payload[self._idx['strength']], u''),
901 self._payload[self._idx['preparation']],
902 gmTools.bool2subst(self._payload[self._idx['is_currently_active']], _('ongoing'), _('inactive'), _('?ongoing'))
903 )
904
905 return line
906
907 - def turn_into_allergy(self, encounter_id=None, allergy_type='allergy'):
908 allg = gmAllergy.create_allergy (
909 allergene = self._payload[self._idx['substance']],
910 allg_type = allergy_type,
911 episode_id = self._payload[self._idx['pk_episode']],
912 encounter_id = encounter_id
913 )
914 allg['substance'] = gmTools.coalesce (
915 self._payload[self._idx['brand']],
916 self._payload[self._idx['substance']]
917 )
918 allg['reaction'] = self._payload[self._idx['discontinue_reason']]
919 allg['atc_code'] = gmTools.coalesce(self._payload[self._idx['atc_substance']], self._payload[self._idx['atc_brand']])
920 if self._payload[self._idx['external_code_brand']] is not None:
921 allg['substance_code'] = u'%s::::%s' % (self._payload[self._idx['external_code_type_brand']], self._payload[self._idx['external_code_brand']])
922 allg['allergene'] = self._payload[self._idx['substance']]
923 comps = [ c['description'] for c in self.containing_drug.components ]
924 if len(comps) == 0:
925 allg['generics'] = self._payload[self._idx['substance']]
926 else:
927 allg['generics'] = u'; '.join(comps)
928
929 allg.save()
930 return allg
931
932
933
934 - def _get_ddd(self):
935
936 try: self.__ddd
937 except AttributeError: self.__ddd = None
938
939 if self.__ddd is not None:
940 return self.__ddd
941
942 if self._payload[self._idx['atc_substance']] is not None:
943 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_substance']])
944 if len(ddd) != 0:
945 self.__ddd = ddd[0]
946 else:
947 if self._payload[self._idx['atc_brand']] is not None:
948 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_brand']])
949 if len(ddd) != 0:
950 self.__ddd = ddd[0]
951
952 return self.__ddd
953
954 ddd = property(_get_ddd, lambda x:x)
955
957 drug = self.containing_drug
958
959 if drug is None:
960 return None
961
962 return drug.external_code
963
964 external_code = property(_get_external_code, lambda x:x)
965
967 drug = self.containing_drug
968
969 if drug is None:
970 return None
971
972 return drug.external_code_type
973
974 external_code_type = property(_get_external_code_type, lambda x:x)
975
977 if self._payload[self._idx['pk_brand']] is None:
978 return None
979
980 return cBrandedDrug(aPK_obj = self._payload[self._idx['pk_brand']])
981
982 containing_drug = property(_get_containing_drug, lambda x:x)
983
985 tests = [
986
987 ' 1-1-1-1 ',
988
989 '1-1-1-1',
990 '22-1-1-1',
991 '1/3-1-1-1',
992 '/4-1-1-1'
993 ]
994 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}$"
995 for test in tests:
996 print test.strip(), ":", regex.match(pattern, test.strip())
997
999
1000 args = {
1001 'enc': encounter,
1002 'epi': episode,
1003 'prep': preparation,
1004 'subst': create_used_substance(substance = substance, atc = atc)['pk']
1005 }
1006
1007 cmd = u"""
1008 insert into clin.substance_intake (
1009 fk_encounter,
1010 fk_episode,
1011 fk_substance,
1012 preparation,
1013 intake_is_approved_of
1014 ) values (
1015 %(enc)s,
1016 %(epi)s,
1017 %(subst)s,
1018 gm.nullify_empty_string(%(prep)s),
1019 False
1020 )
1021 returning pk
1022 """
1023 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
1024 return cSubstanceIntakeEntry(aPK_obj = rows[0][0])
1025
1027 cmd = u'delete from clin.substance_intake where pk = %(pk)s'
1028 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': substance}}])
1029
1063
1064
1142
1144 """Represents a drug as marketed by a manufacturer."""
1145
1146 _cmd_fetch_payload = u"select *, xmin from ref.branded_drug where pk = %s"
1147 _cmds_store_payload = [
1148 u"""update ref.branded_drug set
1149 description = %(description)s,
1150 preparation = %(preparation)s,
1151 atc_code = gm.nullify_empty_string(%(atc_code)s),
1152 external_code = gm.nullify_empty_string(%(external_code)s),
1153 external_code_type = gm.nullify_empty_string(%(external_code_type)s),
1154 is_fake = %(is_fake)s,
1155 fk_data_source = %(fk_data_source)s
1156 where
1157 pk = %(pk)s and
1158 xmin = %(xmin)s
1159 returning
1160 xmin
1161 """
1162 ]
1163 _updatable_fields = [
1164 u'description',
1165 u'preparation',
1166 u'atc_code',
1167 u'is_fake',
1168 u'external_code',
1169 u'external_code_type',
1170 u'fk_data_source'
1171 ]
1172
1174 if self._payload[self._idx['external_code']] is None:
1175 return None
1176
1177 return self._payload[self._idx['external_code']]
1178
1179 external_code = property(_get_external_code, lambda x:x)
1180
1182
1183
1184 if self._payload[self._idx['external_code_type']] is None:
1185 return None
1186
1187 return self._payload[self._idx['external_code_type']]
1188
1189 external_code_type = property(_get_external_code_type, lambda x:x)
1190
1192 cmd = u'select * from ref.substance_in_brand where fk_brand = %(brand)s'
1193 args = {'brand': self._payload[self._idx['pk']]}
1194 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1195 return rows
1196
1197 components = property(_get_components, lambda x:x)
1198
1200 cmd = u'SELECT EXISTS (SELECT 1 FROM clin.vaccine WHERE fk_brand = %(fk_brand)s)'
1201 args = {'fk_brand': self._payload[self._idx['pk']]}
1202 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1203 return rows[0][0]
1204
1205 is_vaccine = property(_get_is_vaccine, lambda x:x)
1206
1208
1209
1210 atc = gmATC.propagate_atc(substance = substance, atc = atc)
1211
1212 args = {
1213 'brand': self.pk_obj,
1214 'desc': substance,
1215 'atc': atc
1216 }
1217
1218
1219 cmd = u"""
1220 SELECT pk
1221 FROM ref.substance_in_brand
1222 WHERE
1223 fk_brand = %(brand)s
1224 AND
1225 ((description = %(desc)s) OR ((atc_code = %(atc)s) IS TRUE))
1226 """
1227 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1228 if len(rows) > 0:
1229 return
1230
1231
1232 cmd = u"""
1233 INSERT INTO ref.substance_in_brand (fk_brand, description, atc_code)
1234 VALUES (%(brand)s, %(desc)s, %(atc)s)
1235 """
1236 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
1237
1240
1242 cmd = u'SELECT * FROM ref.v_substance_in_brand ORDER BY brand, substance'
1243 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
1244 return rows
1245
1247
1248 cmd = u'SELECT pk FROM ref.branded_drug ORDER BY description'
1249 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
1250
1251 return [ cBrandedDrug(aPK_obj = r['pk']) for r in rows ]
1252
1254 args = {'brand': brand_name, 'prep': preparation}
1255
1256 cmd = u'SELECT pk FROM ref.branded_drug WHERE description = %(brand)s AND preparation = %(prep)s'
1257 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1258
1259 if len(rows) == 0:
1260 return None
1261
1262 return cBrandedDrug(aPK_obj = rows[0]['pk'])
1263
1265
1266 if preparation is None:
1267 preparation = _('units')
1268
1269 if preparation.strip() == u'':
1270 preparation = _('units')
1271
1272 drug = get_drug_by_brand(brand_name = brand_name, preparation = preparation)
1273
1274 if drug is not None:
1275 if return_existing:
1276 return drug
1277 return None
1278
1279 cmd = u'insert into ref.branded_drug (description, preparation) values (%(brand)s, %(prep)s) returning pk'
1280 args = {'brand': brand_name, 'prep': preparation}
1281 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
1282
1283 return cBrandedDrug(aPK_obj = rows[0]['pk'])
1284
1288
1290 cmd = u'delete from ref.substance_in_brand where fk_brand = %(brand)s and pk = %(comp)s'
1291 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'brand': brand, 'comp': component}}])
1292
1293
1294
1295 if __name__ == "__main__":
1296
1297 if len(sys.argv) < 2:
1298 sys.exit()
1299
1300 if sys.argv[1] != 'test':
1301 sys.exit()
1302
1303 from Gnumed.pycommon import gmLog2
1304 from Gnumed.pycommon import gmI18N
1305 from Gnumed.business import gmPerson
1306
1307 gmI18N.activate_locale()
1308
1309
1315
1317 mmi_file = cGelbeListeCSVFile(filename = sys.argv[2])
1318 for drug in mmi_file:
1319 print "-------------"
1320 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])
1321 for stoff in drug['wirkstoffe']:
1322 print " Wirkstoff:", stoff
1323 raw_input()
1324 if mmi_file.has_unknown_fields is not None:
1325 print "has extra data under [%s]" % gmTools.default_csv_reader_rest_key
1326 for key in mmi_file.csv_fieldnames:
1327 print key, '->', drug[key]
1328 raw_input()
1329 mmi_file.close()
1330
1334
1336 mmi = cGelbeListeWineInterface()
1337 mmi_file = mmi.select_drugs()
1338 for drug in mmi_file:
1339 print "-------------"
1340 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])
1341 for stoff in drug['wirkstoffe']:
1342 print " Wirkstoff:", stoff
1343 print drug
1344 mmi_file.close()
1345
1349
1351 mmi = cGelbeListeInterface()
1352 print mmi
1353 print "interface definition:", mmi.version
1354
1355 diclofenac = '7587712'
1356 phenprocoumon = '4421744'
1357 mmi.check_drug_interactions(drug_ids_list = [diclofenac, phenprocoumon])
1358
1359
1360
1367
1368
1369
1371 drug = create_substance_intake (
1372 substance = u'Whiskey',
1373 atc = u'no ATC available',
1374 encounter = 1,
1375 episode = 1,
1376 preparation = 'a nice glass'
1377 )
1378 print drug
1379
1384
1385
1386 test_MMI_file()
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396