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