| Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf8 -*-
2 """Medication handling code.
3
4 license: GPL
5 """
6 #============================================================
7 # $Source: /cvsroot/gnumed/gnumed/gnumed/client/business/gmMedication.py,v $
8 # $Id: gmMedication.py,v 1.21 2010/02/06 20:44:58 ncq Exp $
9 __version__ = "$Revision: 1.21 $"
10 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
11
12 import sys, logging, csv, codecs, os, re as regex
13
14
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17 from Gnumed.pycommon import gmBusinessDBObject, gmPG2, gmShellAPI, gmTools, gmDateTime
18 from Gnumed.business import gmATC
19
20
21 _log = logging.getLogger('gm.meds')
22 _log.info(__version__)
23
24 #============================================================
25 # wishlist:
26 # - --conf-file= for glwin.exe
27 # - wirkstoff: Konzentration auch in Multiprodukten
28 # - wirkstoff: ATC auch in Multiprodukten
29 # - Suche nach ATC per CLI
30
32 """Iterator over a Gelbe Liste/MMI v8.2 CSV file."""
33
34 version = u'Gelbe Liste/MMI v8.2 CSV file interface'
35 default_transfer_file_windows = r"c:\rezept.txt"
36 #default_encoding = 'cp1252'
37 default_encoding = 'cp1250'
38 csv_fieldnames = [
39 u'name',
40 u'packungsgroesse', # obsolete, use "packungsmenge"
41 u'darreichungsform',
42 u'packungstyp',
43 u'festbetrag',
44 u'avp',
45 u'hersteller',
46 u'rezepttext',
47 u'pzn',
48 u'status_vertrieb',
49 u'status_rezeptpflicht',
50 u'status_fachinfo',
51 u'btm',
52 u'atc',
53 u'anzahl_packungen',
54 u'zuzahlung_pro_packung',
55 u'einheit',
56 u'schedule_morgens',
57 u'schedule_mittags',
58 u'schedule_abends',
59 u'schedule_nachts',
60 u'status_dauermedikament',
61 u'status_hausliste',
62 u'status_negativliste',
63 u'ik_nummer',
64 u'status_rabattvertrag',
65 u'wirkstoffe',
66 u'wirkstoffmenge',
67 u'wirkstoffeinheit',
68 u'wirkstoffmenge_bezug',
69 u'wirkstoffmenge_bezugseinheit',
70 u'status_import',
71 u'status_lifestyle',
72 u'status_ausnahmeliste',
73 u'packungsmenge',
74 u'apothekenpflicht',
75 u'status_billigere_packung',
76 u'rezepttyp',
77 u'besonderes_arzneimittel', # Abstimmungsverfahren SGB-V
78 u't-rezept-pflicht', # Thalidomid-Rezept
79 u'erstattbares_medizinprodukt',
80 u'hilfsmittel',
81 u'hzv_rabattkennung',
82 u'hzv_preis'
83 ]
84 boolean_fields = [
85 u'status_rezeptpflicht',
86 u'status_fachinfo',
87 u'btm',
88 u'status_dauermedikament',
89 u'status_hausliste',
90 u'status_negativliste',
91 u'status_rabattvertrag',
92 u'status_import',
93 u'status_lifestyle',
94 u'status_ausnahmeliste',
95 u'apothekenpflicht',
96 u'status_billigere_packung',
97 u'besonderes_arzneimittel', # Abstimmungsverfahren SGB-V
98 u't-rezept-pflicht',
99 u'erstattbares_medizinprodukt',
100 u'hilfsmittel'
101 ]
102 #--------------------------------------------------------
104
105 _log.info(cGelbeListeCSVFile.version)
106
107 self.filename = filename
108 if filename is None:
109 self.filename = cGelbeListeCSVFile.default_transfer_file_windows
110
111 _log.debug('reading Gelbe Liste/MMI drug data from [%s]', self.filename)
112
113 self.csv_file = codecs.open(filename = filename, mode = 'rUb', encoding = cGelbeListeCSVFile.default_encoding)
114
115 self.csv_lines = gmTools.unicode_csv_reader (
116 self.csv_file,
117 fieldnames = cGelbeListeCSVFile.csv_fieldnames,
118 delimiter = ';',
119 quotechar = '"',
120 dict = True
121 )
122 #--------------------------------------------------------
125 #--------------------------------------------------------
127 line = self.csv_lines.next()
128
129 for field in cGelbeListeCSVFile.boolean_fields:
130 line[field] = (line[field].strip() == u'T')
131
132 # split field "Wirkstoff" by ";"
133 if line['wirkstoffe'].strip() == u'':
134 line['wirkstoffe'] = []
135 else:
136 line['wirkstoffe'] = [ wirkstoff.strip() for wirkstoff in line['wirkstoffe'].split(u';') ]
137
138 return line
139 #--------------------------------------------------------
147 #============================================================
149
150 #--------------------------------------------------------
153 #--------------------------------------------------------
156 #--------------------------------------------------------
159 #--------------------------------------------------------
162 #--------------------------------------------------------
165 #--------------------------------------------------------
168 #--------------------------------------------------------
171 #============================================================
173 """Support v8.2 CSV file interface only."""
174
175 version = u'Gelbe Liste/MMI v8.2 interface'
176 default_encoding = 'cp1250'
177 bdt_line_template = u'%03d6210#%s\r\n' # Medikament verordnet auf Kassenrezept
178 bdt_line_base_length = 8
179 #--------------------------------------------------------
181 _log.info(u'%s (native Windows)', cGelbeListeWindowsInterface.version)
182
183 self.path_to_binary = r'C:\Programme\MMI PHARMINDEX\glwin.exe'
184 self.args = r'-KEEPBACKGROUND -PRESCRIPTIONFILE %s -CLOSETOTRAY'
185
186 paths = gmTools.gmPaths()
187
188 self.default_csv_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'rezept.txt')
189 self.default_csv_filename_arg = os.path.join(paths.home_dir, '.gnumed', 'tmp')
190 self.interactions_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'gm2mmi.bdt')
191 self.data_date_filename = r'C:\Programme\MMI PHARMINDEX\datadate.txt'
192
193 self.data_date = None
194 self.online_update_date = None
195
196 # use adjusted config.dat
197 #--------------------------------------------------------
199
200 open(self.data_date_filename, 'wb').close()
201
202 cmd = u'%s -DATADATE' % self.path_to_binary
203 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = True):
204 _log.error('problem querying the MMI drug database for version information')
205 return {
206 'data': u'?',
207 'online_update': u'?'
208 }
209
210 version_file = open(self.data_date_filename, 'rU')
211 versions = {
212 'data': version_file.readline()[:10],
213 'online_update': version_file.readline()[:10]
214 }
215 version_file.close()
216
217 return versions
218 #--------------------------------------------------------
220 versions = self.get_data_source_version()
221
222 args = {
223 'lname': u'Medikamentendatenbank "mmi PHARMINDEX" (Gelbe Liste)',
224 'sname': u'GL/MMI',
225 'ver': u'Daten: %s, Preise (Onlineupdate): %s' % (versions['data'], versions['online_update']),
226 'src': u'Medizinische Medien Informations GmbH, Am Forsthaus Gravenbruch 7, 63263 Neu-Isenburg',
227 'lang': u'de'
228 }
229
230 cmd = u"""select pk from ref.data_source where name_long = %(lname)s and name_short = %(sname)s and version = %(ver)s"""
231 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
232 if len(rows) > 0:
233 return rows[0]['pk']
234
235 cmd = u"""
236 INSERT INTO ref.data_source (name_long, name_short, version, source, lang)
237 VALUES (
238 %(lname)s,
239 %(sname)s,
240 %(ver)s,
241 %(src)s,
242 %(lang)s
243 )
244 returning pk
245 """
246
247 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
248
249 return rows[0]['pk']
250 #--------------------------------------------------------
252
253 # must make sure csv file exists
254 open(self.default_csv_filename, 'wb').close()
255
256 if cmd is None:
257 cmd = (u'%s %s' % (self.path_to_binary, self.args)) % self.default_csv_filename_arg
258
259 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
260 _log.error('problem switching to the MMI drug database')
261 # apparently on the first call MMI does not
262 # consistently return 0 on success
263 # return False
264
265 return True
266 #--------------------------------------------------------
268
269 # better to clean up interactions file
270 open(self.interactions_filename, 'wb').close()
271
272 if not self.switch_to_frontend(blocking = True):
273 return None
274
275 return cGelbeListeCSVFile(filename = self.default_csv_filename)
276 #--------------------------------------------------------
278
279 selected_drugs = self.select_drugs()
280 if selected_drugs is None:
281 return None
282
283 new_substances = []
284
285 for drug in selected_drugs:
286 atc = None # hopefully MMI eventually supports atc-per-substance in a drug...
287 if len(drug['wirkstoffe']) == 1:
288 atc = drug['atc']
289 for wirkstoff in drug['wirkstoffe']:
290 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc))
291
292 selected_drugs.close()
293
294 return new_substances
295 #--------------------------------------------------------
297
298 selected_drugs = self.select_drugs()
299 if selected_drugs is None:
300 return None
301
302 data_src_pk = self.create_data_source_entry()
303
304 new_drugs = []
305 new_substances = []
306
307 for entry in selected_drugs:
308
309 _log.debug('importing drug: %s %s', entry['name'], entry['darreichungsform'])
310
311 if entry[u'hilfsmittel']:
312 _log.debug('skipping Hilfsmittel')
313 continue
314
315 if entry[u'erstattbares_medizinprodukt']:
316 _log.debug('skipping sonstiges Medizinprodukt')
317 continue
318
319 # create branded drug (or get it if it already exists)
320 drug = create_branded_drug(brand_name = entry['name'], preparation = entry['darreichungsform'])
321 if drug is None:
322 drug = get_drug_by_brand(brand_name = entry['name'], preparation = entry['darreichungsform'])
323 new_drugs.append(drug)
324
325 # update fields
326 drug['is_fake'] = False
327 drug['atc_code'] = entry['atc']
328 drug['external_code'] = u'%s::%s' % ('DE-PZN', entry['pzn'])
329 drug['fk_data_source'] = data_src_pk
330 drug.save()
331
332 # add components to brand
333 atc = None # hopefully MMI eventually supports atc-per-substance in a drug...
334 if len(entry['wirkstoffe']) == 1:
335 atc = entry['atc']
336 for wirkstoff in entry['wirkstoffe']:
337 drug.add_component(substance = wirkstoff, atc = atc)
338
339 # create as consumable substances, too
340 atc = None # hopefully MMI eventually supports atc-per-substance in a drug...
341 if len(entry['wirkstoffe']) == 1:
342 atc = entry['atc']
343 for wirkstoff in entry['wirkstoffe']:
344 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc))
345
346 return new_drugs, new_substances
347 #--------------------------------------------------------
349 """For this to work the BDT interaction check must be configured in the MMI."""
350
351 if pzn_list is None:
352 if substances is None:
353 return
354 if len(substances) < 2:
355 return
356 pzn_list = [ s.external_code for s in substances ]
357 pzn_list = [ pzn for pzn in pzn_list if pzn is not None ]
358 pzn_list = [ code_value for code_type, code_value in pzn_list if code_type == u'DE-PZN']
359
360 else:
361 if len(pzn_list) < 2:
362 return
363
364 if pzn_list < 2:
365 return
366
367 bdt_file = codecs.open(filename = self.interactions_filename, mode = 'wb', encoding = cGelbeListeWindowsInterface.default_encoding)
368
369 for pzn in pzn_list:
370 pzn = pzn.strip()
371 lng = cGelbeListeWindowsInterface.bdt_line_base_length + len(pzn)
372 bdt_file.write(cGelbeListeWindowsInterface.bdt_line_template % (lng, pzn))
373
374 bdt_file.close()
375
376 self.switch_to_frontend(blocking = False)
377 #--------------------------------------------------------
379
380 cmd = None
381
382 if substance.external_code is not None:
383 code_type, pzn = substance.external_code
384 if code_type == u'DE-PZN':
385 cmd = u'%s -PZN %s' % (self.path_to_binary, pzn)
386
387 if cmd is None:
388 name = gmTools.coalesce (
389 substance['brand'],
390 substance['substance']
391 )
392 cmd = u'%s -NAME %s' % (self.path_to_binary, name)
393
394 # better to clean up interactions file
395 open(self.interactions_filename, 'wb').close()
396
397 self.switch_to_frontend(cmd = cmd)
398 #============================================================
400
402 cGelbeListeWindowsInterface.__init__(self)
403
404 _log.info(u'%s (WINE extension)', cGelbeListeWindowsInterface.version)
405
406 # FIXME: if -CLOSETOTRAY is used GNUmed cannot detect the end of MMI
407 self.path_to_binary = r'wine "C:\Programme\MMI PHARMINDEX\glwin.exe"'
408 self.args = r'"-PRESCRIPTIONFILE %s -KEEPBACKGROUND"'
409
410 paths = gmTools.gmPaths()
411
412 self.default_csv_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'mmi2gm.csv')
413 self.default_csv_filename_arg = r'c:\windows\temp\mmi2gm.csv'
414 self.interactions_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'gm2mmi.bdt')
415 self.data_date_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'Programme', 'MMI PHARMINDEX', 'datadate.txt')
416 #============================================================
418 """empirical CSV interface"""
419
422
424
425 try:
426 csv_file = open(filename, 'rb') # FIXME: encoding ?
427 except:
428 _log.exception('cannot access [%s]', filename)
429 csv_file = None
430
431 field_names = u'PZN Handelsname Form Abpackungsmenge Einheit Preis1 Hersteller Preis2 rezeptpflichtig Festbetrag Packungszahl Packungsgr\xf6\xdfe'.split()
432
433 if csv_file is None:
434 return False
435
436 csv_lines = csv.DictReader (
437 csv_file,
438 fieldnames = field_names,
439 delimiter = ';'
440 )
441
442 for line in csv_lines:
443 print "--------------------------------------------------------------------"[:31]
444 for key in field_names:
445 tmp = ('%s ' % key)[:30]
446 print '%s: %s' % (tmp, line[key])
447
448 csv_file.close()
449
450 # narr = u'%sx %s %s %s (\u2258 %s %s) von %s (%s)' % (
451 # line['Packungszahl'].strip(),
452 # line['Handelsname'].strip(),
453 # line['Form'].strip(),
454 # line[u'Packungsgr\xf6\xdfe'].strip(),
455 # line['Abpackungsmenge'].strip(),
456 # line['Einheit'].strip(),
457 # line['Hersteller'].strip(),
458 # line['PZN'].strip()
459 # )
460 #============================================================
461 drug_data_source_interfaces = {
462 'Gelbe Liste/MMI (Windows)': cGelbeListeWindowsInterface,
463 'Gelbe Liste/MMI (WINE)': cGelbeListeWineInterface
464 }
465 #============================================================
466 # substances in use across all patients
467 #------------------------------------------------------------
469 cmd = u'select * from clin.consumed_substance order by description'
470 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}])
471 return rows
472 #------------------------------------------------------------
474 cmd = u'select * from clin.consumed_substance WHERE pk = %(pk)s'
475 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'pk': pk}}])
476 if len(rows) == 0:
477 return None
478 return rows[0]
479 #------------------------------------------------------------
481
482 substance = substance.strip()
483
484 if atc is not None:
485 atc = atc.strip()
486
487 args = {'desc': substance, 'atc': atc}
488
489 cmd = u'select pk, atc_code, description from clin.consumed_substance where description = %(desc)s'
490 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
491
492 if len(rows) == 0:
493 cmd = u'insert into clin.consumed_substance (description, atc_code) values (%(desc)s, gm.nullify_empty_string(%(atc)s)) returning pk, atc_code, description'
494 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
495
496 gmATC.propagate_atc(substance = substance, atc = atc)
497
498 row = rows[0]
499 # unfortunately not a real dict so no setting stuff by keyword
500 #row['atc_code'] = args['atc']
501 row[1] = args['atc']
502 return row
503 #------------------------------------------------------------
505 args = {'pk': substance}
506 cmd = u"""
507 delete from clin.consumed_substance
508 where
509 pk = %(pk)s and not exists (
510 select 1 from clin.substance_intake
511 where fk_substance = %(pk)s
512 )"""
513 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
514 #============================================================
516 """Represents a substance currently taken by a patient."""
517
518 _cmd_fetch_payload = u"select * from clin.v_pat_substance_intake where pk_substance_intake = %s"
519 _cmds_store_payload = [
520 u"""update clin.substance_intake set
521 clin_when = %(started)s,
522 strength = gm.nullify_empty_string(%(strength)s),
523 preparation = %(preparation)s,
524 schedule = gm.nullify_empty_string(%(schedule)s),
525 aim = gm.nullify_empty_string(%(aim)s),
526 narrative = gm.nullify_empty_string(%(notes)s),
527 intake_is_approved_of = %(intake_is_approved_of)s,
528
529 -- is_long_term = %(is_long_term)s,
530 is_long_term = (
531 case
532 when (
533 (%(is_long_term)s is False)
534 and
535 (gm.is_null_or_blank_string(%(duration)s) is True)
536 ) is True then null
537 else %(is_long_term)s
538 end
539 )::boolean,
540 duration = (
541 case
542 when %(is_long_term)s is True then null
543 else gm.nullify_empty_string(%(duration)s)
544 end
545 )::interval,
546
547 fk_brand = %(pk_brand)s,
548 fk_substance = %(pk_substance)s,
549 fk_episode = %(pk_episode)s
550 where
551 pk = %(pk_substance_intake)s and
552 xmin = %(xmin_substance_intake)s
553 returning
554 xmin as xmin_substance_intake
555 """
556 ]
557 _updatable_fields = [
558 u'started',
559 u'preparation',
560 u'strength',
561 u'intake_is_approved_of',
562 u'schedule',
563 u'duration',
564 u'aim',
565 u'is_long_term',
566 u'notes',
567 u'pk_brand',
568 u'pk_substance',
569 u'pk_episode'
570 ]
571 #--------------------------------------------------------
573
574 if self._payload[self._idx['duration']] is None:
575 duration = gmTools.bool2subst (
576 self._payload[self._idx['is_long_term']],
577 _('long-term'),
578 _('short-term'),
579 _('?short-term')
580 )
581 else:
582 duration = gmDateTime.format_interval (
583 self._payload[self._idx['duration']],
584 accuracy_wanted = gmDateTime.acc_days
585 )
586
587 line = u'%s%s (%s %s): %s %s %s (%s)' % (
588 u' ' * left_margin,
589 self._payload[self._idx['started']].strftime(date_format),
590 gmTools.u_right_arrow,
591 duration,
592 self._payload[self._idx['substance']],
593 self._payload[self._idx['strength']],
594 self._payload[self._idx['preparation']],
595 gmTools.bool2subst(self._payload[self._idx['is_currently_active']], _('ongoing'), _('inactive'), _('?ongoing'))
596 )
597
598 return line
599 #--------------------------------------------------------
600 # properties
601 #--------------------------------------------------------
603
604 try: self.__ddd
605 except AttributeError: self.__ddd = None
606
607 if self.__ddd is not None:
608 return self.__ddd
609
610 if self._payload[self._idx['atc_substance']] is not None:
611 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_substance']])
612 if len(ddd) != 0:
613 self.__ddd = ddd[0]
614 else:
615 if self._payload[self._idx['atc_brand']] is not None:
616 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_brand']])
617 if len(ddd) != 0:
618 self.__ddd = ddd[0]
619
620 return self.__ddd
621
622 ddd = property(_get_ddd, lambda x:x)
623 #--------------------------------------------------------
625 drug = self.containing_drug
626
627 if drug is None:
628 return None
629
630 return drug.external_code
631
632 external_code = property(_get_external_code, lambda x:x)
633 #--------------------------------------------------------
635 if self._payload[self._idx['pk_brand']] is None:
636 return None
637
638 return cBrandedDrug(aPK_obj = self._payload[self._idx['pk_brand']])
639
640 containing_drug = property(_get_containing_drug, lambda x:x)
641 #--------------------------------------------------------
643 tests = [
644 # lead, trail
645 ' 1-1-1-1 ',
646 # leading dose
647 '1-1-1-1',
648 '22-1-1-1',
649 '1/3-1-1-1',
650 '/4-1-1-1'
651 ]
652 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}$"
653 for test in tests:
654 print test.strip(), ":", regex.match(pattern, test.strip())
655 #------------------------------------------------------------
656 -def create_substance_intake(substance=None, atc=None, encounter=None, episode=None, preparation=None):
657
658 args = {
659 'enc': encounter,
660 'epi': episode,
661 'prep': preparation,
662 'subst': create_used_substance(substance = substance, atc = atc)['pk']
663 }
664
665 cmd = u"""
666 insert into clin.substance_intake (
667 fk_encounter,
668 fk_episode,
669 fk_substance,
670 preparation,
671 intake_is_approved_of
672 ) values (
673 %(enc)s,
674 %(epi)s,
675 %(subst)s,
676 gm.nullify_empty_string(%(prep)s),
677 False
678 )
679 returning pk
680 """
681 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
682 return cSubstanceIntakeEntry(aPK_obj = rows[0][0])
683 #------------------------------------------------------------
685 cmd = u'delete from clin.substance_intake where pk = %(pk)s'
686 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': substance}}])
687 #============================================================
689 """Represents a drug as marketed by a manufacturer."""
690
691 _cmd_fetch_payload = u"select *, xmin from ref.branded_drug where pk = %s"
692 _cmds_store_payload = [
693 u"""update ref.branded_drug set
694 description = %(description)s,
695 preparation = %(preparation)s,
696 atc_code = gm.nullify_empty_string(%(atc_code)s),
697 external_code = gm.nullify_empty_string(%(external_code)s),
698 is_fake = %(is_fake)s,
699 fk_data_source = %(fk_data_source)s
700 where
701 pk = %(pk)s and
702 xmin = %(xmin)s
703 returning
704 xmin
705 """
706 ]
707 _updatable_fields = [
708 u'description',
709 u'preparation',
710 u'atc_code',
711 u'is_fake',
712 u'external_code',
713 u'fk_data_source'
714 ]
715 #--------------------------------------------------------
717 if self._payload[self._idx['external_code']] is None:
718 return None
719
720 if regex.match(u'.+::.+', self._payload[self._idx['external_code']], regex.UNICODE) is None:
721 # FIXME: maybe evaluate fk_data_source
722 return None
723
724 return regex.split(u'::', self._payload[self._idx['external_code']], 1)
725
726 external_code = property(_get_external_code, lambda x:x)
727 #--------------------------------------------------------
729 cmd = u'select * from ref.substance_in_brand where fk_brand = %(brand)s'
730 args = {'brand': self._payload[self._idx['pk']]}
731 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
732 return rows
733
734 components = property(_get_components, lambda x:x)
735 #--------------------------------------------------------
737
738 # normalize atc
739 atc = gmATC.propagate_atc(substance = substance, atc = atc)
740
741 args = {
742 'brand': self.pk_obj,
743 'desc': substance,
744 'atc': atc
745 }
746
747 # already exists ?
748 cmd = u"""
749 SELECT pk
750 FROM ref.substance_in_brand
751 WHERE
752 fk_brand = %(brand)s
753 AND
754 ((description = %(desc)s) OR ((atc_code = %(atc)s) IS TRUE))
755 """
756 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
757 if len(rows) > 0:
758 return
759
760 # create it
761 cmd = u"""
762 INSERT INTO ref.substance_in_brand (fk_brand, description, atc_code)
763 VALUES (%(brand)s, %(desc)s, %(atc)s)
764 """
765 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
766 #------------------------------------------------------------
768 delete_component_from_branded_drug(brand = self.pk_obj, component = substance)
769 #------------------------------------------------------------
771 cmd = u'SELECT * FROM ref.v_substance_in_brand ORDER BY brand, substance'
772 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
773 return rows
774 #------------------------------------------------------------
776
777 cmd = u'SELECT pk FROM ref.branded_drug ORDER BY description'
778 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
779
780 return [ cBrandedDrug(aPK_obj = r['pk']) for r in rows ]
781 #------------------------------------------------------------
783 args = {'brand': brand_name, 'prep': preparation}
784
785 cmd = u'SELECT pk FROM ref.branded_drug WHERE description = %(brand)s AND preparation = %(prep)s'
786 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False)
787
788 if len(rows) == 0:
789 return None
790
791 return cBrandedDrug(aPK_obj = rows[0]['pk'])
792 #------------------------------------------------------------
794
795 if preparation is None:
796 preparation = _('units')
797
798 if preparation.strip() == u'':
799 preparation = _('units')
800
801 drug = get_drug_by_brand(brand_name = brand_name, preparation = preparation)
802
803 if drug is not None:
804 if return_existing:
805 return drug
806 return None
807
808 cmd = u'insert into ref.branded_drug (description, preparation) values (%(brand)s, %(prep)s) returning pk'
809 args = {'brand': brand_name, 'prep': preparation}
810 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
811
812 return cBrandedDrug(aPK_obj = rows[0]['pk'])
813 #------------------------------------------------------------
815 cmd = u'delete from ref.branded_drug where pk = %(pk)s'
816 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': brand}}])
817 #------------------------------------------------------------
819 cmd = u'delete from ref.substance_in_brand where fk_brand = %(brand)s and pk = %(comp)s'
820 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'brand': brand, 'comp': component}}])
821 #============================================================
822 # main
823 #------------------------------------------------------------
824 if __name__ == "__main__":
825
826 from Gnumed.pycommon import gmLog2
827 from Gnumed.pycommon import gmI18N
828
829 gmI18N.activate_locale()
830 # gmDateTime.init()
831 #--------------------------------------------------------
833 mmi = cGelbeListeWineInterface()
834 print mmi
835 print "interface definition:", mmi.version
836 print "database versions: ", mmi.get_data_source_version()
837 #--------------------------------------------------------
839 mmi_file = cGelbeListeCSVFile(filename = sys.argv[2])
840 for drug in mmi_file:
841 print "-------------"
842 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])
843 for stoff in drug['wirkstoffe']:
844 print " Wirkstoff:", stoff
845 print drug
846 mmi_file.close()
847 #--------------------------------------------------------
851 #--------------------------------------------------------
853 mmi = cGelbeListeWineInterface()
854 mmi_file = mmi.select_drugs()
855 for drug in mmi_file:
856 print "-------------"
857 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])
858 for stoff in drug['wirkstoffe']:
859 print " Wirkstoff:", stoff
860 print drug
861 mmi_file.close()
862 #--------------------------------------------------------
866 #--------------------------------------------------------
868 mmi = cGelbeListeInterface()
869 print mmi
870 print "interface definition:", mmi.version
871 # Metoprolol + Hct vs Citalopram
872 diclofenac = '7587712'
873 phenprocoumon = '4421744'
874 mmi.check_drug_interactions(pzn_list = [diclofenac, phenprocoumon])
875 #--------------------------------------------------------
877 drug = create_substance_intake (
878 substance = u'Whiskey',
879 atc = u'no ATC available',
880 encounter = 1,
881 episode = 1,
882 preparation = 'a nice glass'
883 )
884 print drug
885 #--------------------------------------------------------
890 #--------------------------------------------------------
891 if (len(sys.argv)) > 1 and (sys.argv[1] == 'test'):
892 #test_MMI_interface()
893 #test_MMI_file()
894 #test_mmi_switch_to()
895 #test_mmi_select_drugs()
896 #test_mmi_import_substances()
897 #test_mmi_import_drugs()
898 #test_interaction_check()
899 #test_create_substance_intake()
900 test_show_components()
901 #============================================================
902 # $Log: gmMedication.py,v $
903 # Revision 1.21 2010/02/06 20:44:58 ncq
904 # - .ddd on substance intake
905 #
906 # Revision 1.20 2009/12/25 21:38:50 ncq
907 # - add 2 new fields to MMI CSV file
908 # - show-info-on-drug
909 # - enhance switch-to-frontend to allow custom startup cmd
910 #
911 # Revision 1.19 2009/12/02 16:48:58 ncq
912 # - add infrastructure for removing component from brand
913 #
914 # Revision 1.18 2009/12/01 21:48:09 ncq
915 # - get-substance-by-pk
916 #
917 # Revision 1.17 2009/11/30 21:56:36 ncq
918 # - components property on branded drug
919 #
920 # Revision 1.16 2009/11/30 15:06:27 ncq
921 # - handle a bunch of possibilities of dirty records retrieved from GLI/MMI
922 # - default preparation to i18n(units)
923 #
924 # Revision 1.15 2009/11/29 19:59:31 ncq
925 # - improve substance/component creation with propagate-atc
926 #
927 # Revision 1.14 2009/11/29 15:57:27 ncq
928 # - while SQL results are dicts as far as *retrieval* is concerned,
929 # they are NOT for inserting data into them, so use list access
930 #
931 # Revision 1.13 2009/11/28 18:27:30 ncq
932 # - much improved ATC detection on substance creation
933 # - create-patient-consumed-substance -> create-substance-intake
934 # - get-branded-drugs
935 # - get-substances-in-brands
936 # - delete-branded-drugs
937 #
938 # Revision 1.12 2009/11/24 19:57:22 ncq
939 # - implement getting/creating data souce entry for MMI
940 # - implement version retrieval for MMI
941 # - import-drugs()
942 # - check-drug-interactions()
943 # - cConsumedSubstance -> cSubstanceIntakeEntry + .external_code
944 # - cBrandedDrug
945 # - tests
946 #
947 # Revision 1.11 2009/11/06 15:05:07 ncq
948 # - get-substances-in-use
949 # - meds formatting
950 # - delete-patient-consumed-substance
951 #
952 # Revision 1.10 2009/10/29 17:16:59 ncq
953 # - return newly created substances from creator func and substance importer method
954 # - better naming
955 # - finish up cConsumedSubstance
956 #
957 # Revision 1.9 2009/10/28 16:40:12 ncq
958 # - add some docs about schedule parsing
959 #
960 # Revision 1.8 2009/10/26 22:29:05 ncq
961 # - better factorization of paths in MMI interface
962 # - update ATC on INN if now known
963 # - delete-consumed-substance
964 #
965 # Revision 1.7 2009/10/21 20:37:18 ncq
966 # - MMI uses cp1250, rather than cp1252, (at least under WINE) contrary to direct communication ...
967 # - use unicode csv reader
968 # - add a bunch of file cleanup
969 # - split MMI interface into WINE vs native Windows version
970 #
971 # Revision 1.6 2009/10/21 09:15:50 ncq
972 # - much improved MMI frontend
973 #
974 # Revision 1.5 2009/09/29 13:14:25 ncq
975 # - faulty ordering of definitions
976 #
977 # Revision 1.4 2009/09/01 22:16:35 ncq
978 # - improved interaction check test
979 #
980 # Revision 1.3 2009/08/24 18:36:20 ncq
981 # - add CSV file iterator
982 # - add BDT interaction check
983 #
984 # Revision 1.2 2009/08/21 09:56:37 ncq
985 # - start drug data source interfaces
986 # - add MMI/Gelbe Liste interface
987 #
988 # Revision 1.1 2009/05/12 12:02:01 ncq
989 # - start supporting current medications
990 #
991 #
992
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Feb 9 04:01:34 2010 | http://epydoc.sourceforge.net |