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

Source Code for Module Gnumed.business.gmMedication

   1  # -*- coding: utf8 -*- 
   2  """Medication handling code. 
   3   
   4  license: GPL 
   5  """ 
   6  #============================================================ 
   7  __version__ = "$Revision: 1.21 $" 
   8  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>" 
   9   
  10  import sys, logging, csv, codecs, os, re as regex, subprocess 
  11   
  12   
  13  if __name__ == '__main__': 
  14          sys.path.insert(0, '../../') 
  15  from Gnumed.pycommon import gmBusinessDBObject, gmPG2, gmShellAPI, gmTools 
  16  from Gnumed.pycommon import gmDispatcher, gmDateTime, gmHooks 
  17  from Gnumed.business import gmATC, gmAllergy 
  18   
  19   
  20  _log = logging.getLogger('gm.meds') 
  21  _log.info(__version__) 
  22   
  23  #============================================================ 
24 -def _on_substance_intake_modified():
25 """Always relates to the active patient.""" 26 gmHooks.run_hook_script(hook = u'after_substance_intake_modified')
27 28 gmDispatcher.connect(_on_substance_intake_modified, u'substance_intake_mod_db') 29 30 #============================================================
31 -def drug2renal_insufficiency_url(search_term=None):
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 url_template = u'http://www.google.de/search?hl=de&source=hp&q=site%%3Adosing.de+%s&btnG=Google-Suche' 64 url = url_template % u'+OR+'.join(terms) 65 66 _log.debug(u'renal insufficiency URL: %s', url) 67 68 return url
69 #============================================================ 70 # this should be in gmCoding.py
71 -def create_data_source(long_name=None, short_name=None, version=None, source=None, language=None):
72 73 args = { 74 'lname': long_name, 75 'sname': short_name, 76 'ver': version, 77 'src': source, 78 'lang': language 79 } 80 81 cmd = u"""select pk from ref.data_source where name_long = %(lname)s and name_short = %(sname)s and version = %(ver)s""" 82 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 83 if len(rows) > 0: 84 return rows[0]['pk'] 85 86 cmd = u""" 87 INSERT INTO ref.data_source (name_long, name_short, version, source, lang) 88 VALUES ( 89 %(lname)s, 90 %(sname)s, 91 %(ver)s, 92 %(src)s, 93 %(lang)s 94 ) 95 returning pk 96 """ 97 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 98 99 return rows[0]['pk']
100 #============================================================ 101 # wishlist: 102 # - --conf-file= for glwin.exe 103 # - wirkstoff: Konzentration auch in Multiprodukten 104 # - wirkstoff: ATC auch in Multiprodukten 105 # - Suche nach ATC per CLI 106
107 -class cGelbeListeCSVFile(object):
108 """Iterator over a Gelbe Liste/MMI v8.2 CSV file.""" 109 110 version = u'Gelbe Liste/MMI v8.2 CSV file interface' 111 default_transfer_file_windows = r"c:\rezept.txt" 112 #default_encoding = 'cp1252' 113 default_encoding = 'cp1250' 114 csv_fieldnames = [ 115 u'name', 116 u'packungsgroesse', # obsolete, use "packungsmenge" 117 u'darreichungsform', 118 u'packungstyp', 119 u'festbetrag', 120 u'avp', 121 u'hersteller', 122 u'rezepttext', 123 u'pzn', 124 u'status_vertrieb', 125 u'status_rezeptpflicht', 126 u'status_fachinfo', 127 u'btm', 128 u'atc', 129 u'anzahl_packungen', 130 u'zuzahlung_pro_packung', 131 u'einheit', 132 u'schedule_morgens', 133 u'schedule_mittags', 134 u'schedule_abends', 135 u'schedule_nachts', 136 u'status_dauermedikament', 137 u'status_hausliste', 138 u'status_negativliste', 139 u'ik_nummer', 140 u'status_rabattvertrag', 141 u'wirkstoffe', 142 u'wirkstoffmenge', 143 u'wirkstoffeinheit', 144 u'wirkstoffmenge_bezug', 145 u'wirkstoffmenge_bezugseinheit', 146 u'status_import', 147 u'status_lifestyle', 148 u'status_ausnahmeliste', 149 u'packungsmenge', 150 u'apothekenpflicht', 151 u'status_billigere_packung', 152 u'rezepttyp', 153 u'besonderes_arzneimittel', # Abstimmungsverfahren SGB-V 154 u't_rezept_pflicht', # Thalidomid-Rezept 155 u'erstattbares_medizinprodukt', 156 u'hilfsmittel', 157 u'hzv_rabattkennung', 158 u'hzv_preis' 159 ] 160 boolean_fields = [ 161 u'status_rezeptpflicht', 162 u'status_fachinfo', 163 u'btm', 164 u'status_dauermedikament', 165 u'status_hausliste', 166 u'status_negativliste', 167 u'status_rabattvertrag', 168 u'status_import', 169 u'status_lifestyle', 170 u'status_ausnahmeliste', 171 u'apothekenpflicht', 172 u'status_billigere_packung', 173 u'besonderes_arzneimittel', # Abstimmungsverfahren SGB-V 174 u't_rezept_pflicht', 175 u'erstattbares_medizinprodukt', 176 u'hilfsmittel' 177 ] 178 #--------------------------------------------------------
179 - def __init__(self, filename=None):
180 181 _log.info(cGelbeListeCSVFile.version) 182 183 self.filename = filename 184 if filename is None: 185 self.filename = cGelbeListeCSVFile.default_transfer_file_windows 186 187 _log.debug('reading Gelbe Liste/MMI drug data from [%s]', self.filename) 188 189 self.csv_file = codecs.open(filename = filename, mode = 'rUb', encoding = cGelbeListeCSVFile.default_encoding) 190 191 self.csv_lines = gmTools.unicode_csv_reader ( 192 self.csv_file, 193 fieldnames = cGelbeListeCSVFile.csv_fieldnames, 194 delimiter = ';', 195 quotechar = '"', 196 dict = True 197 )
198 #--------------------------------------------------------
199 - def __iter__(self):
200 return self
201 #--------------------------------------------------------
202 - def next(self):
203 line = self.csv_lines.next() 204 205 for field in cGelbeListeCSVFile.boolean_fields: 206 line[field] = (line[field].strip() == u'T') 207 208 # split field "Wirkstoff" by ";" 209 if line['wirkstoffe'].strip() == u'': 210 line['wirkstoffe'] = [] 211 else: 212 line['wirkstoffe'] = [ wirkstoff.strip() for wirkstoff in line['wirkstoffe'].split(u';') ] 213 214 return line
215 #--------------------------------------------------------
216 - def close(self, truncate=True):
217 try: self.csv_file.close() 218 except: pass 219 220 if truncate: 221 try: os.open(self.filename, 'wb').close 222 except: pass
223 #============================================================
224 -class cDrugDataSourceInterface(object):
225 226 #--------------------------------------------------------
227 - def __init__(self):
228 self.patient = None 229 self.custom_path_to_binary = None
230 #--------------------------------------------------------
231 - def get_data_source_version(self):
232 raise NotImplementedError
233 #--------------------------------------------------------
234 - def create_data_source_entry(self):
235 raise NotImplementedError
236 #--------------------------------------------------------
237 - def switch_to_frontend(self, blocking=False):
238 raise NotImplementedError
239 #--------------------------------------------------------
240 - def select_drugs(self):
241 raise NotImplementedError
242 #--------------------------------------------------------
243 - def import_drugs(self):
244 raise NotImplementedError
245 #--------------------------------------------------------
246 - def check_drug_interactions(self, drug_ids_list=None, substances=None):
247 raise NotImplementedError
248 #--------------------------------------------------------
249 - def show_info_on_drug(self, drug=None):
250 raise NotImplementedError
251 #============================================================
252 -class cFreeDiamsInterface(cDrugDataSourceInterface):
253 254 version = u'FreeDiams v0.4.2 interface' 255 default_encoding = 'utf8' 256 default_dob_format = '%Y/%m/%d' 257 258 map_gender2mf = { 259 'm': u'M', 260 'f': u'F', 261 'tf': u'H', 262 'tm': u'H', 263 'h': u'H' 264 } 265 #--------------------------------------------------------
266 - def __init__(self):
267 cDrugDataSourceInterface.__init__(self) 268 _log.info(cFreeDiamsInterface.version) 269 270 paths = gmTools.gmPaths() 271 self.__gm2fd_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'gm2freediams.xml') 272 self.__fd2gm_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'freediams2gm.xml') 273 self.__fd4gm_config_file = os.path.join(paths.home_dir, '.gnumed', 'freediams4gm.conf') 274 275 self.path_to_binary = None 276 self.__detect_binary()
277 #--------------------------------------------------------
278 - def get_data_source_version(self):
279 # ~/.freediams/config.ini: [License] -> AcceptedVersion=.... 280 281 if not self.__detect_binary(): 282 return False 283 284 freediams = subprocess.Popen ( 285 args = u'--version', # --version or -version or -v 286 executable = self.path_to_binary, 287 stdout = subprocess.PIPE, 288 stderr = subprocess.PIPE, 289 # close_fds = True, # Windows can't do that in conjunction with stdout/stderr = ... :-( 290 universal_newlines = True 291 ) 292 data, errors = freediams.communicate() 293 ver = regex.search('FreeDiams\s\d.\d.\d', data).group().split()[1] 294 _log.debug('FreeDiams %s', ver) 295 296 return version
297 #--------------------------------------------------------
298 - def create_data_source_entry(self):
299 return create_data_source ( 300 long_name = u'"FreeDiams" Drug Database Frontend', 301 short_name = u'FreeDiams', 302 version = self.get_data_source_version(), 303 source = u'http://ericmaeker.fr/FreeMedForms/di-manual/index.html', 304 language = u'fr' # actually to be multi-locale 305 )
306 #--------------------------------------------------------
307 - def switch_to_frontend(self, blocking=False):
308 """http://ericmaeker.fr/FreeMedForms/di-manual/en/html/ligne_commandes.html""" 309 310 if not self.__detect_binary(): 311 return False 312 313 self.__create_gm2fd_file() 314 open(self.__fd2gm_filename, 'wb').close() 315 316 args = u'--exchange-in="%s"' % (self.__gm2fd_filename) 317 318 cmd = r'%s %s' % (self.path_to_binary, args) 319 320 # if self.patient is not None: 321 # names = self.patient.get_active_name() 322 # args += u' --patientname="%(lastnames)s, %(firstnames)s"' % names 323 # args += u' --patientsurname="%(lastnames)s"' % names 324 # args += u' --gender=%s' % cFreeDiamsInterface.map_gender2mf[self.patient['gender']] 325 # if self.patient['dob'] is not None: 326 # args += u' --dateofbirth=%s' % self.patient['dob'].strftime(cFreeDiamsInterface.default_dob_format) 327 328 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking): 329 _log.error('problem switching to the FreeDiams drug database') 330 return False 331 332 return True
333 #--------------------------------------------------------
334 - def select_drugs(self):
335 self.switch_to_frontend()
336 #--------------------------------------------------------
337 - def import_drugs(self):
338 """FreeDiams ONLY use CIS. 339 340 CIS stands for Unique Speciality Identifier (eg bisoprolol 5 mg, gel). 341 CIS is AFSSAPS specific, but pharmacist can retreive drug name with the CIS. 342 AFSSAPS is the French FDA. 343 344 CIP stands for Unique Presentation Identifier (eg 30 pills plaq) 345 CIP if you want to specify the packaging of the drug (30 pills 346 thermoformed tablet...) -- actually not really usefull for french 347 doctors. 348 """ 349 self.switch_to_frontend()
350 # .external_code_type: u'FR-CIS' 351 # .external_cod: the CIS value 352 #--------------------------------------------------------
353 - def check_drug_interactions(self, drug_ids_list=None, substances=None):
354 self.switch_to_frontend()
355 #--------------------------------------------------------
356 - def show_info_on_drug(self, drug=None):
357 # pass in CIS 358 self.switch_to_frontend()
359 #-------------------------------------------------------- 360 # internal helpers 361 #--------------------------------------------------------
362 - def __detect_binary(self):
363 364 if self.path_to_binary is not None: 365 return True 366 367 found, cmd = gmShellAPI.find_first_binary(binaries = [ 368 r'/usr/bin/freediams', 369 r'freediams', 370 r'/Applications/FreeDiams.app/Contents/MacOs/FreeDiams', 371 r'c:\programs\freediams\freediams.exe', 372 r'freediams.exe' 373 ]) 374 375 if found: 376 self.path_to_binary = cmd 377 return True 378 379 try: 380 self.custom_path_to_binary 381 except AttributeError: 382 _log.error('cannot find FreeDiams binary, no custom path set') 383 return False 384 385 found, cmd = gmShellAPI.detect_external_binary(binary = self.custom_path_to_binary) 386 if found: 387 self.path_to_binary = cmd 388 return True 389 390 _log.error('cannot find FreeDiams binary') 391 return False
392 #--------------------------------------------------------
393 - def __create_gm2fd_file(self):
394 395 xml_file = codecs.open(self.__gm2fd_filename, 'wb', 'utf8') 396 if self.patient is None: 397 xml_file.close() 398 return 399 400 name = self.patient.get_active_name() 401 if self.patient['dob'] is None: 402 dob = u'' 403 else: 404 dob = self.patient['dob'].strftime(cFreeDiamsInterface.default_dob_format) 405 406 emr = self.patient.get_emr() 407 allgs = emr.get_allergies() # leave out sensitivities ? 408 atcs = [ a['atc_code'] for a in allgs if a['atc_code'] is not None ] 409 inns = [ a['allergene'] for a in allgs ] 410 # this is rather fragile: FreeDiams won't know what type of UID this is 411 # (but it will assume it is of the type of the drug database in use) 412 uids = [ a['substance_code'] for a in allgs if a['substance_code'] is not None ] 413 414 # Eric says the order of same-level nodes does not matter. 415 xml = u"""<?xml version="1.0" encoding="UTF-8"?> 416 417 <FreeDiams_In version="0.4.2"> 418 <EMR name="GNUmed" uid="unused"/> 419 <ConfigFile value="%s"/> 420 <OutFile value="%s" format="html_xml"/> 421 <Ui editmode="select-only" blockPatientDatas="1"/> 422 <Patient> 423 <Identity name="%s" surname="%s" uid="%s" dob="%s" gender="%s"/> 424 <ATCAllergies value="%s"/> 425 <InnAllergies value="%s"/> 426 <DrugsUidAllergies value="%s"/> 427 </Patient> 428 </FreeDiams_In> 429 430 <!-- 431 <InnIntolerances value=""/> 432 <ATCIntolerances value="B05B"/> 433 <DrugsUidIntolerances value="68586203;62869109"/> 434 # FIXME: search by LOINC code and add (as soon as supported by FreeDiams ...) 435 <Creatinine value="12" unit="mg/l or mmol/l"/> 436 <Weight value="70" unit="kg or pd" /> 437 <Height value="170" unit="cm or "/> 438 <ICD10 value="J11.0;A22;Z23"/> 439 --> 440 """ % ( 441 self.__fd4gm_config_file, 442 self.__fd2gm_filename, 443 name['firstnames'], name['lastnames'], self.patient.ID, dob, cFreeDiamsInterface.map_gender2mf[self.patient['gender']], 444 u';'.join(atcs), 445 u';'.join(inns), 446 u';'.join(uids) 447 ) 448 449 xml_file = codecs.open(self.__gm2fd_filename, 'wb', 'utf8') 450 xml_file.write(xml) 451 xml_file.close()
452 #--------------------------------------------------------
453 - def import_fd2gm_file(self):
454 455 # fixed_xml = codecs.open(gmTools.get_unique_filename(suffix = '.xml', 'w', 'utf-8') 456 # for line in self.__fd2gm_filename: 457 458 # fd2gm = codecs.open(self.__fd2gm_filename, 'rU', 'utf-8') 459 460 from xml.etree import ElementTree as etree 461 462 fd2gm_xml = etree.ElementTree() 463 fd2gm_xml.parse(self.__fd2gm_filename) 464 465 print fd2gm_xml
466 467 #============================================================
468 -class cGelbeListeWindowsInterface(cDrugDataSourceInterface):
469 """Support v8.2 CSV file interface only.""" 470 471 version = u'Gelbe Liste/MMI v8.2 interface' 472 default_encoding = 'cp1250' 473 bdt_line_template = u'%03d6210#%s\r\n' # Medikament verordnet auf Kassenrezept 474 bdt_line_base_length = 8 475 #--------------------------------------------------------
476 - def __init__(self):
477 478 cDrugDataSourceInterface.__init__(self) 479 480 _log.info(u'%s (native Windows)', cGelbeListeWindowsInterface.version) 481 482 self.path_to_binary = r'C:\Programme\MMI PHARMINDEX\glwin.exe' 483 self.args = r'-KEEPBACKGROUND -PRESCRIPTIONFILE %s -CLOSETOTRAY' 484 485 paths = gmTools.gmPaths() 486 487 self.default_csv_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'rezept.txt') 488 self.default_csv_filename_arg = os.path.join(paths.home_dir, '.gnumed', 'tmp') 489 self.interactions_filename = os.path.join(paths.home_dir, '.gnumed', 'tmp', 'gm2mmi.bdt') 490 self.data_date_filename = r'C:\Programme\MMI PHARMINDEX\datadate.txt' 491 492 self.__data_date = None 493 self.__online_update_date = None
494 495 # use adjusted config.dat 496 #--------------------------------------------------------
497 - def get_data_source_version(self, force_reload=False):
498 499 if self.__data_date is not None: 500 if not force_reload: 501 return { 502 'data': self.__data_date, 503 'online_update': self.__online_update_date 504 } 505 506 open(self.data_date_filename, 'wb').close() 507 508 cmd = u'%s -DATADATE' % self.path_to_binary 509 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = True): 510 _log.error('problem querying the MMI drug database for version information') 511 self.__data_date = None 512 self.__online_update_date = None 513 return { 514 'data': u'?', 515 'online_update': u'?' 516 } 517 518 try: 519 version_file = open(self.data_date_filename, 'rU') 520 except StandardError: 521 _log.error('problem querying the MMI drug database for version information') 522 _log.exception('cannot open MMI drug database version file [%s]', self.data_date_filename) 523 self.__data_date = None 524 self.__online_update_date = None 525 return { 526 'data': u'?', 527 'online_update': u'?' 528 } 529 530 self.__data_date = version_file.readline()[:10] 531 self.__online_update_date = version_file.readline()[:10] 532 version_file.close() 533 534 return { 535 'data': self.__data_date, 536 'online_update': self.__online_update_date 537 }
538 #--------------------------------------------------------
539 - def create_data_source_entry(self):
540 versions = self.get_data_source_version() 541 542 return create_data_source ( 543 long_name = u'Medikamentendatenbank "mmi PHARMINDEX" (Gelbe Liste)', 544 short_name = u'GL/MMI', 545 version = u'Daten: %s, Preise (Onlineupdate): %s' % (versions['data'], versions['online_update']), 546 source = u'Medizinische Medien Informations GmbH, Am Forsthaus Gravenbruch 7, 63263 Neu-Isenburg', 547 language = u'de' 548 )
549 #--------------------------------------------------------
550 - def switch_to_frontend(self, blocking=False, cmd=None):
551 552 # must make sure csv file exists 553 open(self.default_csv_filename, 'wb').close() 554 555 if cmd is None: 556 cmd = (u'%s %s' % (self.path_to_binary, self.args)) % self.default_csv_filename_arg 557 558 if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking): 559 _log.error('problem switching to the MMI drug database') 560 # apparently on the first call MMI does not 561 # consistently return 0 on success 562 # return False 563 564 return True
565 #--------------------------------------------------------
566 - def select_drugs(self, filename=None):
567 568 # better to clean up interactions file 569 open(self.interactions_filename, 'wb').close() 570 571 if not self.switch_to_frontend(blocking = True): 572 return None 573 574 return cGelbeListeCSVFile(filename = self.default_csv_filename)
575 #--------------------------------------------------------
576 - def import_drugs_as_substances(self):
577 578 selected_drugs = self.select_drugs() 579 if selected_drugs is None: 580 return None 581 582 new_substances = [] 583 584 for drug in selected_drugs: 585 atc = None # hopefully MMI eventually supports atc-per-substance in a drug... 586 if len(drug['wirkstoffe']) == 1: 587 atc = drug['atc'] 588 for wirkstoff in drug['wirkstoffe']: 589 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc)) 590 591 selected_drugs.close() 592 593 return new_substances
594 #--------------------------------------------------------
595 - def import_drugs(self):
596 597 selected_drugs = self.select_drugs() 598 if selected_drugs is None: 599 return None 600 601 data_src_pk = self.create_data_source_entry() 602 603 new_drugs = [] 604 new_substances = [] 605 606 for entry in selected_drugs: 607 608 _log.debug('importing drug: %s %s', entry['name'], entry['darreichungsform']) 609 610 if entry[u'hilfsmittel']: 611 _log.debug('skipping Hilfsmittel') 612 continue 613 614 if entry[u'erstattbares_medizinprodukt']: 615 _log.debug('skipping sonstiges Medizinprodukt') 616 continue 617 618 # create branded drug (or get it if it already exists) 619 drug = create_branded_drug(brand_name = entry['name'], preparation = entry['darreichungsform']) 620 if drug is None: 621 drug = get_drug_by_brand(brand_name = entry['name'], preparation = entry['darreichungsform']) 622 new_drugs.append(drug) 623 624 # update fields 625 drug['is_fake'] = False 626 drug['atc_code'] = entry['atc'] 627 drug['external_code_type'] = u'DE-PZN' 628 drug['external_code'] = entry['pzn'] 629 drug['fk_data_source'] = data_src_pk 630 drug.save() 631 632 # add components to brand 633 atc = None # hopefully MMI eventually supports atc-per-substance in a drug... 634 if len(entry['wirkstoffe']) == 1: 635 atc = entry['atc'] 636 for wirkstoff in entry['wirkstoffe']: 637 drug.add_component(substance = wirkstoff, atc = atc) 638 639 # create as consumable substances, too 640 atc = None # hopefully MMI eventually supports atc-per-substance in a drug... 641 if len(entry['wirkstoffe']) == 1: 642 atc = entry['atc'] 643 for wirkstoff in entry['wirkstoffe']: 644 new_substances.append(create_used_substance(substance = wirkstoff, atc = atc)) 645 646 return new_drugs, new_substances
647 #--------------------------------------------------------
648 - def check_drug_interactions(self, drug_ids_list=None, substances=None):
649 """For this to work the BDT interaction check must be configured in the MMI.""" 650 651 if drug_ids_list is None: 652 if substances is None: 653 return 654 if len(substances) < 2: 655 return 656 drug_ids_list = [ (s.external_code_type, s.external_code) for s in substances ] 657 drug_ids_list = [ code_value for code_type, code_value in drug_ids_list if (code_value is not None) and (code_type == u'DE-PZN')] 658 659 else: 660 if len(drug_ids_list) < 2: 661 return 662 663 if drug_ids_list < 2: 664 return 665 666 bdt_file = codecs.open(filename = self.interactions_filename, mode = 'wb', encoding = cGelbeListeWindowsInterface.default_encoding) 667 668 for pzn in drug_ids_list: 669 pzn = pzn.strip() 670 lng = cGelbeListeWindowsInterface.bdt_line_base_length + len(pzn) 671 bdt_file.write(cGelbeListeWindowsInterface.bdt_line_template % (lng, pzn)) 672 673 bdt_file.close() 674 675 self.switch_to_frontend(blocking = False)
676 #--------------------------------------------------------
677 - def show_info_on_substance(self, substance=None):
678 679 cmd = None 680 681 if substance.external_code_type == u'DE-PZN': 682 cmd = u'%s -PZN %s' % (self.path_to_binary, substance.external_code) 683 684 if cmd is None: 685 name = gmTools.coalesce ( 686 substance['brand'], 687 substance['substance'] 688 ) 689 cmd = u'%s -NAME %s' % (self.path_to_binary, name) 690 691 # better to clean up interactions file 692 open(self.interactions_filename, 'wb').close() 693 694 self.switch_to_frontend(cmd = cmd)
695 #============================================================
696 -class cGelbeListeWineInterface(cGelbeListeWindowsInterface):
697
698 - def __init__(self):
699 cGelbeListeWindowsInterface.__init__(self) 700 701 _log.info(u'%s (WINE extension)', cGelbeListeWindowsInterface.version) 702 703 # FIXME: if -CLOSETOTRAY is used GNUmed cannot detect the end of MMI 704 self.path_to_binary = r'wine "C:\Programme\MMI PHARMINDEX\glwin.exe"' 705 self.args = r'"-PRESCRIPTIONFILE %s -KEEPBACKGROUND"' 706 707 paths = gmTools.gmPaths() 708 709 self.default_csv_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'mmi2gm.csv') 710 self.default_csv_filename_arg = r'c:\windows\temp\mmi2gm.csv' 711 self.interactions_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'gm2mmi.bdt') 712 self.data_date_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'Programme', 'MMI PHARMINDEX', 'datadate.txt')
713 #============================================================
714 -class cIfapInterface(cDrugDataSourceInterface):
715 """empirical CSV interface""" 716
717 - def __init__(self):
718 pass
719
720 - def print_transfer_file(self, filename=None):
721 722 try: 723 csv_file = open(filename, 'rb') # FIXME: encoding ? 724 except: 725 _log.exception('cannot access [%s]', filename) 726 csv_file = None 727 728 field_names = u'PZN Handelsname Form Abpackungsmenge Einheit Preis1 Hersteller Preis2 rezeptpflichtig Festbetrag Packungszahl Packungsgr\xf6\xdfe'.split() 729 730 if csv_file is None: 731 return False 732 733 csv_lines = csv.DictReader ( 734 csv_file, 735 fieldnames = field_names, 736 delimiter = ';' 737 ) 738 739 for line in csv_lines: 740 print "--------------------------------------------------------------------"[:31] 741 for key in field_names: 742 tmp = ('%s ' % key)[:30] 743 print '%s: %s' % (tmp, line[key]) 744 745 csv_file.close()
746 747 # narr = u'%sx %s %s %s (\u2258 %s %s) von %s (%s)' % ( 748 # line['Packungszahl'].strip(), 749 # line['Handelsname'].strip(), 750 # line['Form'].strip(), 751 # line[u'Packungsgr\xf6\xdfe'].strip(), 752 # line['Abpackungsmenge'].strip(), 753 # line['Einheit'].strip(), 754 # line['Hersteller'].strip(), 755 # line['PZN'].strip() 756 # ) 757 #============================================================ 758 drug_data_source_interfaces = { 759 'Deutschland: Gelbe Liste/MMI (Windows)': cGelbeListeWindowsInterface, 760 'Deutschland: Gelbe Liste/MMI (WINE)': cGelbeListeWineInterface, 761 'FreeDiams (France, US, Canada)': cFreeDiamsInterface 762 } 763 #============================================================ 764 # substances in use across all patients 765 #------------------------------------------------------------
766 -def get_substances_in_use():
767 cmd = u'select * from clin.consumed_substance order by description' 768 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}]) 769 return rows
770 #------------------------------------------------------------
771 -def get_substance_by_pk(pk=None):
772 cmd = u'select * from clin.consumed_substance WHERE pk = %(pk)s' 773 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'pk': pk}}]) 774 if len(rows) == 0: 775 return None 776 return rows[0]
777 #------------------------------------------------------------
778 -def create_used_substance(substance=None, atc=None):
779 780 substance = substance.strip() 781 782 if atc is not None: 783 atc = atc.strip() 784 785 args = {'desc': substance, 'atc': atc} 786 787 cmd = u'select pk, atc_code, description from clin.consumed_substance where description = %(desc)s' 788 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 789 790 if len(rows) == 0: 791 cmd = u'insert into clin.consumed_substance (description, atc_code) values (%(desc)s, gm.nullify_empty_string(%(atc)s)) returning pk, atc_code, description' 792 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 793 794 gmATC.propagate_atc(substance = substance, atc = atc) 795 796 row = rows[0] 797 # unfortunately not a real dict so no setting stuff by keyword 798 #row['atc_code'] = args['atc'] 799 row[1] = args['atc'] 800 return row
801 #------------------------------------------------------------
802 -def delete_used_substance(substance=None):
803 args = {'pk': substance} 804 cmd = u""" 805 delete from clin.consumed_substance 806 where 807 pk = %(pk)s and not exists ( 808 select 1 from clin.substance_intake 809 where fk_substance = %(pk)s 810 )""" 811 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
812 #============================================================
813 -class cSubstanceIntakeEntry(gmBusinessDBObject.cBusinessDBObject):
814 """Represents a substance currently taken by a patient.""" 815 816 _cmd_fetch_payload = u"select * from clin.v_pat_substance_intake where pk_substance_intake = %s" 817 _cmds_store_payload = [ 818 u"""update clin.substance_intake set 819 clin_when = %(started)s, 820 discontinued = %(discontinued)s, 821 discontinue_reason = gm.nullify_empty_string(%(discontinue_reason)s), 822 strength = gm.nullify_empty_string(%(strength)s), 823 preparation = %(preparation)s, 824 schedule = gm.nullify_empty_string(%(schedule)s), 825 aim = gm.nullify_empty_string(%(aim)s), 826 narrative = gm.nullify_empty_string(%(notes)s), 827 intake_is_approved_of = %(intake_is_approved_of)s, 828 829 -- is_long_term = %(is_long_term)s, 830 is_long_term = ( 831 case 832 when ( 833 (%(is_long_term)s is False) 834 and 835 (%(duration)s is NULL) 836 ) is True then null 837 else %(is_long_term)s 838 end 839 )::boolean, 840 duration = ( 841 case 842 when %(is_long_term)s is True then null 843 else %(duration)s 844 end 845 )::interval, 846 847 fk_brand = %(pk_brand)s, 848 fk_substance = %(pk_substance)s, 849 fk_episode = %(pk_episode)s 850 where 851 pk = %(pk_substance_intake)s and 852 xmin = %(xmin_substance_intake)s 853 returning 854 xmin as xmin_substance_intake 855 """ 856 ] 857 _updatable_fields = [ 858 u'started', 859 u'discontinued', 860 u'discontinue_reason', 861 u'preparation', 862 u'strength', 863 u'intake_is_approved_of', 864 u'schedule', 865 u'duration', 866 u'aim', 867 u'is_long_term', 868 u'notes', 869 u'pk_brand', 870 u'pk_substance', 871 u'pk_episode' 872 ] 873 #--------------------------------------------------------
874 - def format(self, left_margin=0, date_format='%Y-%m-%d'):
875 876 if self._payload[self._idx['duration']] is None: 877 duration = gmTools.bool2subst ( 878 self._payload[self._idx['is_long_term']], 879 _('long-term'), 880 _('short-term'), 881 _('?short-term') 882 ) 883 else: 884 duration = gmDateTime.format_interval ( 885 self._payload[self._idx['duration']], 886 accuracy_wanted = gmDateTime.acc_days 887 ) 888 889 line = u'%s%s (%s %s): %s %s %s (%s)' % ( 890 u' ' * left_margin, 891 self._payload[self._idx['started']].strftime(date_format), 892 gmTools.u_right_arrow, 893 duration, 894 self._payload[self._idx['substance']], 895 gmTools.coalesce(self._payload[self._idx['strength']], u''), 896 self._payload[self._idx['preparation']], 897 gmTools.bool2subst(self._payload[self._idx['is_currently_active']], _('ongoing'), _('inactive'), _('?ongoing')) 898 ) 899 900 return line
901 #--------------------------------------------------------
902 - def turn_into_allergy(self, encounter_id=None, allergy_type='allergy'):
903 allg = gmAllergy.create_allergy ( 904 allergene = self._payload[self._idx['substance']], 905 allg_type = allergy_type, 906 episode_id = self._payload[self._idx['pk_episode']], 907 encounter_id = encounter_id 908 ) 909 allg['substance'] = gmTools.coalesce ( 910 self._payload[self._idx['brand']], 911 self._payload[self._idx['substance']] 912 ) 913 allg['reaction'] = self._payload[self._idx['discontinue_reason']] 914 allg['atc_code'] = gmTools.coalesce(self._payload[self._idx['atc_substance']], self._payload[self._idx['atc_brand']]) 915 if self._payload[self._idx['external_code_brand']] is not None: 916 allg['substance_code'] = u'%s::::%s' % (self._payload[self._idx['external_code_type_brand']], self._payload[self._idx['external_code_brand']]) 917 allg['allergene'] = self._payload[self._idx['substance']] 918 comps = [ c['description'] for c in self.containing_drug.components ] 919 if len(comps) == 0: 920 allg['generics'] = self._payload[self._idx['substance']] 921 else: 922 allg['generics'] = u'; '.join(comps) 923 924 allg.save() 925 return allg
926 #-------------------------------------------------------- 927 # properties 928 #--------------------------------------------------------
929 - def _get_ddd(self):
930 931 try: self.__ddd 932 except AttributeError: self.__ddd = None 933 934 if self.__ddd is not None: 935 return self.__ddd 936 937 if self._payload[self._idx['atc_substance']] is not None: 938 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_substance']]) 939 if len(ddd) != 0: 940 self.__ddd = ddd[0] 941 else: 942 if self._payload[self._idx['atc_brand']] is not None: 943 ddd = gmATC.atc2ddd(atc = self._payload[self._idx['atc_brand']]) 944 if len(ddd) != 0: 945 self.__ddd = ddd[0] 946 947 return self.__ddd
948 949 ddd = property(_get_ddd, lambda x:x) 950 #--------------------------------------------------------
951 - def _get_external_code(self):
952 drug = self.containing_drug 953 954 if drug is None: 955 return None 956 957 return drug.external_code
958 959 external_code = property(_get_external_code, lambda x:x) 960 #--------------------------------------------------------
961 - def _get_external_code_type(self):
962 drug = self.containing_drug 963 964 if drug is None: 965 return None 966 967 return drug.external_code_type
968 969 external_code_type = property(_get_external_code_type, lambda x:x) 970 #--------------------------------------------------------
971 - def _get_containing_drug(self):
972 if self._payload[self._idx['pk_brand']] is None: 973 return None 974 975 return cBrandedDrug(aPK_obj = self._payload[self._idx['pk_brand']])
976 977 containing_drug = property(_get_containing_drug, lambda x:x) 978 #--------------------------------------------------------
979 - def _get_parsed_schedule(self):
980 tests = [ 981 # lead, trail 982 ' 1-1-1-1 ', 983 # leading dose 984 '1-1-1-1', 985 '22-1-1-1', 986 '1/3-1-1-1', 987 '/4-1-1-1' 988 ] 989 pattern = "^(\d\d|/\d|\d/\d|\d)[\s-]{1,5}\d{0,2}[\s-]{1,5}\d{0,2}[\s-]{1,5}\d{0,2}$" 990 for test in tests: 991 print test.strip(), ":", regex.match(pattern, test.strip())
992 #------------------------------------------------------------
993 -def create_substance_intake(substance=None, atc=None, encounter=None, episode=None, preparation=None):
994 995 args = { 996 'enc': encounter, 997 'epi': episode, 998 'prep': preparation, 999 'subst': create_used_substance(substance = substance, atc = atc)['pk'] 1000 } 1001 1002 cmd = u""" 1003 insert into clin.substance_intake ( 1004 fk_encounter, 1005 fk_episode, 1006 fk_substance, 1007 preparation, 1008 intake_is_approved_of 1009 ) values ( 1010 %(enc)s, 1011 %(epi)s, 1012 %(subst)s, 1013 gm.nullify_empty_string(%(prep)s), 1014 False 1015 ) 1016 returning pk 1017 """ 1018 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 1019 return cSubstanceIntakeEntry(aPK_obj = rows[0][0])
1020 #------------------------------------------------------------
1021 -def delete_substance_intake(substance=None):
1022 cmd = u'delete from clin.substance_intake where pk = %(pk)s' 1023 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': substance}}])
1024 #------------------------------------------------------------
1025 -def format_substance_intake_notes(emr=None, output_format=u'latex', table_type=u'by-brand'):
1026 1027 tex = u'\n{\\small\n' 1028 tex += u'\\noindent %s\n' % _('Additional notes') 1029 tex += u'\n' 1030 tex += u'\\noindent \\begin{tabular}{|l|l|l|l|}\n' 1031 tex += u'\\hline\n' 1032 tex += u'%s & %s & %s & \\\\ \n' % (_('Substance'), _('Strength'), _('Brand')) 1033 tex += u'\\hline\n' 1034 tex += u'%s\n' 1035 tex += u'\n' 1036 tex += u'\\end{tabular}\n' 1037 tex += u'}\n' 1038 1039 current_meds = emr.get_current_substance_intake ( 1040 include_inactive = False, 1041 include_unapproved = False, 1042 order_by = u'brand, substance' 1043 ) 1044 1045 # create lines 1046 lines = [] 1047 for med in current_meds: 1048 1049 lines.append(u'%s & %s & %s %s & {\\scriptsize %s} \\\\ \n \\hline \n' % ( 1050 med['substance'], 1051 gmTools.coalesce(med['strength'], u''), 1052 gmTools.coalesce(med['brand'], u''), 1053 med['preparation'], 1054 gmTools.coalesce(med['notes'], u'') 1055 )) 1056 1057 return tex % u' \n'.join(lines)
1058 1059 #------------------------------------------------------------
1060 -def format_substance_intake(emr=None, output_format=u'latex', table_type=u'by-brand'):
1061 1062 tex = u'\\noindent %s {\\tiny (%s)\\par}\n' % (_('Medication list'), _('ordered by brand')) 1063 tex += u'\n' 1064 tex += u'\\noindent \\begin{tabular}{|l|l|}\n' 1065 tex += u'\\hline\n' 1066 tex += u'%s & %s \\\\ \n' % (_('Drug'), _('Regimen')) 1067 tex += u'\\hline\n' 1068 tex += u'\n' 1069 tex += u'\\hline\n' 1070 tex += u'%s\n' 1071 tex += u'\n' 1072 tex += u'\\end{tabular}\n' 1073 1074 current_meds = emr.get_current_substance_intake ( 1075 include_inactive = False, 1076 include_unapproved = False, 1077 order_by = u'brand, substance' 1078 ) 1079 1080 # aggregate data 1081 line_data = {} 1082 for med in current_meds: 1083 identifier = gmTools.coalesce(med['brand'], med['substance']) 1084 1085 try: 1086 line_data[identifier] 1087 except KeyError: 1088 line_data[identifier] = {'brand': u'', 'preparation': u'', 'schedule': u'', 'aims': [], 'strengths': []} 1089 1090 line_data[identifier]['brand'] = identifier 1091 if med['strength'] is not None: 1092 line_data[identifier]['strengths'].append(med['strength'].strip()) 1093 line_data[identifier]['preparation'] = med['preparation'] 1094 line_data[identifier]['schedule'] = gmTools.coalesce(med['schedule'], u'') 1095 if med['aim'] not in line_data[identifier]['aims']: 1096 line_data[identifier]['aims'].append(med['aim']) 1097 1098 # create lines 1099 already_seen = [] 1100 lines = [] 1101 line1_template = u'%s %s & %s \\\\' 1102 line2_template = u' & {\\scriptsize %s\\par} \\\\' 1103 1104 for med in current_meds: 1105 identifier = gmTools.coalesce(med['brand'], med['substance']) 1106 1107 if identifier in already_seen: 1108 continue 1109 1110 already_seen.append(identifier) 1111 1112 lines.append (line1_template % ( 1113 line_data[identifier]['brand'], 1114 line_data[identifier]['preparation'], 1115 line_data[identifier]['schedule'] 1116 )) 1117 1118 strengths = u'/'.join(line_data[identifier]['strengths']) 1119 if strengths == u'': 1120 template = u' & {\\scriptsize %s\\par} \\\\' 1121 for aim in line_data[identifier]['aims']: 1122 lines.append(template % aim) 1123 else: 1124 if len(line_data[identifier]['aims']) == 0: 1125 template = u'%s & \\\\' 1126 lines.append(template % strengths) 1127 else: 1128 template = u'%s & {\\scriptsize %s\\par} \\\\' 1129 lines.append(template % (strengths, line_data[identifier]['aims'][0])) 1130 template = u' & {\\scriptsize %s\\par} \\\\' 1131 for aim in line_data[identifier]['aims'][1:]: 1132 lines.append(template % aim) 1133 1134 lines.append(u'\\hline') 1135 1136 return tex % u' \n'.join(lines)
1137 #============================================================
1138 -class cBrandedDrug(gmBusinessDBObject.cBusinessDBObject):
1139 """Represents a drug as marketed by a manufacturer.""" 1140 1141 _cmd_fetch_payload = u"select *, xmin from ref.branded_drug where pk = %s" 1142 _cmds_store_payload = [ 1143 u"""update ref.branded_drug set 1144 description = %(description)s, 1145 preparation = %(preparation)s, 1146 atc_code = gm.nullify_empty_string(%(atc_code)s), 1147 external_code = gm.nullify_empty_string(%(external_code)s), 1148 external_code_type = gm.nullify_empty_string(%(external_code_type)s), 1149 is_fake = %(is_fake)s, 1150 fk_data_source = %(fk_data_source)s 1151 where 1152 pk = %(pk)s and 1153 xmin = %(xmin)s 1154 returning 1155 xmin 1156 """ 1157 ] 1158 _updatable_fields = [ 1159 u'description', 1160 u'preparation', 1161 u'atc_code', 1162 u'is_fake', 1163 u'external_code', 1164 u'external_code_type', 1165 u'fk_data_source' 1166 ] 1167 #--------------------------------------------------------
1168 - def _get_external_code(self):
1169 if self._payload[self._idx['external_code']] is None: 1170 return None 1171 1172 return self._payload[self._idx['external_code']]
1173 1174 external_code = property(_get_external_code, lambda x:x) 1175 #--------------------------------------------------------
1176 - def _get_external_code_type(self):
1177 1178 # FIXME: maybe evaluate fk_data_source ? 1179 if self._payload[self._idx['external_code_type']] is None: 1180 return None 1181 1182 return self._payload[self._idx['external_code_type']]
1183 1184 external_code_type = property(_get_external_code_type, lambda x:x) 1185 #--------------------------------------------------------
1186 - def _get_components(self):
1187 cmd = u'select * from ref.substance_in_brand where fk_brand = %(brand)s' 1188 args = {'brand': self._payload[self._idx['pk']]} 1189 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False) 1190 return rows
1191 1192 components = property(_get_components, lambda x:x) 1193 #--------------------------------------------------------
1194 - def _get_is_vaccine(self):
1195 cmd = u'SELECT EXISTS (SELECT 1 FROM clin.vaccine WHERE fk_brand = %(fk_brand)s)' 1196 args = {'fk_brand': self._payload[self._idx['pk']]} 1197 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False) 1198 return rows[0][0]
1199 1200 is_vaccine = property(_get_is_vaccine, lambda x:x) 1201 #--------------------------------------------------------
1202 - def add_component(self, substance=None, atc=None):
1203 1204 # normalize atc 1205 atc = gmATC.propagate_atc(substance = substance, atc = atc) 1206 1207 args = { 1208 'brand': self.pk_obj, 1209 'desc': substance, 1210 'atc': atc 1211 } 1212 1213 # already exists ? 1214 cmd = u""" 1215 SELECT pk 1216 FROM ref.substance_in_brand 1217 WHERE 1218 fk_brand = %(brand)s 1219 AND 1220 ((description = %(desc)s) OR ((atc_code = %(atc)s) IS TRUE)) 1221 """ 1222 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False) 1223 if len(rows) > 0: 1224 return 1225 1226 # create it 1227 cmd = u""" 1228 INSERT INTO ref.substance_in_brand (fk_brand, description, atc_code) 1229 VALUES (%(brand)s, %(desc)s, %(atc)s) 1230 """ 1231 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
1232 #------------------------------------------------------------
1233 - def remove_component(substance=None):
1234 delete_component_from_branded_drug(brand = self.pk_obj, component = substance)
1235 #------------------------------------------------------------
1236 -def get_substances_in_brands():
1237 cmd = u'SELECT * FROM ref.v_substance_in_brand ORDER BY brand, substance' 1238 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False) 1239 return rows
1240 #------------------------------------------------------------
1241 -def get_branded_drugs():
1242 1243 cmd = u'SELECT pk FROM ref.branded_drug ORDER BY description' 1244 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False) 1245 1246 return [ cBrandedDrug(aPK_obj = r['pk']) for r in rows ]
1247 #------------------------------------------------------------
1248 -def get_drug_by_brand(brand_name=None, preparation=None):
1249 args = {'brand': brand_name, 'prep': preparation} 1250 1251 cmd = u'SELECT pk FROM ref.branded_drug WHERE description = %(brand)s AND preparation = %(prep)s' 1252 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False) 1253 1254 if len(rows) == 0: 1255 return None 1256 1257 return cBrandedDrug(aPK_obj = rows[0]['pk'])
1258 #------------------------------------------------------------
1259 -def create_branded_drug(brand_name=None, preparation=None, return_existing=False):
1260 1261 if preparation is None: 1262 preparation = _('units') 1263 1264 if preparation.strip() == u'': 1265 preparation = _('units') 1266 1267 drug = get_drug_by_brand(brand_name = brand_name, preparation = preparation) 1268 1269 if drug is not None: 1270 if return_existing: 1271 return drug 1272 return None 1273 1274 cmd = u'insert into ref.branded_drug (description, preparation) values (%(brand)s, %(prep)s) returning pk' 1275 args = {'brand': brand_name, 'prep': preparation} 1276 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False) 1277 1278 return cBrandedDrug(aPK_obj = rows[0]['pk'])
1279 #------------------------------------------------------------
1280 -def delete_branded_drug(brand=None):
1281 cmd = u'delete from ref.branded_drug where pk = %(pk)s' 1282 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'pk': brand}}])
1283 #------------------------------------------------------------
1284 -def delete_component_from_branded_drug(brand=None, component=None):
1285 cmd = u'delete from ref.substance_in_brand where fk_brand = %(brand)s and pk = %(comp)s' 1286 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': {'brand': brand, 'comp': component}}])
1287 #============================================================ 1288 # main 1289 #------------------------------------------------------------ 1290 if __name__ == "__main__": 1291 1292 if len(sys.argv) < 2: 1293 sys.exit() 1294 1295 if sys.argv[1] != 'test': 1296 sys.exit() 1297 1298 from Gnumed.pycommon import gmLog2 1299 from Gnumed.pycommon import gmI18N 1300 from Gnumed.business import gmPerson 1301 1302 gmI18N.activate_locale() 1303 # gmDateTime.init() 1304 #--------------------------------------------------------
1305 - def test_MMI_interface():
1306 mmi = cGelbeListeWineInterface() 1307 print mmi 1308 print "interface definition:", mmi.version 1309 print "database versions: ", mmi.get_data_source_version()
1310 #--------------------------------------------------------
1311 - def test_MMI_file():
1312 mmi_file = cGelbeListeCSVFile(filename = sys.argv[2]) 1313 for drug in mmi_file: 1314 print "-------------" 1315 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn']) 1316 for stoff in drug['wirkstoffe']: 1317 print " Wirkstoff:", stoff 1318 print drug 1319 mmi_file.close()
1320 #--------------------------------------------------------
1321 - def test_mmi_switch_to():
1322 mmi = cGelbeListeWineInterface() 1323 mmi.switch_to_frontend(blocking = False)
1324 #--------------------------------------------------------
1325 - def test_mmi_select_drugs():
1326 mmi = cGelbeListeWineInterface() 1327 mmi_file = mmi.select_drugs() 1328 for drug in mmi_file: 1329 print "-------------" 1330 print '"%s" (ATC: %s / PZN: %s)' % (drug['name'], drug['atc'], drug['pzn']) 1331 for stoff in drug['wirkstoffe']: 1332 print " Wirkstoff:", stoff 1333 print drug 1334 mmi_file.close()
1335 #--------------------------------------------------------
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_drug_interactions(drug_ids_list = [diclofenac, phenprocoumon])
1348 #-------------------------------------------------------- 1349 # FreeDiams 1350 #--------------------------------------------------------
1351 - def test_fd_switch_to():
1352 gmPerson.set_active_patient(patient = gmPerson.cIdentity(aPK_obj = 12)) 1353 fd = cFreeDiamsInterface() 1354 fd.patient = gmPerson.gmCurrentPatient() 1355 fd.switch_to_frontend(blocking = True) 1356 fd.import_fd2gm_file()
1357 #-------------------------------------------------------- 1358 # generic 1359 #--------------------------------------------------------
1360 - def test_create_substance_intake():
1361 drug = create_substance_intake ( 1362 substance = u'Whiskey', 1363 atc = u'no ATC available', 1364 encounter = 1, 1365 episode = 1, 1366 preparation = 'a nice glass' 1367 ) 1368 print drug
1369 #--------------------------------------------------------
1370 - def test_show_components():
1371 drug = cBrandedDrug(aPK_obj = sys.argv[2]) 1372 print drug 1373 print drug.components
1374 #-------------------------------------------------------- 1375 #test_MMI_interface() 1376 #test_MMI_file() 1377 #test_mmi_switch_to() 1378 #test_mmi_select_drugs() 1379 #test_mmi_import_substances() 1380 #test_mmi_import_drugs() 1381 test_fd_switch_to() 1382 #test_interaction_check() 1383 #test_create_substance_intake() 1384 #test_show_components() 1385 #============================================================ 1386