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
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 url_template = u'http://www.google.de/#q=site%%3Adosing.de+%s'
61 url = url_template % u'+OR+'.join(terms)
62
63 _log.debug(u'renal insufficiency URL: %s', url)
64
65 return url
66
67
68 -def create_data_source(long_name=None, short_name=None, version=None, source=None, language=None):
69
70 args = {
71 'lname': long_name,
72 'sname': short_name,
73 'ver': version,
74 'src': source,
75 'lang': language
76 }
77
78 cmd = u"""select pk from ref.data_source where name_long = %(lname)s and name_short = %(sname)s and version = %(ver)s"""
79 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
80 if len(rows) > 0:
81 return rows[0]['pk']
82
83 cmd = u"""
84 INSERT INTO ref.data_source (name_long, name_short, version, source, lang)
85 VALUES (
86 %(lname)s,
87 %(sname)s,
88 %(ver)s,
89 %(src)s,
90 %(lang)s
91 )
92 returning pk
93 """
94 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
95
96 return rows[0]['pk']
97
98
99
100
101
102
103
105 """Iterator over a Gelbe Liste/MMI v8.2 CSV file."""
106
107 version = u'Gelbe Liste/MMI v8.2 CSV file interface'
108 default_transfer_file_windows = r"c:\rezept.txt"
109
110 default_encoding = 'cp1250'
111 csv_fieldnames = [
112 u'name',
113 u'packungsgroesse',
114 u'darreichungsform',
115 u'packungstyp',
116 u'festbetrag',
117 u'avp',
118 u'hersteller',
119 u'rezepttext',
120 u'pzn',
121 u'status_vertrieb',
122 u'status_rezeptpflicht',
123 u'status_fachinfo',
124 u'btm',
125 u'atc',
126 u'anzahl_packungen',
127 u'zuzahlung_pro_packung',
128 u'einheit',
129 u'schedule_morgens',
130 u'schedule_mittags',
131 u'schedule_abends',
132 u'schedule_nachts',
133 u'status_dauermedikament',
134 u'status_hausliste',
135 u'status_negativliste',
136 u'ik_nummer',
137 u'status_rabattvertrag',
138 u'wirkstoffe',
139 u'wirkstoffmenge',
140 u'wirkstoffeinheit',
141 u'wirkstoffmenge_bezug',
142 u'wirkstoffmenge_bezugseinheit',
143 u'status_import',
144 u'status_lifestyle',
145 u'status_ausnahmeliste',
146 u'packungsmenge',
147 u'apothekenpflicht',
148 u'status_billigere_packung',
149 u'rezepttyp',
150 u'besonderes_arzneimittel',
151 u't_rezept_pflicht',
152 u'erstattbares_medizinprodukt',
153 u'hilfsmittel',
154 u'hzv_rabattkennung',
155 u'hzv_preis'
156 ]
157 boolean_fields = [
158 u'status_rezeptpflicht',
159 u'status_fachinfo',
160 u'btm',
161 u'status_dauermedikament',
162 u'status_hausliste',
163 u'status_negativliste',
164 u'status_rabattvertrag',
165 u'status_import',
166 u'status_lifestyle',
167 u'status_ausnahmeliste',
168 u'apothekenpflicht',
169 u'status_billigere_packung',
170 u'besonderes_arzneimittel',
171 u't_rezept_pflicht',
172 u'erstattbares_medizinprodukt',
173 u'hilfsmittel'
174 ]
175
195
198
200 line = self.csv_lines.next()
201
202 for field in cGelbeListeCSVFile.boolean_fields:
203 line[field] = (line[field].strip() == u'T')
204
205
206 if line['wirkstoffe'].strip() == u'':
207 line['wirkstoffe'] = []
208 else:
209 line['wirkstoffe'] = [ wirkstoff.strip() for wirkstoff in line['wirkstoffe'].split(u';') ]
210
211 return line
212
213 - def close(self, truncate=True):
214 try: self.csv_file.close()
215 except: pass
216
217 if truncate:
218 try: os.open(self.filename, 'wb').close
219 except: pass
220
222
223
225 self.patient = None
226 self.custom_path_to_binary = None
227
229 raise NotImplementedError
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
251 """http://ericmaeker.fr/FreeMedForms/di-manual/ligne_commandes.html"""
252
253 version = u'FreeDiams v0.3.0 interface'
254 default_encoding = 'utf8'
255 default_dob_format = '%d/%m/%Y'
256
257 map_gender2mf = {
258 'm': u'M',
259 'f': u'F',
260 'tf': u'F',
261 'tm': u'M',
262 'h': u'H'
263 }
264
271
273
274
275 return u'0.3.0'
276
277
279 return create_data_source (
280 long_name = u'"FreeDiams" Drug Database Frontend',
281 short_name = u'FreeDiams',
282 version = self.get_data_source_version(),
283 source = u'http://ericmaeker.fr/FreeMedForms/di-manual/index.html',
284 language = u'fr'
285 )
286
288 """ --medintux : définit une utilisation spécifique à MedinTux.
289 --exchange="xxx" : définit le fichier d'échange entre les deux applications.
290 --chrono : Chronomètres diverses fonctions du testeur d'interactions (proposé à des fins de déboggage)
291 --transmit-dosage = non documenté.
292 """
293 found, cmd = gmShellAPI.find_first_binary(binaries = [
294 self.custom_path_to_binary,
295 r'/usr/bin/freediams',
296 r'freediams',
297 r'/Applications/FreeDiams.app/Contents/MacOs/FreeDiams',
298 r'c:\programs\freediams\freediams.exe',
299 r'freediams.exe'
300 ])
301
302 if not found:
303 _log.error('cannot find FreeDiams binary')
304 return False
305
306
307 open(self.__exchange_filename, 'wb').close()
308 args = u'--exchange="%s"' % self.__exchange_filename
309
310 if self.patient is not None:
311
312 args += u' --patientname="%(firstnames)s %(lastnames)s"' % self.patient.get_active_name()
313
314 args += u' --gender=%s' % cFreeDiamsInterface.map_gender2mf[self.patient['gender']]
315
316 if self.patient['dob'] is not None:
317 args += u' --dateofbirth="%s"' % self.patient['dob'].strftime(cFreeDiamsInterface.default_dob_format)
318
319
320
321
322
323
324
325 cmd = r'%s %s' % (cmd, args)
326
327 if not gmShellAPI.run_command_in_shell(command = cmd):
328 _log.error('problem switching to the FreeDiams drug database')
329 return False
330
331 return True
332
335
337 """FreeDiams ONLY use CIS.
338
339 CIS stands for Unique Speciality Identifier (eg bisoprolol 5 mg, gel).
340 CIS is AFSSAPS specific, but pharmacist can retreive drug name with the CIS.
341 AFSSAPS is the French FDA.
342
343 CIP stands for Unique Presentation Identifier (eg 30 pills plaq)
344 CIP if you want to specify the packaging of the drug (30 pills
345 thermoformed tablet...) -- actually not really usefull for french
346 doctors.
347 """
348 self.switch_to_frontend()
349
350
351
354
358
360 """Support v8.2 CSV file interface only."""
361
362 version = u'Gelbe Liste/MMI v8.2 interface'
363 default_encoding = 'cp1250'
364 bdt_line_template = u'%03d6210#%s\r\n'
365 bdt_line_base_length = 8
366
368
369 cDrugDataSourceInterface.__init__(self)
370
371 _log.info(u'%s (native Windows)', cGelbeListeWindowsInterface.version)
372
373 self.path_to_binary = r'C:\Programme\MMI PHARMINDEX\glwin.exe'
374 self.args = r'-KEEPBACKGROUND -PRESCRIPTIONFILE %s -CLOSETOTRAY'
375
376 paths = gmTools.gmPaths()
377
378 self.default_csv_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'rezept.txt')
379 self.default_csv_filename_arg = os.path.join(paths.home_dir, '.gnumed', 'tmp')
380 self.interactions_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'gm2mmi.bdt')
381 self.data_date_filename = r'C:\Programme\MMI PHARMINDEX\datadate.txt'
382
383 self.__data_date = None
384 self.__online_update_date = None
385
386
387
389
390 if self.__data_date is not None:
391 if not force_reload:
392 return {
393 'data': self.__data_date,
394 'online_update': self.__online_update_date
395 }
396
397 open(self.data_date_filename, 'wb').close()
398
399 cmd = u'%s -DATADATE' % self.path_to_binary
400 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = True):
401 _log.error('problem querying the MMI drug database for version information')
402 self.__data_date = None
403 self.__online_update_date = None
404 return {
405 'data': u'?',
406 'online_update': u'?'
407 }
408
409 version_file = open(self.data_date_filename, 'rU')
410 self.__data_date = version_file.readline()[:10]
411 self.__online_update_date = version_file.readline()[:10]
412 version_file.close()
413
414 return {
415 'data': self.__data_date,
416 'online_update': self.__online_update_date
417 }
418
420 versions = self.get_data_source_version()
421
422 return create_data_source (
423 long_name = u'Medikamentendatenbank "mmi PHARMINDEX" (Gelbe Liste)',
424 short_name = u'GL/MMI',
425 version = u'Daten: %s, Preise (Onlineupdate): %s' % (versions['data'], versions['online_update']),
426 source = u'Medizinische Medien Informations GmbH, Am Forsthaus Gravenbruch 7, 63263 Neu-Isenburg',
427 language = u'de'
428 )
429
431
432
433 open(self.default_csv_filename, 'wb').close()
434
435 if cmd is None:
436 cmd = (u'%s %s' % (self.path_to_binary, self.args)) % self.default_csv_filename_arg
437
438 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
439 _log.error('problem switching to the MMI drug database')
440
441
442
443
444 return True
445
455
457
458 selected_drugs = self.select_drugs()
459 if selected_drugs is None:
460 return None
461
462 new_substances = []
463
464 for drug in selected_drugs:
465 atc = None
466 if len(drug['wirkstoffe']) == 1:
467 atc = drug['atc']
468 for wirkstoff in drug['wirkstoffe']:
469 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc))
470
471 selected_drugs.close()
472
473 return new_substances
474
476
477 selected_drugs = self.select_drugs()
478 if selected_drugs is None:
479 return None
480
481 data_src_pk = self.create_data_source_entry()
482
483 new_drugs = []
484 new_substances = []
485
486 for entry in selected_drugs:
487
488 _log.debug('importing drug: %s %s', entry['name'], entry['darreichungsform'])
489
490 if entry[u'hilfsmittel']:
491 _log.debug('skipping Hilfsmittel')
492 continue
493
494 if entry[u'erstattbares_medizinprodukt']:
495 _log.debug('skipping sonstiges Medizinprodukt')
496 continue
497
498
499 drug = create_branded_drug(brand_name = entry['name'], preparation = entry['darreichungsform'])
500 if drug is None:
501 drug = get_drug_by_brand(brand_name = entry['name'], preparation = entry['darreichungsform'])
502 new_drugs.append(drug)
503
504
505 drug['is_fake'] = False
506 drug['atc_code'] = entry['atc']
507 drug['external_code_type'] = u'DE-PZN'
508 drug['external_code'] = entry['pzn']
509 drug['fk_data_source'] = data_src_pk
510 drug.save()
511
512
513 atc = None
514 if len(entry['wirkstoffe']) == 1:
515 atc = entry['atc']
516 for wirkstoff in entry['wirkstoffe']:
517 drug.add_component(substance = wirkstoff, atc = atc)
518
519
520 atc = None
521 if len(entry['wirkstoffe']) == 1:
522 atc = entry['atc']
523 for wirkstoff in entry['wirkstoffe']:
524 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc))
525
526 return new_drugs, new_substances
527
556
575
577
579 cGelbeListeWindowsInterface.__init__(self)
580
581 _log.info(u'%s (WINE extension)', cGelbeListeWindowsInterface.version)
582
583
584 self.path_to_binary = r'wine "C:\Programme\MMI PHARMINDEX\glwin.exe"'
585 self.args = r'"-PRESCRIPTIONFILE %s -KEEPBACKGROUND"'
586
587 paths = gmTools.gmPaths()
588
589 self.default_csv_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'mmi2gm.csv')
590 self.default_csv_filename_arg = r'c:\windows\temp\mmi2gm.csv'
591 self.interactions_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'gm2mmi.bdt')
592 self.data_date_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'Programme', 'MMI PHARMINDEX', 'datadate.txt')
593
595 """empirical CSV interface"""
596
599
601
602 try:
603 csv_file = open(filename, 'rb')
604 except:
605 _log.exception('cannot access [%s]', filename)
606 csv_file = None
607
608 field_names = u'PZN Handelsname Form Abpackungsmenge Einheit Preis1 Hersteller Preis2 rezeptpflichtig Festbetrag Packungszahl Packungsgr\xf6\xdfe'.split()
609
610 if csv_file is None:
611 return False
612
613 csv_lines = csv.DictReader (
614 csv_file,
615 fieldnames = field_names,
616 delimiter = ';'
617 )
618
619 for line in csv_lines:
620 print "--------------------------------------------------------------------"[:31]
621 for key in field_names:
622 tmp = ('%s ' % key)[:30]
623 print '%s: %s' % (tmp, line[key])
624
625 csv_file.close()
626
627
628
629
630
631
632
633
634
635
636
637
638 drug_data_source_interfaces = {
639 'Deutschland: Gelbe Liste/MMI (Windows)': cGelbeListeWindowsInterface,
640 'Deutschland: Gelbe Liste/MMI (WINE)': cGelbeListeWineInterface,
641 'France: FreeDiams': cFreeDiamsInterface
642 }
643
644
645
647 cmd = u'select * from clin.consumed_substance order by description'
648 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}])
649 return rows
650
652 cmd = u'select * from clin.consumed_substance WHERE pk = %(pk)s'
653 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'pk': pk}}])
654 if len(rows) == 0:
655 return None
656 return rows[0]
657
659
660 substance = substance.strip()
661
662 if atc is not None:
663 atc = atc.strip()
664
665 args = {'desc': substance, 'atc': atc}
666
667 cmd = u'select pk, atc_code, description from clin.consumed_substance where description = %(desc)s'
668 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
669
670 if len(rows) == 0:
671 cmd = u'insert into clin.consumed_substance (description, atc_code) values (%(desc)s, gm.nullify_empty_string(%(atc)s)) returning pk, atc_code, description'
672 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
673
674 gmATC.propagate_atc(substance = substance, atc = atc)
675
676 row = rows[0]
677
678
679 row[1] = args['atc']
680 return row
681
683 args = {'pk': substance}
684 cmd = u"""
685 delete from clin.consumed_substance
686 where
687 pk = %(pk)s and not exists (
688 select 1 from clin.substance_intake
689 where fk_substance = %(pk)s
690 )"""
691 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
692
693 -class cSubstanceIntakeEntry(gmBusinessDBObject.cBusinessDBObject):
694 """Represents a substance currently taken by a patient."""
695
696 _cmd_fetch_payload = u"select * from clin.v_pat_substance_intake where pk_substance_intake = %s"
697 _cmds_store_payload = [
698 u"""update clin.substance_intake set
699 clin_when = %(started)s,
700 discontinued = %(discontinued)s,
701 discontinue_reason = gm.nullify_empty_string(%(discontinue_reason)s),
702 strength = gm.nullify_empty_string(%(strength)s),
703 preparation = %(preparation)s,
704 schedule = gm.nullify_empty_string(%(schedule)s),
705 aim = gm.nullify_empty_string(%(aim)s),
706 narrative = gm.nullify_empty_string(%(notes)s),
707 intake_is_approved_of = %(intake_is_approved_of)s,
708
709 -- is_long_term = %(is_long_term)s,
710 is_long_term = (
711 case
712 when (
713 (%(is_long_term)s is False)
714 and
715 (gm.is_null_or_blank_string(%(duration)s) is True)
716 ) is True then null
717 else %(is_long_term)s
718 end
719 )::boolean,
720 duration = (
721 case
722 when %(is_long_term)s is True then null
723 else gm.nullify_empty_string(%(duration)s)
724 end
725 )::interval,
726
727 fk_brand = %(pk_brand)s,
728 fk_substance = %(pk_substance)s,
729 fk_episode = %(pk_episode)s
730 where
731 pk = %(pk_substance_intake)s and
732 xmin = %(xmin_substance_intake)s
733 returning
734 xmin as xmin_substance_intake
735 """
736 ]
737 _updatable_fields = [
738 u'started',
739 u'discontinued',
740 u'discontinue_reason',
741 u'preparation',
742 u'strength',
743 u'intake_is_approved_of',
744 u'schedule',
745 u'duration',
746 u'aim',
747 u'is_long_term',
748 u'notes',
749 u'pk_brand',
750 u'pk_substance',
751 u'pk_episode'
752 ]
753
754 - def format(self, left_margin=0, date_format='%Y-%m-%d'):
755
756 if self._payload[self._idx['duration']] is None:
757 duration = gmTools.bool2subst (
758 self._payload[self._idx['is_long_term']],
759 _('long-term'),
760 _('short-term'),
761 _('?short-term')
762 )
763 else:
764 duration = gmDateTime.format_interval (
765 self._payload[self._idx['duration']],
766 accuracy_wanted = gmDateTime.acc_days
767 )
768
769 line = u'%s%s (%s %s): %s %s %s (%s)' % (
770 u' ' * left_margin,
771 self._payload[self._idx['started']].strftime(date_format),
772 gmTools.u_right_arrow,
773 duration,
774 self._payload[self._idx['substance']],
775 self._payload[self._idx['strength']],
776 self._payload[self._idx['preparation']],
777 gmTools.bool2subst(self._payload[self._idx['is_currently_active']], _('ongoing'), _('inactive'), _('?ongoing'))
778 )
779
780 return line
781
782 - def turn_into_allergy(self, encounter_id=None, allergy_type='allergy'):
783 allg = gmAllergy.create_allergy (
784 substance = gmTools.coalesce (
785 self._payload[self._idx['brand']],
786 self._payload[self._idx['substance']]
787 ),
788 allg_type = allergy_type,
789 episode_id = self._payload[self._idx['pk_episode']],
790 encounter_id = encounter_id
791 )
792 allg['reaction'] = self._payload[self._idx['discontinue_reason']]
793 allg['atc_code'] = gmTools.coalesce(self._payload[self._idx['atc_substance']], self._payload[self._idx['atc_brand']])
794 if self._payload[self._idx['external_code_brand']] is not None:
795 allg['substance_code'] = u'%s::::%s' % (self._payload[self._idx['external_code_type_brand']], self._payload[self._idx['external_code_brand']])
796 allg['generics'] = self._payload[self._idx['substance']]
797
798 allg.save()
799 return allg
800
801
802
803 - def _get_ddd(self):
804
805 try: self.__ddd
806 except AttributeError: self.__ddd = None
807
808 if self.__ddd is not None:
809 return self.__ddd
810
811 if self._payload[self._idx['atc_substance']] is not None:
812 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_substance']])
813 if len(ddd) != 0:
814 self.__ddd = ddd[0]
815 else:
816 if self._payload[self._idx['atc_brand']] is not None:
817 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_brand']])
818 if len(ddd) != 0:
819 self.__ddd = ddd[0]
820
821 return self.__ddd
822
823 ddd = property(_get_ddd, lambda x:x)
824
826 drug = self.containing_drug
827
828 if drug is None:
829 return None
830
831 return drug.external_code
832
833 external_code = property(_get_external_code, lambda x:x)
834
836 drug = self.containing_drug
837
838 if drug is None:
839 return None
840
841 return drug.external_code_type
842
843 external_code_type = property(_get_external_code_type, lambda x:x)
844
846 if self._payload[self._idx['pk_brand']] is None:
847 return None
848
849 return cBrandedDrug(aPK_obj = self._payload[self._idx['pk_brand']])
850
851 containing_drug = property(_get_containing_drug, lambda x:x)
852
854 tests = [
855
856 ' 1-1-1-1 ',
857
858 '1-1-1-1',
859 '22-1-1-1',
860 '1/3-1-1-1',
861 '/4-1-1-1'
862 ]
863 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}$"
864 for test in tests:
865 print test.strip(), ":", regex.match(pattern, test.strip())
866
868
869 args = {
870 'enc': encounter,
871 'epi': episode,
872 'prep': preparation,
873 'subst': create_used_substance(substance = substance, atc = atc)['pk']
874 }
875
876 cmd = u"""
877 insert into clin.substance_intake (
878 fk_encounter,
879 fk_episode,
880 fk_substance,
881 preparation,
882 intake_is_approved_of
883 ) values (
884 %(enc)s,
885 %(epi)s,
886 %(subst)s,
887 gm.nullify_empty_string(%(prep)s),
888 False
889 )
890 returning pk
891 """
892 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
893 return cSubstanceIntakeEntry(aPK_obj = rows[0][0])
894
896 cmd = u'delete from clin.substance_intake where pk = %(pk)s'
897 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': substance}}])
898
974
976 """Represents a drug as marketed by a manufacturer."""
977
978 _cmd_fetch_payload = u"select *, xmin from ref.branded_drug where pk = %s"
979 _cmds_store_payload = [
980 u"""update ref.branded_drug set
981 description = %(description)s,
982 preparation = %(preparation)s,
983 atc_code = gm.nullify_empty_string(%(atc_code)s),
984 external_code = gm.nullify_empty_string(%(external_code)s),
985 external_code_type = gm.nullify_empty_string(%(external_code_type)s),
986 is_fake = %(is_fake)s,
987 fk_data_source = %(fk_data_source)s
988 where
989 pk = %(pk)s and
990 xmin = %(xmin)s
991 returning
992 xmin
993 """
994 ]
995 _updatable_fields = [
996 u'description',
997 u'preparation',
998 u'atc_code',
999 u'is_fake',
1000 u'external_code',
1001 u'external_code_type',
1002 u'fk_data_source'
1003 ]
1004
1006 if self._payload[self._idx['external_code']] is None:
1007 return None
1008
1009 return self._payload[self._idx['external_code']]
1010
1011 external_code = property(_get_external_code, lambda x:x)
1012
1014
1015
1016 if self._payload[self._idx['external_code_type']] is None:
1017 return None
1018
1019 return self._payload[self._idx['external_code_type']]
1020
1021 external_code_type = property(_get_external_code_type, lambda x:x)
1022
1024 cmd = u'select * from ref.substance_in_brand where fk_brand = %(brand)s'
1025 args = {'brand': self._payload[self._idx['pk']]}
1026 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1027 return rows
1028
1029 components = property(_get_components, lambda x:x)
1030
1032
1033
1034 atc = gmATC.propagate_atc(substance = substance, atc = atc)
1035
1036 args = {
1037 'brand': self.pk_obj,
1038 'desc': substance,
1039 'atc': atc
1040 }
1041
1042
1043 cmd = u"""
1044 SELECT pk
1045 FROM ref.substance_in_brand
1046 WHERE
1047 fk_brand = %(brand)s
1048 AND
1049 ((description = %(desc)s) OR ((atc_code = %(atc)s) IS TRUE))
1050 """
1051 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1052 if len(rows) > 0:
1053 return
1054
1055
1056 cmd = u"""
1057 INSERT INTO ref.substance_in_brand (fk_brand, description, atc_code)
1058 VALUES (%(brand)s, %(desc)s, %(atc)s)
1059 """
1060 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
1061
1064
1066 cmd = u'SELECT * FROM ref.v_substance_in_brand ORDER BY brand, substance'
1067 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
1068 return rows
1069
1071
1072 cmd = u'SELECT pk FROM ref.branded_drug ORDER BY description'
1073 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
1074
1075 return [ cBrandedDrug(aPK_obj = r['pk']) for r in rows ]
1076
1078 args = {'brand': brand_name, 'prep': preparation}
1079
1080 cmd = u'SELECT pk FROM ref.branded_drug WHERE description = %(brand)s AND preparation = %(prep)s'
1081 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
1082
1083 if len(rows) == 0:
1084 return None
1085
1086 return cBrandedDrug(aPK_obj = rows[0]['pk'])
1087
1089
1090 if preparation is None:
1091 preparation = _('units')
1092
1093 if preparation.strip() == u'':
1094 preparation = _('units')
1095
1096 drug = get_drug_by_brand(brand_name = brand_name, preparation = preparation)
1097
1098 if drug is not None:
1099 if return_existing:
1100 return drug
1101 return None
1102
1103 cmd = u'insert into ref.branded_drug (description, preparation) values (%(brand)s, %(prep)s) returning pk'
1104 args = {'brand': brand_name, 'prep': preparation}
1105 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
1106
1107 return cBrandedDrug(aPK_obj = rows[0]['pk'])
1108
1112
1114 cmd = u'delete from ref.substance_in_brand where fk_brand = %(brand)s and pk = %(comp)s'
1115 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'brand': brand, 'comp': component}}])
1116
1117
1118
1119 if __name__ == "__main__":
1120
1121 if len(sys.argv) < 2:
1122 sys.exit()
1123
1124 if sys.argv[1] != 'test':
1125 sys.exit()
1126
1127 from Gnumed.pycommon import gmLog2
1128 from Gnumed.pycommon import gmI18N
1129
1130 gmI18N.activate_locale()
1131
1132
1138
1140 mmi_file = cGelbeListeCSVFile(filename = sys.argv[2])
1141 for drug in mmi_file:
1142 print "-------------"
1143 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])
1144 for stoff in drug['wirkstoffe']:
1145 print " Wirkstoff:", stoff
1146 print drug
1147 mmi_file.close()
1148
1152
1154 mmi = cGelbeListeWineInterface()
1155 mmi_file = mmi.select_drugs()
1156 for drug in mmi_file:
1157 print "-------------"
1158 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])
1159 for stoff in drug['wirkstoffe']:
1160 print " Wirkstoff:", stoff
1161 print drug
1162 mmi_file.close()
1163
1167
1169 mmi = cGelbeListeInterface()
1170 print mmi
1171 print "interface definition:", mmi.version
1172
1173 diclofenac = '7587712'
1174 phenprocoumon = '4421744'
1175 mmi.check_drug_interactions(pzn_list = [diclofenac, phenprocoumon])
1176
1178 drug = create_substance_intake (
1179 substance = u'Whiskey',
1180 atc = u'no ATC available',
1181 encounter = 1,
1182 episode = 1,
1183 preparation = 'a nice glass'
1184 )
1185 print drug
1186
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200 test_show_components()
1201
1202