Package Gnumed :: Package business :: Module gmDrugDataSources
[frames] | no frames]

Source Code for Module Gnumed.business.gmDrugDataSources

   1  # -*- coding: utf-8 -*- 
   2  """Code handling drug data sources (such as databases). 
   3   
   4  license: GPL v2 or later 
   5  """ 
   6  #============================================================ 
   7  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>" 
   8   
   9  import sys 
  10  import csv 
  11  import os 
  12  import io 
  13  import logging 
  14  import subprocess 
  15  import re as regex 
  16  from xml.etree import ElementTree as etree 
  17   
  18   
  19  if __name__ == '__main__': 
  20          sys.path.insert(0, '../../') 
  21          from Gnumed.pycommon import gmI18N 
  22          gmI18N.activate_locale() 
  23          gmI18N.install_domain('gnumed') 
  24  from Gnumed.pycommon import gmTools 
  25  from Gnumed.pycommon import gmShellAPI 
  26  from Gnumed.business import gmMedication 
  27  from Gnumed.business import gmCoding 
  28   
  29   
  30  _log = logging.getLogger('gm.meds') 
  31   
  32  #============================================================ 
  33  # generic drug data source interface class 
  34  #------------------------------------------------------------ 
35 -class cDrugDataSourceInterface(object):
36 37 #--------------------------------------------------------
38 - def __init__(self):
39 self.patient = None 40 self.reviewer = None 41 self.custom_path_to_binary = None
42 #--------------------------------------------------------
43 - def get_data_source_version(self):
44 raise NotImplementedError
45 #--------------------------------------------------------
46 - def create_data_source_entry(self):
47 raise NotImplementedError
48 #--------------------------------------------------------
49 - def switch_to_frontend(self, blocking=False):
50 raise NotImplementedError
51 #--------------------------------------------------------
52 - def import_drugs(self):
53 self.switch_to_frontend()
54 #--------------------------------------------------------
55 - def check_interactions(self, substance_intakes=None):
56 self.switch_to_frontend()
57 #--------------------------------------------------------
58 - def show_info_on_drug(self, substance_intake=None):
59 self.switch_to_frontend()
60 #--------------------------------------------------------
61 - def show_info_on_substance(self, substance_intake=None):
62 self.switch_to_frontend()
63 #--------------------------------------------------------
64 - def prescribe(self, substance_intakes=None):
65 self.switch_to_frontend() 66 return []
67 68 #============================================================ 69 # Gelbe Liste 70 #------------------------------------------------------------ 71 # wishlist: 72 # - --conf-file= for glwin.exe 73 # - wirkstoff: Konzentration auch in Multiprodukten 74 # - wirkstoff: ATC auch in Multiprodukten 75 # - Suche nach ATC per CLI 76
77 -class cGelbeListeCSVFile(object):
78 """Iterator over a Gelbe Liste/MMI v8.2 CSV file.""" 79 80 version = 'Gelbe Liste/MMI v8.2 CSV file interface' 81 default_transfer_file_windows = r"c:\rezept.txt" 82 #default_encoding = 'cp1252' 83 default_encoding = 'cp1250' 84 csv_fieldnames = [ 85 'name', 86 'packungsgroesse', # obsolete, use "packungsmenge" 87 'darreichungsform', 88 'packungstyp', 89 'festbetrag', 90 'avp', 91 'hersteller', 92 'rezepttext', 93 'pzn', 94 'status_vertrieb', 95 'status_rezeptpflicht', 96 'status_fachinfo', 97 'btm', 98 'atc', 99 'anzahl_packungen', 100 'zuzahlung_pro_packung', 101 'einheit', 102 'schedule_morgens', 103 'schedule_mittags', 104 'schedule_abends', 105 'schedule_nachts', 106 'status_dauermedikament', 107 'status_hausliste', 108 'status_negativliste', 109 'ik_nummer', 110 'status_rabattvertrag', 111 'wirkstoffe', 112 'wirkstoffmenge', 113 'wirkstoffeinheit', 114 'wirkstoffmenge_bezug', 115 'wirkstoffmenge_bezugseinheit', 116 'status_import', 117 'status_lifestyle', 118 'status_ausnahmeliste', 119 'packungsmenge', 120 'apothekenpflicht', 121 'status_billigere_packung', 122 'rezepttyp', 123 'besonderes_arzneimittel', # Abstimmungsverfahren SGB-V 124 't_rezept_pflicht', # Thalidomid-Rezept 125 'erstattbares_medizinprodukt', 126 'hilfsmittel', 127 'hzv_rabattkennung', 128 'hzv_preis' 129 ] 130 boolean_fields = [ 131 'status_rezeptpflicht', 132 'status_fachinfo', 133 'btm', 134 'status_dauermedikament', 135 'status_hausliste', 136 'status_negativliste', 137 'status_rabattvertrag', 138 'status_import', 139 'status_lifestyle', 140 'status_ausnahmeliste', 141 'apothekenpflicht', 142 'status_billigere_packung', 143 'besonderes_arzneimittel', # Abstimmungsverfahren SGB-V 144 't_rezept_pflicht', 145 'erstattbares_medizinprodukt', 146 'hilfsmittel' 147 ] 148 #--------------------------------------------------------
149 - def __init__(self, filename=None):
150 151 _log.info(cGelbeListeCSVFile.version) 152 153 self.filename = filename 154 if filename is None: 155 self.filename = cGelbeListeCSVFile.default_transfer_file_windows 156 157 _log.debug('reading Gelbe Liste/MMI drug data from [%s]', self.filename) 158 159 self.csv_file = io.open(filename, mode = 'rt', encoding = cGelbeListeCSVFile.default_encoding) 160 161 self.csv_lines = gmTools.unicode_csv_reader ( 162 self.csv_file, 163 fieldnames = cGelbeListeCSVFile.csv_fieldnames, 164 delimiter = ';', 165 quotechar = '"', 166 dict = True 167 )
168 #--------------------------------------------------------
169 - def __iter__(self):
170 return self
171 #--------------------------------------------------------
172 - def next(self):
173 line = self.csv_lines.next() 174 175 for field in cGelbeListeCSVFile.boolean_fields: 176 line[field] = (line[field].strip() == 'T') 177 178 # split field "Wirkstoff" by ";" 179 if line['wirkstoffe'].strip() == '': 180 line['wirkstoffe'] = [] 181 else: 182 line['wirkstoffe'] = [ wirkstoff.strip() for wirkstoff in line['wirkstoffe'].split(';') ] 183 184 return line
185 #--------------------------------------------------------
186 - def close(self, truncate=True):
187 try: self.csv_file.close() 188 except: pass 189 190 if truncate: 191 try: os.open(self.filename, 'wb').close 192 except: pass
193 #--------------------------------------------------------
194 - def _get_has_unknown_fields(self):
196 197 has_unknown_fields = property(_get_has_unknown_fields, lambda x:x)
198 199 #============================================================
200 -class cGelbeListeWindowsInterface(cDrugDataSourceInterface):
201 """Support v8.2 CSV file interface only.""" 202 203 version = 'Gelbe Liste/MMI v8.2 interface' 204 default_encoding = 'cp1250' 205 bdt_line_template = '%03d6210#%s\r\n' # Medikament verordnet auf Kassenrezept 206 bdt_line_base_length = 8 207 #--------------------------------------------------------
208 - def __init__(self):
209 210 cDrugDataSourceInterface.__init__(self) 211 212 _log.info('%s (native Windows)', cGelbeListeWindowsInterface.version) 213 214 self.path_to_binary = r'C:\Programme\MMI PHARMINDEX\glwin.exe' 215 self.args = r'-KEEPBACKGROUND -PRESCRIPTIONFILE %s -CLOSETOTRAY' 216 217 paths = gmTools.gmPaths() 218 219 self.default_csv_filename = os.path.join(paths.tmp_dir, 'rezept.txt') 220 self.default_csv_filename_arg = paths.tmp_dir 221 self.interactions_filename = os.path.join(paths.tmp_dir, 'gm2mmi.bdt') 222 self.data_date_filename = r'C:\Programme\MMI PHARMINDEX\datadate.txt' 223 224 self.__data_date = None 225 self.__online_update_date = None
226 227 # use adjusted config.dat 228 #--------------------------------------------------------
229 - def get_data_source_version(self, force_reload=False):
230 231 if self.__data_date is not None: 232 if not force_reload: 233 return { 234 'data': self.__data_date, 235 'online_update': self.__online_update_date 236 } 237 try: 238 open(self.data_date_filename, 'wb').close() 239 except Exception: 240 _log.error('problem querying the MMI drug database for version information') 241 _log.exception('cannot create MMI drug database version file [%s]', self.data_date_filename) 242 self.__data_date = None 243 self.__online_update_date = None 244 return { 245 'data': '?', 246 'online_update': '?' 247 } 248 249 cmd = '%s -DATADATE' % self.path_to_binary 250 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = True): 251 _log.error('problem querying the MMI drug database for version information') 252 self.__data_date = None 253 self.__online_update_date = None 254 return { 255 'data': '?', 256 'online_update': '?' 257 } 258 259 try: 260 version_file = io.open(self.data_date_filename, mode = 'rt', encoding = 'utf8') 261 except Exception: 262 _log.error('problem querying the MMI drug database for version information') 263 _log.exception('cannot open MMI drug database version file [%s]', self.data_date_filename) 264 self.__data_date = None 265 self.__online_update_date = None 266 return { 267 'data': '?', 268 'online_update': '?' 269 } 270 271 self.__data_date = version_file.readline()[:10] 272 self.__online_update_date = version_file.readline()[:10] 273 version_file.close() 274 275 return { 276 'data': self.__data_date, 277 'online_update': self.__online_update_date 278 }
279 #--------------------------------------------------------
280 - def create_data_source_entry(self):
281 versions = self.get_data_source_version() 282 283 return gmCoding.create_data_source ( 284 long_name = 'Medikamentendatenbank "mmi PHARMINDEX" (Gelbe Liste)', 285 short_name = 'GL/MMI', 286 version = 'Daten: %s, Preise (Onlineupdate): %s' % (versions['data'], versions['online_update']), 287 source = 'Medizinische Medien Informations GmbH, Am Forsthaus Gravenbruch 7, 63263 Neu-Isenburg', 288 language = 'de' 289 )
290 #--------------------------------------------------------
291 - def switch_to_frontend(self, blocking=False, cmd=None):
292 293 try: 294 # must make sure csv file exists 295 open(self.default_csv_filename, 'wb').close() 296 except IOError: 297 _log.exception('problem creating GL/MMI <-> GNUmed exchange file') 298 return False 299 300 if cmd is None: 301 cmd = ('%s %s' % (self.path_to_binary, self.args)) % self.default_csv_filename_arg 302 303 if os.name == 'nt': 304 blocking = True 305 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking): 306 _log.error('problem switching to the MMI drug database') 307 # apparently on the first call MMI does not 308 # consistently return 0 on success 309 # return False 310 311 return True
312 #--------------------------------------------------------
313 - def __let_user_select_drugs(self):
314 315 # better to clean up interactions file 316 open(self.interactions_filename, 'wb').close() 317 318 if not self.switch_to_frontend(blocking = True): 319 return None 320 321 return cGelbeListeCSVFile(filename = self.default_csv_filename)
322 #--------------------------------------------------------
323 - def import_drugs_as_substances(self):
324 325 selected_drugs = self.__let_user_select_drugs() 326 if selected_drugs is None: 327 return None 328 329 new_substances = [] 330 331 for drug in selected_drugs: 332 atc = None # hopefully MMI eventually supports atc-per-substance in a drug... 333 if len(drug['wirkstoffe']) == 1: 334 atc = drug['atc'] 335 for wirkstoff in drug['wirkstoffe']: 336 new_substances.append(gmMedication.create_substance_dose(substance = wirkstoff, atc = atc, amount = amount, unit = unit)) 337 338 selected_drugs.close() 339 340 return new_substances
341 #--------------------------------------------------------
342 - def import_drugs(self):
343 344 selected_drugs = self.__let_user_select_drugs() 345 if selected_drugs is None: 346 return None 347 348 data_src_pk = self.create_data_source_entry() 349 350 new_drugs = [] 351 new_substances = [] 352 353 for entry in selected_drugs: 354 355 _log.debug('importing drug: %s %s', entry['name'], entry['darreichungsform']) 356 357 if entry['hilfsmittel']: 358 _log.debug('skipping Hilfsmittel') 359 continue 360 361 if entry['erstattbares_medizinprodukt']: 362 _log.debug('skipping sonstiges Medizinprodukt') 363 continue 364 365 # create drug product (or get it if it already exists) 366 drug = gmMedication.create_drug_product(product_name = entry['name'], preparation = entry['darreichungsform']) 367 if drug is None: 368 drug = gmMedication.get_drug_by_name(product_name = entry['name'], preparation = entry['darreichungsform']) 369 new_drugs.append(drug) 370 371 # update fields 372 drug['is_fake_product'] = False 373 drug['atc'] = entry['atc'] 374 drug['external_code_type'] = 'DE-PZN' 375 drug['external_code'] = entry['pzn'] 376 drug['fk_data_source'] = data_src_pk 377 drug.save() 378 379 # add components to drug 380 atc = None # hopefully MMI eventually supports atc-per-substance in a drug... 381 if len(entry['wirkstoffe']) == 1: 382 atc = entry['atc'] 383 for wirkstoff in entry['wirkstoffe']: 384 drug.add_component(substance = wirkstoff, atc = atc) 385 386 # create as substance doses, too 387 atc = None # hopefully MMI eventually supports atc-per-substance in a drug... 388 if len(entry['wirkstoffe']) == 1: 389 atc = entry['atc'] 390 for wirkstoff in entry['wirkstoffe']: 391 new_substances.append(gmMedication.create_substance_dose(substance = wirkstoff, atc = atc, amount = amount, unit = unit)) 392 393 return new_drugs, new_substances
394 #--------------------------------------------------------
395 - def check_interactions(self, drug_ids_list=None, substances=None):
396 """For this to work the BDT interaction check must be configured in the MMI.""" 397 398 if drug_ids_list is None: 399 if substances is None: 400 return 401 if len(substances) < 2: 402 return 403 drug_ids_list = [ (s.external_code_type, s.external_code) for s in substances ] 404 drug_ids_list = [ code_value for code_type, code_value in drug_ids_list if (code_value is not None) and (code_type == 'DE-PZN')] 405 406 else: 407 if len(drug_ids_list) < 2: 408 return 409 410 if drug_ids_list < 2: 411 return 412 413 bdt_file = io.open(self.interactions_filename, mode = 'wt', encoding = cGelbeListeWindowsInterface.default_encoding) 414 415 for pzn in drug_ids_list: 416 pzn = pzn.strip() 417 lng = cGelbeListeWindowsInterface.bdt_line_base_length + len(pzn) 418 bdt_file.write(cGelbeListeWindowsInterface.bdt_line_template % (lng, pzn)) 419 420 bdt_file.close() 421 422 self.switch_to_frontend(blocking = True)
423 #--------------------------------------------------------
424 - def show_info_on_drug(self, drug=None):
425 self.switch_to_frontend(blocking = True)
426 #--------------------------------------------------------
427 - def show_info_on_substance(self, substance=None):
428 429 cmd = None 430 431 if substance.external_code_type == 'DE-PZN': 432 cmd = '%s -PZN %s' % (self.path_to_binary, substance.external_code) 433 434 if cmd is None: 435 name = gmTools.coalesce ( 436 substance['product'], 437 substance['substance'] 438 ) 439 cmd = '%s -NAME %s' % (self.path_to_binary, name) 440 441 # better to clean up interactions file 442 open(self.interactions_filename, 'wb').close() 443 444 self.switch_to_frontend(cmd = cmd)
445 446 #============================================================
447 -class cGelbeListeWineInterface(cGelbeListeWindowsInterface):
448
449 - def __init__(self):
450 cGelbeListeWindowsInterface.__init__(self) 451 452 _log.info('%s (WINE extension)', cGelbeListeWindowsInterface.version) 453 454 # FIXME: if -CLOSETOTRAY is used GNUmed cannot detect the end of MMI 455 self.path_to_binary = r'wine "C:\Programme\MMI PHARMINDEX\glwin.exe"' 456 self.args = r'"-PRESCRIPTIONFILE %s -KEEPBACKGROUND"' 457 458 paths = gmTools.gmPaths() 459 460 self.default_csv_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'mmi2gm.csv') 461 self.default_csv_filename_arg = r'c:\windows\temp\mmi2gm.csv' 462 self.interactions_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'gm2mmi.bdt') 463 self.data_date_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'Programme', 'MMI PHARMINDEX', 'datadate.txt')
464 465 #============================================================ 466 # FreeDiams 467 #------------------------------------------------------------
468 -class cFreeDiamsInterface(cDrugDataSourceInterface):
469 470 version = 'FreeDiams interface' 471 default_encoding = 'utf8' 472 default_dob_format = '%Y/%m/%d' 473 474 map_gender2mf = { 475 'm': 'M', 476 'f': 'F', 477 'tf': 'H', 478 'tm': 'H', 479 'h': 'H' 480 } 481 #--------------------------------------------------------
482 - def __init__(self):
483 cDrugDataSourceInterface.__init__(self) 484 _log.info(cFreeDiamsInterface.version) 485 486 self.__imported_drugs = [] 487 488 self.__gm2fd_filename = gmTools.get_unique_filename(prefix = r'gm2freediams-', suffix = r'.xml') 489 _log.debug('GNUmed -> FreeDiams "exchange-in" file: %s', self.__gm2fd_filename) 490 self.__fd2gm_filename = gmTools.get_unique_filename(prefix = r'freediams2gm-', suffix = r'.xml') 491 _log.debug('GNUmed <-> FreeDiams "exchange-out"/"prescription" file: %s', self.__fd2gm_filename) 492 paths = gmTools.gmPaths() 493 # this file can be modified by the user as needed: 494 self.__fd4gm_config_file = os.path.join(paths.home_dir, '.gnumed', 'freediams4gm.conf') 495 _log.debug('FreeDiams config file for GNUmed use: %s', self.__fd4gm_config_file) 496 497 self.path_to_binary = None 498 self.__detect_binary()
499 #--------------------------------------------------------
500 - def get_data_source_version(self):
501 # ~/.freediams/config.ini: [License] -> AcceptedVersion=.... 502 503 if not self.__detect_binary(): 504 return False 505 506 freediams = subprocess.Popen ( 507 args = '--version', # --version or -version or -v 508 executable = self.path_to_binary, 509 stdout = subprocess.PIPE, 510 stderr = subprocess.PIPE, 511 # close_fds = True, # Windows can't do that in conjunction with stdout/stderr = ... :-( 512 universal_newlines = True 513 ) 514 data, errors = freediams.communicate() 515 version = regex.search('FreeDiams\s\d.\d.\d', data).group().split()[1] 516 _log.debug('FreeDiams %s', version) 517 518 return version
519 #--------------------------------------------------------
520 - def create_data_source_entry(self):
521 return gmCoding.create_data_source ( 522 long_name = '"FreeDiams" Drug Database Frontend', 523 short_name = 'FreeDiams', 524 version = self.get_data_source_version(), 525 source = 'http://ericmaeker.fr/FreeMedForms/di-manual/index.html', 526 language = 'fr' # actually to be multi-locale 527 )
528 #--------------------------------------------------------
529 - def switch_to_frontend(self, blocking=False, mode='interactions'):
530 """http://ericmaeker.fr/FreeMedForms/di-manual/en/html/ligne_commandes.html""" 531 532 _log.debug('calling FreeDiams in [%s] mode', mode) 533 534 self.__imported_drugs = [] 535 536 if not self.__detect_binary(): 537 return False 538 539 self.__create_gm2fd_file(mode = mode) 540 541 args = '--exchange-in="%s"' % (self.__gm2fd_filename) 542 cmd = r'%s %s' % (self.path_to_binary, args) 543 if os.name == 'nt': 544 blocking = True 545 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking): 546 _log.error('problem switching to the FreeDiams drug database') 547 return False 548 549 if blocking == True: 550 self.import_fd2gm_file_as_drugs() 551 552 return True
553 #--------------------------------------------------------
554 - def import_drugs(self):
555 self.switch_to_frontend(blocking = True)
556 #--------------------------------------------------------
557 - def check_interactions(self, substance_intakes=None):
558 if substance_intakes is None: 559 return 560 if len(substance_intakes) < 2: 561 return 562 563 self.__create_prescription_file(substance_intakes = substance_intakes) 564 self.switch_to_frontend(mode = 'interactions', blocking = False)
565 #--------------------------------------------------------
566 - def show_info_on_drug(self, substance_intake=None):
567 if substance_intake is None: 568 return 569 570 self.__create_prescription_file(substance_intakes = [substance_intake]) 571 self.switch_to_frontend(mode = 'interactions', blocking = False)
572 #--------------------------------------------------------
573 - def show_info_on_substance(self, substance_intake=None):
574 self.show_info_on_drug(substance_intake = substance_intake)
575 #--------------------------------------------------------
576 - def prescribe(self, substance_intakes=None):
577 if substance_intakes is None: 578 if not self.__export_latest_prescription(): 579 self.__create_prescription_file() 580 else: 581 self.__create_prescription_file(substance_intakes = substance_intakes) 582 583 self.switch_to_frontend(mode = 'prescription', blocking = True) 584 self.import_fd2gm_file_as_prescription() 585 586 return self.__imported_drugs
587 #-------------------------------------------------------- 588 # internal helpers 589 #--------------------------------------------------------
590 - def __detect_binary(self):
591 592 if self.path_to_binary is not None: 593 return True 594 595 found, cmd = gmShellAPI.find_first_binary(binaries = [ 596 r'/usr/bin/freediams', 597 r'freediams', 598 r'/Applications/FreeDiams.app/Contents/MacOs/FreeDiams', 599 r'C:\Program Files (x86)\FreeDiams\freediams.exe', 600 r'C:\Program Files\FreeDiams\freediams.exe', 601 r'c:\programs\freediams\freediams.exe', 602 r'freediams.exe' 603 ]) 604 605 if found: 606 self.path_to_binary = cmd 607 return True 608 609 try: 610 self.custom_path_to_binary 611 except AttributeError: 612 _log.error('cannot find FreeDiams binary, no custom path set') 613 return False 614 615 if self.custom_path_to_binary is None: 616 _log.error('cannot find FreeDiams binary') 617 return False 618 619 found, cmd = gmShellAPI.detect_external_binary(binary = self.custom_path_to_binary) 620 if found: 621 self.path_to_binary = cmd 622 return True 623 624 _log.error('cannot find FreeDiams binary') 625 return False
626 #--------------------------------------------------------
628 629 if self.patient is None: 630 _log.debug('cannot export latest FreeDiams prescriptions w/o patient') 631 return False 632 633 docs = self.patient.get_document_folder() 634 prescription = docs.get_latest_freediams_prescription() 635 if prescription is None: 636 _log.debug('no FreeDiams prescription available') 637 return False 638 639 for part in prescription.parts: 640 if part['filename'] == 'freediams-prescription.xml': 641 if part.save_to_file(filename = self.__fd2gm_filename) is not None: 642 return True 643 644 _log.error('cannot export latest FreeDiams prescription to XML file') 645 646 return False
647 #--------------------------------------------------------
648 - def __create_prescription_file(self, substance_intakes=None):
649 """FreeDiams calls this exchange-out or prescription file. 650 651 CIS stands for Unique Speciality Identifier (eg bisoprolol 5 mg, gel). 652 CIS is AFSSAPS specific, but pharmacist can retreive drug name with the CIS. 653 AFSSAPS is the French FDA. 654 655 CIP stands for Unique Presentation Identifier (eg 30 pills plaq) 656 CIP if you want to specify the packaging of the drug (30 pills 657 thermoformed tablet...) -- actually not really usefull for french 658 doctors. 659 # .external_code_type: u'FR-CIS' 660 # .external_cod: the CIS value 661 662 OnlyForTest: 663 OnlyForTest drugs will be processed by the IA Engine but 664 not printed (regardless of FreeDiams mode). They are shown 665 in gray in the prescription view. 666 667 Select-only is a mode where FreeDiams creates a list of drugs 668 not a full prescription. In this list, users can add ForTestOnly 669 drug if they want to 670 1. print the list without some drugs 671 2. but including these drugs in the IA engine calculation 672 673 Select-Only mode does not have any relation with the ForTestOnly drugs. 674 675 IsTextual: 676 What is the use and significance of the 677 <IsTextual>true/false</IsTextual> 678 flag when both <DrugName> and <TextualDrugName> exist ? 679 680 This tag must be setted even if it sounds like a duplicated 681 data. This tag is needed inside FreeDiams code. 682 683 INN: 684 GNUmed will pass the substance in <TextualDrugName 685 and will also pass <INN>True</INN>. 686 687 Eric: Nop, this is not usefull because pure textual drugs 688 are not processed but just shown. 689 """ 690 # virginize file 691 open(self.__fd2gm_filename, 'wb').close() 692 693 # make sure we've got something to do 694 if substance_intakes is None: 695 if self.patient is None: 696 _log.warning('cannot create prescription file because there is neither a patient nor a substance intake list') 697 # do fail because __export_latest_prescription() should not have been called without patient 698 return False 699 emr = self.patient.emr 700 substance_intakes = emr.get_current_medications ( 701 include_inactive = False, 702 include_unapproved = True 703 ) 704 705 drug_snippets = [] 706 707 # process FD drugs 708 fd_intakes = [ i for i in substance_intakes if ( 709 (i['intake_is_approved_of'] is True) 710 and 711 (i['external_code_type_product'] is not None) 712 and 713 (i['external_code_type_product'].startswith('FreeDiams::')) 714 )] 715 716 intakes_pooled_by_product = {} 717 for intake in fd_intakes: 718 # this will leave only one entry per drug 719 # but FreeDiams knows the components ... 720 intakes_pooled_by_product[intake['product']] = intake 721 del fd_intakes 722 723 drug_snippet = """<Prescription> 724 <Drug u1="%s" u2="" old="%s" u3="" db="%s"> <!-- "old" needs to be the same as "u1" if not known --> 725 <DrugName>%s</DrugName> <!-- just for identification when reading XML files --> 726 </Drug> 727 </Prescription>""" 728 729 last_db_id = 'CA_HCDPD' 730 for intake in intakes_pooled_by_product.values(): 731 last_db_id = gmTools.xml_escape_string(text = intake['external_code_type_product'].replace('FreeDiams::', '').split('::')[0]) 732 drug_snippets.append(drug_snippet % ( 733 gmTools.xml_escape_string(text = intake['external_code_product'].strip()), 734 gmTools.xml_escape_string(text = intake['external_code_product'].strip()), 735 last_db_id, 736 gmTools.xml_escape_string(text = intake['product'].strip()) 737 )) 738 739 # process non-FD drugs 740 non_fd_intakes = [ i for i in substance_intakes if ( 741 (i['intake_is_approved_of'] is True) 742 and ( 743 (i['external_code_type_product'] is None) 744 or 745 (not i['external_code_type_product'].startswith('FreeDiams::')) 746 ) 747 )] 748 749 non_fd_product_intakes = [ i for i in non_fd_intakes if i['product'] is not None ] 750 non_fd_substance_intakes = [ i for i in non_fd_intakes if i['product'] is None ] 751 del non_fd_intakes 752 753 drug_snippet = """<Prescription> 754 <Drug u1="-1" u2="" old="" u3="" db=""> 755 <DrugName>%s</DrugName> 756 </Drug> 757 <Dose Note="%s" IsTextual="true" IsAld="false"/> 758 </Prescription>""" 759 # <DrugUidName></DrugUidName> 760 # <DrugForm></DrugForm> 761 # <DrugRoute></DrugRoute> 762 # <DrugStrength/> 763 764 for intake in non_fd_substance_intakes: 765 drug_name = '%s %s%s (%s)' % ( 766 intake['substance'], 767 intake['amount'], 768 intake['unit'], 769 intake['l10n_preparation'] 770 ) 771 drug_snippets.append(drug_snippet % ( 772 gmTools.xml_escape_string(text = drug_name.strip()), 773 gmTools.xml_escape_string(text = gmTools.coalesce(intake['schedule'], '')) 774 )) 775 776 intakes_pooled_by_product = {} 777 for intake in non_fd_product_intakes: 778 prod = '%s %s' % (intake['product'], intake['l10n_preparation']) 779 try: 780 intakes_pooled_by_product[prod].append(intake) 781 except KeyError: 782 intakes_pooled_by_product[prod] = [intake] 783 784 for product, comps in intakes_pooled_by_product.items(): 785 drug_name = '%s\n' % product 786 for comp in comps: 787 drug_name += ' %s %s%s\n' % ( 788 comp['substance'], 789 comp['amount'], 790 comp['unit'] 791 ) 792 drug_snippets.append(drug_snippet % ( 793 gmTools.xml_escape_string(text = drug_name.strip()), 794 gmTools.xml_escape_string(text = gmTools.coalesce(comps[0]['schedule'], '')) 795 )) 796 797 # assemble XML file 798 xml = """<?xml version = "1.0" encoding = "UTF-8"?> 799 <!DOCTYPE FreeMedForms> 800 <FreeDiams> 801 <FullPrescription version="0.7.2"> 802 %s 803 </FullPrescription> 804 </FreeDiams> 805 """ 806 807 xml_file = io.open(self.__fd2gm_filename, mode = 'wt', encoding = 'utf8') 808 xml_file.write(xml % '\n\t\t'.join(drug_snippets)) 809 xml_file.close() 810 811 return True
812 #--------------------------------------------------------
813 - def __create_gm2fd_file(self, mode='interactions'):
814 815 if mode == 'interactions': 816 mode = 'select-only' 817 elif mode == 'prescription': 818 mode = 'prescriber' 819 else: 820 mode = 'select-only' 821 822 xml_file = io.open(self.__gm2fd_filename, mode = 'wt', encoding = 'utf8') 823 824 xml = """<?xml version="1.0" encoding="UTF-8"?> 825 826 <FreeDiams_In version="0.5.0"> 827 <EMR name="GNUmed" uid="unused"/> 828 <ConfigFile value="%s"/> 829 <ExchangeOut value="%s" format="xml"/> 830 <!-- <DrugsDatabase uid="can be set to a specific DB"/> --> 831 <Ui editmode="%s" blockPatientDatas="1"/> 832 %%s 833 </FreeDiams_In> 834 """ % ( 835 self.__fd4gm_config_file, 836 self.__fd2gm_filename, 837 mode 838 ) 839 840 if self.patient is None: 841 xml_file.write(xml % '') 842 xml_file.close() 843 return 844 845 name = self.patient.get_active_name() 846 if self.patient['dob'] is None: 847 dob = '' 848 else: 849 dob = self.patient['dob'].strftime(cFreeDiamsInterface.default_dob_format) 850 851 emr = self.patient.emr 852 allgs = emr.get_allergies() 853 atc_allgs = [ 854 a['atc_code'] for a in allgs if ((a['atc_code'] is not None) and (a['type'] == 'allergy')) 855 ] 856 atc_sens = [ 857 a['atc_code'] for a in allgs if ((a['atc_code'] is not None) and (a['type'] == 'sensitivity')) 858 ] 859 inn_allgs = [ 860 a['allergene'] for a in allgs if ((a['allergene'] is not None) and (a['type'] == 'allergy')) 861 ] 862 inn_sens = [ 863 a['allergene'] for a in allgs if ((a['allergene'] is not None) and (a['type'] == 'sensitivity')) 864 ] 865 # this is rather fragile: FreeDiams won't know what type of UID this is 866 # (but it will assume it is of the type of the drug database in use) 867 # but eventually FreeDiams puts all drugs into one database :-) 868 uid_allgs = [ 869 a['substance_code'] for a in allgs if ((a['substance_code'] is not None) and (a['type'] == 'allergy')) 870 ] 871 uid_sens = [ 872 a['substance_code'] for a in allgs if ((a['substance_code'] is not None) and (a['type'] == 'sensitivity')) 873 ] 874 875 patient_xml = """<Patient> 876 <Identity 877 lastnames="%s" 878 firstnames="%s" 879 uid="%s" 880 dob="%s" 881 gender="%s" 882 /> 883 <!-- can be <7 characters class codes: --> 884 <ATCAllergies value="%s"/> 885 <ATCIntolerances value="%s"/> 886 887 <InnAllergies value="%s"/> 888 <InnIntolerances value="%s"/> 889 890 <DrugsUidAllergies value="%s"/> 891 <DrugsUidIntolerances value="%s"/> 892 893 <!-- 894 # FIXME: search by LOINC code and add (as soon as supported by FreeDiams ...) 895 <Creatinine value="12" unit="mg/l or mmol/l"/> 896 <Weight value="70" unit="kg or pd" /> 897 <WeightInGrams value="70"/> 898 <Height value="170" unit="cm or "/> 899 <HeightInCentimeters value="170"/> 900 <ICD10 value="J11.0;A22;Z23"/> 901 --> 902 903 </Patient> 904 """ % ( 905 gmTools.xml_escape_string(text = name['lastnames']), 906 gmTools.xml_escape_string(text = name['firstnames']), 907 self.patient.ID, 908 dob, 909 cFreeDiamsInterface.map_gender2mf[self.patient['gender']], 910 gmTools.xml_escape_string(text = ';'.join(atc_allgs)), 911 gmTools.xml_escape_string(text = ';'.join(atc_sens)), 912 gmTools.xml_escape_string(text = ';'.join(inn_allgs)), 913 gmTools.xml_escape_string(text = ';'.join(inn_sens)), 914 gmTools.xml_escape_string(text = ';'.join(uid_allgs)), 915 gmTools.xml_escape_string(text = ';'.join(uid_sens)) 916 ) 917 918 xml_file.write(xml % patient_xml) 919 xml_file.close()
920 #--------------------------------------------------------
921 - def import_fd2gm_file_as_prescription(self, filename=None):
922 923 if filename is None: 924 filename = self.__fd2gm_filename 925 926 _log.debug('importing FreeDiams prescription information from [%s]', filename) 927 928 fd2gm_xml = etree.ElementTree() 929 fd2gm_xml.parse(filename) 930 931 pdfs = fd2gm_xml.findall('ExtraDatas/Printed') 932 if len(pdfs) == 0: 933 _log.debug('no PDF prescription files listed') 934 return 935 936 fd_filenames = [] 937 for pdf in pdfs: 938 fd_filenames.append(pdf.attrib['file']) 939 940 _log.debug('listed PDF prescription files: %s', fd_filenames) 941 942 docs = self.patient.get_document_folder() 943 emr = self.patient.emr 944 945 prescription = docs.add_prescription ( 946 encounter = emr.active_encounter['pk_encounter'], 947 episode = emr.add_episode ( 948 episode_name = DEFAULT_MEDICATION_HISTORY_EPISODE, 949 is_open = False 950 )['pk_episode'] 951 ) 952 prescription['ext_ref'] = 'FreeDiams' 953 prescription.save() 954 fd_filenames.append(filename) 955 success, msg, parts = prescription.add_parts_from_files(files = fd_filenames) 956 if not success: 957 _log.error(msg) 958 return 959 960 for part in parts: 961 part['obj_comment'] = _('copy of printed prescription') 962 part.save() 963 964 xml_part = parts[-1] 965 xml_part['filename'] = 'freediams-prescription.xml' 966 xml_part['obj_comment'] = _('prescription data') 967 xml_part.save() 968 969 # are we the intended reviewer ? 970 from Gnumed.business.gmStaff import gmCurrentProvider 971 me = gmCurrentProvider() 972 # if so: auto-sign the prescription 973 if xml_part['pk_intended_reviewer'] == me['pk_staff']: 974 prescription.set_reviewed(technically_abnormal = False, clinically_relevant = False)
975 #--------------------------------------------------------
976 - def import_fd2gm_file_as_drugs(self, filename=None):
977 """ 978 If returning textual prescriptions (say, drugs which FreeDiams 979 did not know) then "IsTextual" will be True and UID will be -1. 980 """ 981 if filename is None: 982 filename = self.__fd2gm_filename 983 984 # FIXME: do not import IsTextual drugs, or rather, make that configurable 985 986 fd2gm_xml = etree.ElementTree() 987 fd2gm_xml.parse(filename) 988 989 data_src_pk = self.create_data_source_entry() 990 991 xml_version = fd2gm_xml.find('FullPrescription').attrib['version'] 992 _log.debug('fd2gm file version: %s', xml_version) 993 994 if xml_version in ['0.6.0', '0.7.2']: 995 return self.__import_fd2gm_file_as_drugs_0_6_0(fd2gm_xml = fd2gm_xml, pk_data_source = data_src_pk) 996 997 return self.__import_fd2gm_file_as_drugs_0_5(fd2gm_xml = fd2gm_xml, pk_data_source = data_src_pk)
998 #--------------------------------------------------------
999 - def __import_fd2gm_file_as_drugs_0_6_0(self, fd2gm_xml=None, pk_data_source=None):
1000 1001 # drug_id_name = db_def.attrib['drugUidName'] 1002 fd_xml_prescriptions = fd2gm_xml.findall('FullPrescription/Prescription') 1003 1004 self.__imported_drugs = [] 1005 for fd_xml_prescription in fd_xml_prescriptions: 1006 drug_uid = fd_xml_prescription.find('Drug').attrib['u1'].strip() 1007 if drug_uid == '-1': 1008 _log.debug('skipping textual drug') 1009 continue 1010 drug_db = fd_xml_prescription.find('Drug').attrib['db'].strip() 1011 drug_uid_name = fd_xml_prescription.find('Drug/DrugUidName').text.strip() 1012 #drug_uid_name = u'<%s>' % drug_db 1013 drug_name = fd_xml_prescription.find('Drug/DrugName').text.replace(', )', ')').strip() 1014 drug_form = fd_xml_prescription.find('Drug/DrugForm').text.strip() 1015 # drug_atc = fd_xml_prescription.find('DrugATC') 1016 # if drug_atc is None: 1017 # drug_atc = u'' 1018 # else: 1019 # if drug_atc.text is None: 1020 # drug_atc = u'' 1021 # else: 1022 # drug_atc = drug_atc.text.strip() 1023 1024 # create new drug product 1025 new_drug = gmMedication.create_drug_product(product_name = drug_name, preparation = drug_form, return_existing = True) 1026 self.__imported_drugs.append(new_drug) 1027 new_drug['is_fake_product'] = False 1028 # new_drug['atc'] = drug_atc 1029 new_drug['external_code_type'] = 'FreeDiams::%s::%s' % (drug_db, drug_uid_name) 1030 new_drug['external_code'] = drug_uid 1031 new_drug['pk_data_source'] = pk_data_source 1032 new_drug.save() 1033 1034 # parse XML for composition records 1035 fd_xml_components = fd_xml_prescription.getiterator('Composition') 1036 comp_data = {} 1037 for fd_xml_comp in fd_xml_components: 1038 1039 data = {} 1040 1041 xml_strength = fd_xml_comp.attrib['strength'].strip() 1042 amount = regex.match(r'^\d+[.,]{0,1}\d*', xml_strength) 1043 if amount is None: 1044 amount = 99999 1045 else: 1046 amount = amount.group() 1047 data['amount'] = amount 1048 1049 #unit = regex.sub(r'\d+[.,]{0,1}\d*', u'', xml_strength).strip() 1050 unit = (xml_strength[len(amount):]).strip() 1051 if unit == '': 1052 unit = '*?*' 1053 data['unit'] = unit 1054 1055 # hopefully, FreeDiams gets their act together, eventually: 1056 atc = regex.match(r'[A-Za-z]\d\d[A-Za-z]{2}\d\d', fd_xml_comp.attrib['atc'].strip()) 1057 if atc is None: 1058 data['atc'] = None 1059 else: 1060 atc = atc.group() 1061 data['atc'] = atc 1062 1063 molecule_name = fd_xml_comp.attrib['molecularName'].strip() 1064 if molecule_name != '': 1065 gmMedication.create_substance_dose(substance = molecule_name, atc = atc, amount = amount, unit = unit) 1066 data['molecule_name'] = molecule_name 1067 1068 inn_name = fd_xml_comp.attrib['inn'].strip() 1069 if inn_name != '': 1070 gmMedication.create_substance_dose(substance = inn_name, atc = atc, amount = amount, unit = unit) 1071 #data['inn_name'] = molecule_name 1072 data['inn_name'] = inn_name 1073 1074 if molecule_name == '': 1075 data['substance'] = inn_name 1076 _log.info('linking INN [%s] rather than molecularName as component', inn_name) 1077 else: 1078 data['substance'] = molecule_name 1079 1080 data['nature'] = fd_xml_comp.attrib['nature'].strip() 1081 data['nature_ID'] = fd_xml_comp.attrib['natureLink'].strip() 1082 1083 # merge composition records of SA/FT nature 1084 try: 1085 old_data = comp_data[data['nature_ID']] 1086 # normalize INN 1087 if old_data['inn_name'] == '': 1088 old_data['inn_name'] = data['inn_name'] 1089 if data['inn_name'] == '': 1090 data['inn_name'] = old_data['inn_name'] 1091 # normalize molecule 1092 if old_data['molecule_name'] == '': 1093 old_data['molecule_name'] = data['molecule_name'] 1094 if data['molecule_name'] == '': 1095 data['molecule_name'] = old_data['molecule_name'] 1096 # normalize ATC 1097 if old_data['atc'] == '': 1098 old_data['atc'] = data['atc'] 1099 if data['atc'] == '': 1100 data['atc'] = old_data['atc'] 1101 # FT: transformed form 1102 # SA: active substance 1103 # it would be preferable to use the SA record because that's what's *actually* 1104 # contained in the drug, however FreeDiams does not list the amount thereof 1105 # (rather that of the INN) 1106 # FT and SA records of the same component carry the same nature_ID 1107 if data['nature'] == 'FT': 1108 comp_data[data['nature_ID']] = data 1109 else: 1110 comp_data[data['nature_ID']] = old_data 1111 1112 # or create new record 1113 except KeyError: 1114 comp_data[data['nature_ID']] = data 1115 1116 # actually create components from (possibly merged) composition records 1117 for key, data in comp_data.items(): 1118 new_drug.add_component ( 1119 substance = data['substance'], 1120 atc = data['atc'], 1121 amount = data['amount'], 1122 unit = data['unit'] 1123 )
1124 #--------------------------------------------------------
1125 - def __import_fd2gm_file_as_drugs_0_5(self, fd2gm_xml=None, pk_data_source=None):
1126 1127 db_def = fd2gm_xml.find('DrugsDatabaseName') 1128 db_id = db_def.text.strip() 1129 drug_id_name = db_def.attrib['drugUidName'] 1130 fd_xml_drug_entries = fd2gm_xml.findall('FullPrescription/Prescription') 1131 1132 self.__imported_drugs = [] 1133 for fd_xml_drug in fd_xml_drug_entries: 1134 drug_uid = fd_xml_drug.find('Drug_UID').text.strip() 1135 if drug_uid == '-1': 1136 _log.debug('skipping textual drug') 1137 continue # it's a TextualDrug, skip it 1138 drug_name = fd_xml_drug.find('DrugName').text.replace(', )', ')').strip() 1139 drug_form = fd_xml_drug.find('DrugForm').text.strip() 1140 drug_atc = fd_xml_drug.find('DrugATC') 1141 if drug_atc is None: 1142 drug_atc = '' 1143 else: 1144 if drug_atc.text is None: 1145 drug_atc = '' 1146 else: 1147 drug_atc = drug_atc.text.strip() 1148 1149 # create new drug product 1150 new_drug = gmMedication.create_drug_product(product_name = drug_name, preparation = drug_form, return_existing = True) 1151 self.__imported_drugs.append(new_drug) 1152 new_drug['is_fake_product'] = False 1153 new_drug['atc'] = drug_atc 1154 new_drug['external_code_type'] = 'FreeDiams::%s::%s' % (db_id, drug_id_name) 1155 new_drug['external_code'] = drug_uid 1156 new_drug['pk_data_source'] = pk_data_source 1157 new_drug.save() 1158 1159 # parse XML for composition records 1160 fd_xml_components = fd_xml_drug.getiterator('Composition') 1161 comp_data = {} 1162 for fd_xml_comp in fd_xml_components: 1163 1164 data = {} 1165 1166 amount = regex.match(r'\d+[.,]{0,1}\d*', fd_xml_comp.attrib['strenght'].strip()) # sic, typo 1167 if amount is None: 1168 amount = 99999 1169 else: 1170 amount = amount.group() 1171 data['amount'] = amount 1172 1173 unit = regex.sub(r'\d+[.,]{0,1}\d*', '', fd_xml_comp.attrib['strenght'].strip()).strip() # sic, typo 1174 if unit == '': 1175 unit = '*?*' 1176 data['unit'] = unit 1177 1178 molecule_name = fd_xml_comp.attrib['molecularName'].strip() 1179 if molecule_name != '': 1180 gmMedication.create_substance_dose(substance = molecule_name, atc = None, amount = amount, unit = unit) 1181 data['molecule_name'] = molecule_name 1182 1183 inn_name = fd_xml_comp.attrib['inn'].strip() 1184 if inn_name != '': 1185 gmMedication.create_substance_dose(substance = inn_name, atc = None, amount = amount, unit = unit) 1186 data['inn_name'] = molecule_name 1187 1188 if molecule_name == '': 1189 data['substance'] = inn_name 1190 _log.info('linking INN [%s] rather than molecularName as component', inn_name) 1191 else: 1192 data['substance'] = molecule_name 1193 1194 data['nature'] = fd_xml_comp.attrib['nature'].strip() 1195 data['nature_ID'] = fd_xml_comp.attrib['natureLink'].strip() 1196 1197 # merge composition records of SA/FT nature 1198 try: 1199 old_data = comp_data[data['nature_ID']] 1200 # normalize INN 1201 if old_data['inn_name'] == '': 1202 old_data['inn_name'] = data['inn_name'] 1203 if data['inn_name'] == '': 1204 data['inn_name'] = old_data['inn_name'] 1205 # normalize molecule 1206 if old_data['molecule_name'] == '': 1207 old_data['molecule_name'] = data['molecule_name'] 1208 if data['molecule_name'] == '': 1209 data['molecule_name'] = old_data['molecule_name'] 1210 # FT: transformed form 1211 # SA: active substance 1212 # it would be preferable to use the SA record because that's what's *actually* 1213 # contained in the drug, however FreeDiams does not list the amount thereof 1214 # (rather that of the INN) 1215 if data['nature'] == 'FT': 1216 comp_data[data['nature_ID']] = data 1217 else: 1218 comp_data[data['nature_ID']] = old_data 1219 1220 # or create new record 1221 except KeyError: 1222 comp_data[data['nature_ID']] = data 1223 1224 # actually create components from (possibly merged) composition records 1225 for key, data in comp_data.items(): 1226 new_drug.add_component ( 1227 substance = data['substance'], 1228 amount = data['amount'], 1229 unit = data['unit'] 1230 )
1231 1232 #============================================================ 1233 # Ifap 1234 #------------------------------------------------------------
1235 -class cIfapInterface(cDrugDataSourceInterface):
1236 """empirical CSV interface""" 1237
1238 - def __init__(self):
1239 pass
1240
1241 - def print_transfer_file(self, filename=None):
1242 1243 try: 1244 csv_file = io.open(filename, mode = 'rt', encoding = 'latin1') # FIXME: encoding correct ? 1245 except: 1246 _log.exception('cannot access [%s]', filename) 1247 csv_file = None 1248 1249 field_names = 'PZN Handelsname Form Abpackungsmenge Einheit Preis1 Hersteller Preis2 rezeptpflichtig Festbetrag Packungszahl Packungsgr\xf6\xdfe'.split() 1250 1251 if csv_file is None: 1252 return False 1253 1254 csv_lines = csv.DictReader ( 1255 csv_file, 1256 fieldnames = field_names, 1257 delimiter = ';' 1258 ) 1259 1260 for line in csv_lines: 1261 print("--------------------------------------------------------------------"[:31]) 1262 for key in field_names: 1263 tmp = ('%s ' % key)[:30] 1264 print('%s: %s' % (tmp, line[key])) 1265 1266 csv_file.close()
1267 1268 # narr = u'%sx %s %s %s (\u2258 %s %s) von %s (%s)' % ( 1269 # line['Packungszahl'].strip(), 1270 # line['Handelsname'].strip(), 1271 # line['Form'].strip(), 1272 # line[u'Packungsgr\xf6\xdfe'].strip(), 1273 # line['Abpackungsmenge'].strip(), 1274 # line['Einheit'].strip(), 1275 # line['Hersteller'].strip(), 1276 # line['PZN'].strip() 1277 # ) 1278 1279 #============================================================ 1280 drug_data_source_interfaces = { 1281 'Deutschland: Gelbe Liste/MMI (Windows)': cGelbeListeWindowsInterface, 1282 'Deutschland: Gelbe Liste/MMI (WINE)': cGelbeListeWineInterface, 1283 'FreeDiams (FR, US, CA, ZA)': cFreeDiamsInterface 1284 } 1285 1286 #============================================================ 1287 # main 1288 #------------------------------------------------------------ 1289 if __name__ == "__main__": 1290 1291 if len(sys.argv) < 2: 1292 sys.exit() 1293 1294 if sys.argv[1] != 'test': 1295 sys.exit() 1296 1297 from Gnumed.business import gmPerson 1298 1299 #--------------------------------------------------------
1300 - def test_MMI_interface():
1301 mmi = cGelbeListeWineInterface() 1302 print(mmi) 1303 print("interface definition:", mmi.version) 1304 print("database versions: ", mmi.get_data_source_version())
1305 #--------------------------------------------------------
1306 - def test_MMI_file():
1307 mmi_file = cGelbeListeCSVFile(filename = sys.argv[2]) 1308 for drug in mmi_file: 1309 print("-------------") 1310 print('"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn'])) 1311 for stoff in drug['wirkstoffe']: 1312 print(" Wirkstoff:", stoff) 1313 input() 1314 if mmi_file.has_unknown_fields is not None: 1315 print("has extra data under [%s]" % gmTools.default_csv_reader_rest_key) 1316 for key in mmi_file.csv_fieldnames: 1317 print(key, '->', drug[key]) 1318 input() 1319 mmi_file.close()
1320 #--------------------------------------------------------
1321 - def test_mmi_switch_to():
1322 mmi = cGelbeListeWineInterface() 1323 mmi.switch_to_frontend(blocking = True)
1324 #--------------------------------------------------------
1325 - def test_mmi_let_user_select_drugs():
1326 mmi = cGelbeListeWineInterface() 1327 mmi_file = mmi.__let_user_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 #--------------------------------------------------------
1336 - def test_mmi_import_drugs():
1337 mmi = cGelbeListeWineInterface() 1338 mmi.import_drugs()
1339 #--------------------------------------------------------
1340 - def test_mmi_interaction_check():
1341 mmi = cGelbeListeInterface() 1342 print(mmi) 1343 print("interface definition:", mmi.version) 1344 # Metoprolol + Hct vs Citalopram 1345 diclofenac = '7587712' 1346 phenprocoumon = '4421744' 1347 mmi.check_interactions(drug_ids_list = [diclofenac, phenprocoumon])
1348 #-------------------------------------------------------- 1349 # FreeDiams 1350 #--------------------------------------------------------
1351 - def test_fd_switch_to():
1352 gmPerson.set_active_patient(patient = gmPerson.cPerson(aPK_obj = 12)) 1353 fd = cFreeDiamsInterface() 1354 fd.patient = gmPerson.gmCurrentPatient() 1355 # fd.switch_to_frontend(blocking = True) 1356 fd.import_fd2gm_file_as_drugs(filename = sys.argv[2])
1357 #--------------------------------------------------------
1358 - def test_fd_show_interactions():
1359 gmPerson.set_active_patient(patient = gmPerson.cPerson(aPK_obj = 12)) 1360 fd = cFreeDiamsInterface() 1361 fd.patient = gmPerson.gmCurrentPatient() 1362 fd.check_interactions(substances = fd.patient.emr.get_current_medications(include_unapproved = True))
1363 1364 #-------------------------------------------------------- 1365 # MMI/Gelbe Liste 1366 #test_MMI_interface() 1367 #test_MMI_file() 1368 #test_mmi_switch_to() 1369 #test_mmi_let_user_select_drugs() 1370 #test_mmi_import_substances() 1371 #test_mmi_import_drugs() 1372 1373 # FreeDiams 1374 #test_fd_switch_to() 1375 #test_fd_show_interactions() 1376