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

Source Code for Module Gnumed.business.gmVaccination

  1  """GNUmed vaccination related business objects. 
  2  """ 
  3  #============================================================ 
  4  __version__ = "$Revision: 1.38 $" 
  5  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>" 
  6  __license__ = "GPL" 
  7   
  8  import sys, copy, logging 
  9   
 10   
 11  if __name__ == '__main__': 
 12          sys.path.insert(0, '../../') 
 13  #       from Gnumed.pycommon import             #, gmDateTime, gmLog2 
 14  #       gmDateTime.init() 
 15  #       gmI18N.activate_locale() 
 16  from Gnumed.pycommon import gmBusinessDBObject, gmPG2, gmI18N, gmTools 
 17  from Gnumed.business import gmMedication 
 18   
 19   
 20  _log = logging.getLogger('gm.vaccination') 
 21  _log.info(__version__) 
 22   
 23  #============================================================ 
24 -def get_indications(order_by=None):
25 cmd = u'SELECT * from clin.vacc_indication' 26 27 if order_by is not None: 28 cmd = u'%s ORDER BY %s' % (cmd, order_by) 29 30 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False) 31 32 return rows
33 #============================================================ 34 _sql_fetch_vaccine = u"""SELECT *, xmin_vaccine FROM clin.v_vaccines WHERE %s""" 35
36 -class cVaccine(gmBusinessDBObject.cBusinessDBObject):
37 """Represents one vaccine.""" 38 39 _cmd_fetch_payload = _sql_fetch_vaccine % u"pk_vaccine = %s" 40 41 _cmds_store_payload = [ 42 u"""UPDATE clin.vaccine SET 43 id_route = %(pk_route)s, 44 is_live = %(is_live)s, 45 min_age = %(min_age)s, 46 max_age = %(max_age)s, 47 comment = gm.nullify_empty_string(%(comment)s), 48 fk_brand = %(pk_brand)s 49 WHERE 50 pk = %(pk_vaccine)s 51 AND 52 xmin = %(xmin_vaccine)s 53 RETURNING 54 xmin as xmin_vaccine 55 """ 56 ] 57 58 _updatable_fields = [ 59 u'pk_route', 60 u'is_live', 61 u'min_age', 62 u'max_age', 63 u'comment', 64 u'pk_brand' 65 ] 66 #--------------------------------------------------------
67 - def set_indications(self, indications=None, pk_indications=None):
68 queries = [{ 69 'cmd': u'DELETE FROM clin.lnk_vaccine2inds WHERE fk_vaccine = %(pk_vacc)s', 70 'args': {'pk_vacc': self._payload[self._idx['pk_vaccine']]} 71 }] 72 73 if pk_indications is None: 74 if set(self._payload[self._idx['indications']]) == set(indications): 75 return 76 77 for ind in indications: 78 queries.append ({ 79 'cmd': u""" 80 INSERT INTO clin.lnk_vaccine2inds ( 81 fk_vaccine, 82 fk_indication 83 ) VALUES ( 84 %(pk_vacc)s, 85 (SELECT id FROM clin.vacc_indication WHERE description = %(ind)s) 86 )""", 87 'args': {'pk_vacc': self._payload[self._idx['pk_vaccine']], 'ind': ind} 88 }) 89 else: 90 if set(self._payload[self._idx['pk_indications']]) == set(pk_indications): 91 return 92 93 for pk_ind in pk_indications: 94 queries.append ({ 95 'cmd': u""" 96 INSERT INTO clin.lnk_vaccine2inds ( 97 fk_vaccine, 98 fk_indication 99 ) VALUES ( 100 %(pk_vacc)s, 101 %(pk_ind)s 102 )""", 103 'args': {'pk_vacc': self._payload[self._idx['pk_vaccine']], 'pk_ind': pk_ind} 104 }) 105 106 gmPG2.run_rw_queries(queries = queries) 107 self.refetch_payload()
108 #-------------------------------------------------------- 109 # properties 110 #--------------------------------------------------------
111 - def _get_brand(self):
112 return gmMedication.cBrandedDrug(aPK_obj = self._payload[self._idx['pk_brand']])
113 114 brand = property(_get_brand, lambda x:x) 115 #--------------------------------------------------------
116 - def _get_is_in_use(self):
117 cmd = u'SELECT EXISTS(SELECT 1 FROM clin.vaccination WHERE fk_vaccine = %(pk)s)' 118 args = {'pk': self._payload[self._idx['pk_vaccine']]} 119 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False) 120 return rows[0][0]
121 122 is_in_use = property(_get_is_in_use, lambda x:x)
123 #------------------------------------------------------------
124 -def create_vaccine(pk_brand=None, brand_name=None, indications=None):
125 126 if pk_brand is None: 127 prep = _('vaccine') 128 _log.debug('creating branded drug [%s %s]', brand_name, prep) 129 drug = gmMedication.create_branded_drug ( 130 brand_name = brand_name, 131 preparation = prep, 132 return_existing = True 133 ) 134 drug['atc_code'] = u'J07' 135 drug.save() 136 pk_brand = drug['pk'] 137 138 cmd = u'INSERT INTO clin.vaccine (fk_brand) values (%(pk_brand)s) RETURNING pk' 139 queries = [{'cmd': cmd, 'args': {'pk_brand': pk_brand}}] 140 141 for indication in indications: 142 cmd = u""" 143 INSERT INTO clin.lnk_vaccine2inds ( 144 fk_vaccine, 145 fk_indication 146 ) VALUES ( 147 currval(pg_get_serial_sequence('clin.vaccine', 'pk')), 148 (SELECT id 149 FROM clin.vacc_indication 150 WHERE 151 lower(description) = lower(%(ind)s) 152 LIMIT 1 153 ) 154 ) 155 RETURNING fk_vaccine 156 """ 157 queries.append({'cmd': cmd, 'args': {'ind': indication}}) 158 159 rows, idx = gmPG2.run_rw_queries(queries = queries, get_col_idx = False, return_data = True) 160 161 return cVaccine(aPK_obj = rows[0]['fk_vaccine'])
162 #------------------------------------------------------------
163 -def delete_vaccine(vaccine=None):
164 165 cmd = u'DELETE FROM clin.vaccine WHERE pk = %(pk)s' 166 args = {'pk': vaccine} 167 168 try: 169 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 170 except gmPG2.dbapi.IntegrityError: 171 _log.exception('cannot delete vaccine [%s]', vaccine) 172 return False 173 174 return True
175 #------------------------------------------------------------
176 -def get_vaccines(order_by=None):
177 178 if order_by is None: 179 cmd = _sql_fetch_vaccine % u'TRUE' 180 else: 181 cmd = _sql_fetch_vaccine % (u'TRUE\nORDER BY %s' % order_by) 182 183 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 184 185 return [ cVaccine(row = {'data': r, 'idx': idx, 'pk_field': 'pk_vaccine'}) for r in rows ]
186 #------------------------------------------------------------
187 -def map_indications2generic_vaccine(indications=None):
188 189 args = {'inds': indications} 190 cmd = _sql_fetch_vaccine % (u'is_fake_vaccine is True AND indications @> %(inds)s AND %(inds)s @> indications') 191 192 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 193 194 if len(rows) == 0: 195 _log.warning('no fake, generic vaccine found for [%s]', indications) 196 return None 197 198 return cVaccine(row = {'data': rows[0], 'idx': idx, 'pk_field': 'pk_vaccine'})
199 #------------------------------------------------------------
200 -def regenerate_generic_vaccines():
201 202 cmd = u'select gm.create_generic_monovalent_vaccines()' 203 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd}], return_data = True) 204 205 cmd = u'select gm.create_generic_combi_vaccines()' 206 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd}], return_data = True) 207 208 return rows[0][0]
209 #============================================================ 210 # vaccination related classes 211 #============================================================ 212 sql_fetch_vaccination = u"""SELECT * FROM clin.v_pat_vaccinations WHERE %s""" 213
214 -class cVaccination(gmBusinessDBObject.cBusinessDBObject):
215 216 _cmd_fetch_payload = sql_fetch_vaccination % u"pk_vaccination = %s" 217 218 _cmds_store_payload = [ 219 u"""UPDATE clin.vaccination SET 220 soap_cat = %(soap_cat)s, 221 clin_when = %(date_given)s, 222 site = gm.nullify_empty_string(%(site)s), 223 batch_no = gm.nullify_empty_string(%(batch_no)s), 224 reaction = gm.nullify_empty_string(%(reaction)s), 225 narrative = gm.nullify_empty_string(%(comment)s), 226 fk_vaccine = %(pk_vaccine)s, 227 fk_provider = %(pk_provider)s, 228 fk_encounter = %(pk_encounter)s, 229 fk_episode = %(pk_episode)s 230 WHERE 231 pk = %(pk_vaccination)s 232 AND 233 xmin = %(xmin_vaccination)s 234 RETURNING 235 xmin as xmin_vaccination 236 """ 237 ] 238 239 _updatable_fields = [ 240 u'soap_cat', 241 u'date_given', 242 u'site', 243 u'batch_no', 244 u'reaction', 245 u'comment', 246 u'pk_vaccine', 247 u'pk_provider', 248 u'pk_encounter', 249 u'pk_episode' 250 ] 251 #--------------------------------------------------------
252 - def format(self, with_indications=False, with_comment=False, with_reaction=False, date_format='%Y-%m-%d'):
253 254 lines = [] 255 256 lines.append (u' %s: %s [%s]%s' % ( 257 self._payload[self._idx['date_given']].strftime(date_format).decode(gmI18N.get_encoding()), 258 self._payload[self._idx['vaccine']], 259 self._payload[self._idx['batch_no']], 260 gmTools.coalesce(self._payload[self._idx['site']], u'', u' (%s)') 261 )) 262 263 if with_comment: 264 if self._payload[self._idx['comment']] is not None: 265 lines.append(u' %s' % self._payload[self._idx['comment']]) 266 267 if with_reaction: 268 if self._payload[self._idx['reaction']] is not None: 269 lines.append(u' %s' % self._payload[self._idx['reaction']]) 270 271 if with_indications: 272 lines.append(u' %s' % u' / '.join(self._payload[self._idx['indications']])) 273 274 return lines
275 #------------------------------------------------------------
276 -def create_vaccination(encounter=None, episode=None, vaccine=None, batch_no=None):
277 278 cmd = u""" 279 INSERT INTO clin.vaccination ( 280 fk_encounter, 281 fk_episode, 282 fk_vaccine, 283 batch_no 284 ) VALUES ( 285 %(enc)s, 286 %(epi)s, 287 %(vacc)s, 288 %(batch)s 289 ) RETURNING pk; 290 """ 291 args = { 292 u'enc': encounter, 293 u'epi': episode, 294 u'vacc': vaccine, 295 u'batch': batch_no 296 } 297 298 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False, return_data = True) 299 300 return cVaccination(aPK_obj = rows[0][0])
301 302 #------------------------------------------------------------ 303
304 -def delete_vaccination(vaccination=None):
305 cmd = u"""DELETE FROM clin.vaccination WHERE pk = %(pk)s""" 306 args = {'pk': vaccination} 307 308 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
309 310 #------------------------------------------------------------ 311
312 -def format_latest_vaccinations(output_format=u'latex', emr=None):
313 314 _log.debug(u'formatting latest vaccinations into [%s]', output_format) 315 316 vaccs = emr.get_latest_vaccinations() 317 318 if output_format == u'latex': 319 return __format_latest_vaccinations_latex(vaccinations = vaccs) 320 321 msg = _('unknown vaccinations output format [%s]') % output_format 322 _log.error(msg) 323 return msg
324 325 #------------------------------------------------------------ 326
327 -def __format_latest_vaccinations_latex(vaccinations=None):
328 329 if len(vaccinations) == 0: 330 return u'\\noindent %s' % _('No vaccinations to format.') 331 332 tex = u'\\noindent %s {\\tiny (%s)\\par}\n' % (_('Latest vaccinations'), _('per target condition')) 333 tex += u'\n' 334 tex += u'\\noindent \\begin{tabular}{|l|l|l|l|l|l|}\n' 335 tex += u'\\hline\n' 336 tex += u'%s & %s & {\\footnotesize %s} & {\\footnotesize %s} & {\\footnotesize %s\\footnotemark} & {\\footnotesize %s\\footnotemark} \\\\ \n' % ( 337 _('Target'), 338 _('Last given'), 339 _('Vaccine'), 340 _('Lot \#'), 341 _('S/P'), 342 gmTools.u_sum 343 ) 344 tex += u'\\hline\n' 345 tex += u'\n' 346 tex += u'\\hline\n' 347 tex += u'%s' 348 tex += u'\n' 349 tex += u'\\end{tabular}\n' 350 tex += u'\n' 351 tex += u'\\addtocounter{footnote}{-1} \n' 352 tex += u'\\footnotetext{%s} \n' % _('S/P -- "S"ubjective: this vaccination was remembered by the patient. "P"lan: this vaccination was administered in the practice or copied from trustworthy records.') 353 tex += u'\\addtocounter{footnote}{1} \n' 354 tex += u'\\footnotetext{%s -- %s} \n' % (gmTools.u_sum, _('Total number of vaccinations recorded for the corresponding target condition.')) 355 tex += u'\n' 356 357 row_template = u'%s & %s & {\\scriptsize %s} & {\\scriptsize %s} & {\\scriptsize %s} & {\\scriptsize %s} \\\\ \n' 358 lines = u'' 359 targets = sorted(vaccinations.keys()) 360 for target in targets: 361 target_count, vacc = vaccinations[target] 362 lines += row_template % ( 363 target, 364 vacc['date_given'].strftime('%Y %b %d').decode(gmI18N.get_encoding()), 365 vacc['vaccine'], 366 gmTools.tex_escape_string(vacc['batch_no'].strip()), 367 vacc['soap_cat'].upper(), 368 target_count 369 ) 370 if vacc['site'] is not None: 371 lines += u' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par} \\\\ \n' % (_('Injection site'), vacc['site'].strip()) 372 if vacc['reaction'] is not None: 373 lines += u' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par} \\\\ \n' % (_('Reaction'), vacc['reaction'].strip()) 374 if vacc['comment'] is not None: 375 lines += u' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par} \\\\ \n' % (_('Comment'), vacc['comment'].strip()) 376 lines += u'\\hline \n' 377 378 return tex % lines
379 380 #============================================================ 381 #============================================================ 382 #============================================================ 383 # old code 384 #============================================================
385 -class cMissingVaccination(gmBusinessDBObject.cBusinessDBObject):
386 """Represents one missing vaccination. 387 388 - can be due or overdue 389 """ 390 _cmd_fetch_payload = """ 391 (select *, False as overdue 392 from clin.v_pat_missing_vaccs vpmv 393 where 394 pk_patient=%(pat_id)s 395 and 396 (select dob from dem.identity where pk=%(pat_id)s) between (now() - age_due_min) and (now() - coalesce(age_due_max, '115 years'::interval)) 397 and 398 indication=%(indication)s 399 and 400 seq_no=%(seq_no)s 401 order by time_left) 402 403 UNION 404 405 (select *, True as overdue 406 from clin.v_pat_missing_vaccs vpmv 407 where 408 pk_patient=%(pat_id)s 409 and 410 now() - ((select dob from dem.identity where pk=%(pat_id)s)) > coalesce(age_due_max, '115 years'::interval) 411 and 412 indication=%(indication)s 413 and 414 seq_no=%(seq_no)s 415 order by amount_overdue)""" 416 _cmds_lock_rows_for_update = [] 417 _cmds_store_payload = ["""select 1"""] 418 _updatable_fields = [] 419 #--------------------------------------------------------
420 - def is_overdue(self):
421 return self['overdue']
422 #--------------------------------------------------------
423 - def create_vaccination(self):
424 # FIXME: create vaccination from myself, 425 # either pass in episode/encounter/vaccine id or use default for 426 # episode/encounter or use curr_pat.* if pk_patient=curr_pat, 427 # should we auto-destroy after create_vaccination() ? 428 return (False, 'not implemented')
429 #============================================================
430 -class cMissingBooster(gmBusinessDBObject.cBusinessDBObject):
431 """Represents one due booster. 432 """ 433 _cmd_fetch_payload = """ 434 select *, now() - amount_overdue as latest_due 435 from clin.v_pat_missing_boosters vpmb 436 where 437 pk_patient=%(pat_id)s 438 and 439 indication=%(indication)s 440 order by amount_overdue""" 441 _cmds_lock_rows_for_update = [] 442 _cmds_store_payload = ["""select 1"""] 443 _updatable_fields = []
444 #============================================================
445 -class cScheduledVaccination(gmBusinessDBObject.cBusinessDBObject):
446 """Represents one vaccination scheduled following a course. 447 """ 448 _cmd_fetch_payload = u"select * from clin.v_vaccs_scheduled4pat where pk_vacc_def=%s" 449 _cmds_lock_rows_for_update = [] 450 _cmds_store_payload = ["""select 1"""] 451 _updatable_fields = []
452 #============================================================
453 -class cVaccinationCourse(gmBusinessDBObject.cBusinessDBObject):
454 """Represents one vaccination course. 455 """ 456 _cmd_fetch_payload = """ 457 select *, xmin_vaccination_course from clin.v_vaccination_courses 458 where pk_course=%s""" 459 _cmds_lock_rows_for_update = [ 460 """select 1 from clin.vaccination_course where id=%(pk_course)s and xmin=%(xmin_vaccination_course)s for update""" 461 ] 462 _cmds_store_payload = [ 463 """update clin.vaccination_course set 464 name=%(course)s, 465 fk_recommended_by=%(pk_recommended_by)s, 466 fk_indication=(select id from clin.vacc_indication where description=%(indication)s), 467 comment=%(comment)s 468 where id=%(pk_course)s""", 469 """select xmin_vaccination_course from clin.v_vaccination_courses where pk_course=%(pk_course)s""" 470 ] 471 _updatable_fields = [ 472 'course', 473 'pk_recommended_by', 474 'indication', 475 'comment' 476 ]
477 #============================================================ 478 #============================================================ 479 # convenience functions 480 #------------------------------------------------------------
481 -def create_vaccination_old(patient_id=None, episode_id=None, encounter_id=None, staff_id = None, vaccine=None):
482 # sanity check 483 # 1) any of the args being None should fail the SQL code 484 # 2) do episode/encounter belong to the patient ? 485 cmd = """ 486 select pk_patient 487 from clin.v_pat_episodes 488 where pk_episode=%s 489 union 490 select pk_patient 491 from clin.v_pat_encounters 492 where pk_encounter=%s""" 493 rows = gmPG.run_ro_query('historica', cmd, None, episode_id, encounter_id) 494 if (rows is None) or (len(rows) == 0): 495 _log.error('error checking episode [%s] <-> encounter [%s] consistency' % (episode_id, encounter_id)) 496 return (False, _('internal error, check log')) 497 if len(rows) > 1: 498 _log.error('episode [%s] and encounter [%s] belong to more than one patient !?!' % (episode_id, encounter_id)) 499 return (False, _('consistency error, check log')) 500 # insert new vaccination 501 queries = [] 502 if type(vaccine) == types.IntType: 503 cmd = """insert into clin.vaccination (fk_encounter, fk_episode, fk_patient, fk_provider, fk_vaccine) 504 values (%s, %s, %s, %s, %s)""" 505 else: 506 cmd = """insert into clin.vaccination (fk_encounter, fk_episode, fk_patient, fk_provider, fk_vaccine) 507 values (%s, %s, %s, %s, (select pk from clin.vaccine where trade_name=%s))""" 508 vaccine = str(vaccine) 509 queries.append((cmd, [encounter_id, episode_id, patient_id, staff_id, vaccine])) 510 # get PK of inserted row 511 cmd = "select currval('clin.vaccination_id_seq')" 512 queries.append((cmd, [])) 513 result, msg = gmPG.run_commit('historica', queries, True) 514 if (result is None) or (len(result) == 0): 515 return (False, msg) 516 try: 517 vacc = cVaccination(aPK_obj = result[0][0]) 518 except gmExceptions.ConstructorError: 519 _log.exception('cannot instantiate vaccination' % (result[0][0]), sys.exc_info, verbose=0) 520 return (False, _('internal error, check log')) 521 522 return (True, vacc)
523 #--------------------------------------------------------
524 -def get_vacc_courses():
525 # FIXME: use cVaccinationCourse 526 cmd = 'select name from clin.vaccination_course' 527 rows = gmPG.run_ro_query('historica', cmd) 528 if rows is None: 529 return None 530 if len(rows) == 0: 531 return [] 532 data = [] 533 for row in rows: 534 data.extend(rows) 535 return data
536 #--------------------------------------------------------
537 -def get_vacc_regimes_by_recommender_ordered(pk_patient=None, clear_cache=False):
538 # check DbC, if it fails exception is due 539 int(pk_patient) 540 541 cmd = """ 542 select fk_regime 543 from clin.lnk_pat2vacc_reg l 544 where l.fk_patient = %s""" % pk_patient 545 546 rows = gmPG.run_ro_query('historica', cmd) 547 active = [] 548 if rows and len(rows): 549 active = [ r[0] for r in rows] 550 551 # FIXME: this is patient dependant so how would a cache 552 # FIXME: work that's not taking into account pk_patient ? 553 # recommended_regimes = VaccByRecommender._recommended_regimes 554 # if not clear_cache and recommended_regimes: 555 # return recommended_regimes, active 556 557 r = ( {}, [] ) 558 559 # FIXME: use views ? 560 cmd = """ 561 select 562 r.pk_regime , 563 r.pk_recommended_by , 564 r.indication, 565 r.regime , 566 extract (epoch from d.min_age_due) /60/60/24, 567 extract (epoch from d.max_age_due) /60/60/24, 568 extract (epoch from d.min_interval ) /60/60/24, 569 d.seq_no 570 from 571 clin.v_vaccination_courses r, clin.vacc_def d 572 where 573 d.fk_regime = r.pk_regime 574 order by 575 r.pk_recommended_by, d.min_age_due""" 576 #print cmd 577 #import pdb 578 #pdb.set_trace() 579 # 580 rows = gmPG.run_ro_query('historica', cmd) 581 if rows is None: 582 VaccByRecommender._recommended_regimes = r 583 return r, active 584 585 row_fields = ['pk_regime', 'pk_recommender', 'indication' , 'regime', 'min_age_due', 'max_age_due', 'min_interval', 'seq_no' ] 586 587 for row in rows: 588 m = {} 589 for k, i in zip(row_fields, range(len(row))): 590 m[k] = row[i] 591 pk_recommender = m['pk_recommender'] 592 593 if not pk_recommender in r[0].keys(): 594 r[0][pk_recommender] = [] 595 r[1].append(pk_recommender) 596 r[0][pk_recommender].append(m) 597 598 for k, v in r[0].items(): 599 print k 600 for x in v: 601 print '\t', x 602 603 VaccByRecommender._recommended_regimes = r 604 return r, active
605 #--------------------------------------------------------
606 -def get_missing_vaccinations_ordered_min_due(pk_patient):
607 # DbC 608 int(pk_patient) 609 610 cmd = """ 611 select 612 indication, regime, 613 pk_regime, 614 pk_recommended_by, 615 seq_no , 616 extract(epoch from age_due_min) /60/60/24 as age_due_min, 617 extract(epoch from age_due_max) /60/60/24 as age_due_max, 618 extract(epoch from min_interval)/60/60/24 as min_interval 619 from 620 clin.v_pat_missing_vaccs 621 where pk_patient = %s 622 order by age_due_min, pk_recommended_by, indication 623 """ % pk_patient 624 625 rows = gmPG.run_ro_query('historica', cmd) 626 627 return rows
628 #--------------------------------------------------------
629 -def get_indications_from_vaccinations(vaccinations=None):
630 """Retrieves vaccination bundle indications list. 631 632 * vaccinations = list of any type of vaccination 633 - indicated 634 - due vacc 635 - overdue vaccs 636 - due boosters 637 - arbitrary 638 """ 639 # FIXME: can we not achieve this by: 640 # [lambda [vacc['indication'], ['l10n_indication']] for vacc in vaccination_list] 641 # I think we could, but we would be lacking error handling 642 if vaccinations is None: 643 _log.error('list of vaccinations must be supplied') 644 return (False, [['ERROR: list of vaccinations not supplied', _('ERROR: list of vaccinations not supplied')]]) 645 if len(vaccinations) == 0: 646 return (True, [['empty list of vaccinations', _('empty list of vaccinations')]]) 647 inds = [] 648 for vacc in vaccinations: 649 try: 650 inds.append([vacc['indication'], vacc['l10n_indication']]) 651 except KeyError: 652 try: 653 inds.append([vacc['indication'], vacc['indication']]) 654 except KeyError: 655 inds.append(['vacc -> ind error: %s' % str(vacc), _('vacc -> ind error: %s') % str(vacc)]) 656 return (True, inds)
657 #--------------------------------------------------------
658 -def put_patient_on_schedule(patient_id=None, course=None):
659 """ 660 Schedules a vaccination course for a patient 661 662 * patient_id = Patient's PK 663 * course = course object or Vaccination course's PK 664 """ 665 # FIXME: add method schedule_vaccination_course() to gmPerson.cPatient 666 if isinstance(course, cVaccinationCourse): 667 course_id = course['pk_course'] 668 else: 669 course_id = course 670 671 # insert new patient - vaccination course relation 672 queries = [] 673 cmd = """insert into clin.lnk_pat2vacc_reg (fk_patient, fk_course) 674 values (%s, %s)""" 675 queries.append((cmd, [patient_id, course_id])) 676 result, msg = gmPG.run_commit('historica', queries, True) 677 if result is None: 678 return (False, msg) 679 return (True, msg)
680 #--------------------------------------------------------
681 -def remove_patient_from_schedule(patient_id=None, course=None):
682 """unSchedules a vaccination course for a patient 683 684 * patient_id = Patient's PK 685 * course = course object or Vaccination course's PK 686 """ 687 # FIXME: add method schedule_vaccination_course() to gmPerson.cPatient 688 if isinstance(course, cVaccinationCourse): 689 course_id = course['pk_course'] 690 else: 691 course_id = course 692 693 # delete patient - vaccination course relation 694 queries = [] 695 cmd = """delete from clin.lnk_pat2vacc_reg where fk_patient = %s and fk_course = %s""" 696 697 queries.append((cmd, [patient_id, course_id])) 698 result, msg = gmPG.run_commit('historica', queries, True) 699 if result is None: 700 return (False, msg) 701 return (True, msg)
702 #--------------------------------------------------------
703 -def get_matching_vaccines_for_indications( all_ind):
704 705 quoted_inds = [ "'"+x + "%'" for x in all_ind] 706 707 # cmd_inds_per_vaccine = """ 708 # select count(v.trade_name) , v.trade_name 709 # from 710 # clin.vaccine v, clin.lnk_vaccine2inds l, clin.vacc_indication i 711 # where 712 # v.pk = l.fk_vaccine and l.fk_indication = i.id 713 # group 714 # by trade_name 715 # """ 716 717 cmd_inds_per_vaccine = """ 718 select 719 count(trade_name), 720 trade_name 721 from clin.v_inds4vaccine 722 group by trade_name""" 723 724 cmd_presence_in_vaccine = """ 725 select count(v.trade_name) , v.trade_name 726 727 from 728 clin.vaccine v, clin.lnk_vaccine2inds l, clin.vacc_indication i 729 where 730 v.pk = l.fk_vaccine and l.fk_indication = i.id 731 and 732 i.description like any ( array [ %s ] ) 733 group 734 735 by trade_name 736 737 """ % ', '.join( quoted_inds ) 738 739 inds_per_vaccine = gmPG.run_ro_query( 'historica', cmd_inds_per_vaccine) 740 741 presence_in_vaccine = gmPG.run_ro_query( 'historica', cmd_presence_in_vaccine) 742 743 map_vacc_count_inds = dict ( [ (x[1], x[0]) for x in inds_per_vaccine ] ) 744 745 matched_vaccines = [] 746 for (presence, vaccine) in presence_in_vaccine: 747 if presence == len ( all_ind) : 748 # matched the number of indications selected with a vaccine 749 # is this also ALL the vaccine's indications ? 750 if map_vacc_count_inds[vaccine] == presence: 751 matched_vaccines.append(vaccine) 752 return matched_vaccines
753 #============================================================ 754 # main - unit testing 755 #------------------------------------------------------------ 756 if __name__ == '__main__': 757 758 if len(sys.argv) < 2: 759 sys.exit() 760 761 if sys.argv[1] != u'test': 762 sys.exit() 763 764 # from Gnumed.pycommon import gmPG 765 #--------------------------------------------------------
766 - def test_vacc():
767 vacc = cVaccination(aPK_obj=1) 768 print vacc 769 fields = vacc.get_fields() 770 for field in fields: 771 print field, ':', vacc[field] 772 print "updatable:", vacc.get_updatable_fields()
773 #--------------------------------------------------------
774 - def test_due_vacc():
775 # Test for a due vaccination 776 pk_args = { 777 'pat_id': 12, 778 'indication': 'meningococcus C', 779 'seq_no': 1 780 } 781 missing_vacc = cMissingVaccination(aPK_obj=pk_args) 782 fields = missing_vacc.get_fields() 783 print "\nDue vaccination:" 784 print missing_vacc 785 for field in fields: 786 print field, ':', missing_vacc[field] 787 # Test for an overdue vaccination 788 pk_args = { 789 'pat_id': 12, 790 'indication': 'haemophilus influenzae b', 791 'seq_no': 2 792 } 793 missing_vacc = cMissingVaccination(aPK_obj=pk_args) 794 fields = missing_vacc.get_fields() 795 print "\nOverdue vaccination (?):" 796 print missing_vacc 797 for field in fields: 798 print field, ':', missing_vacc[field]
799 #--------------------------------------------------------
800 - def test_due_booster():
801 pk_args = { 802 'pat_id': 12, 803 'indication': 'tetanus' 804 } 805 missing_booster = cMissingBooster(aPK_obj=pk_args) 806 fields = missing_booster.get_fields() 807 print "\nDue booster:" 808 print missing_booster 809 for field in fields: 810 print field, ':', missing_booster[field]
811 #--------------------------------------------------------
812 - def test_scheduled_vacc():
813 scheduled_vacc = cScheduledVaccination(aPK_obj=20) 814 print "\nScheduled vaccination:" 815 print scheduled_vacc 816 fields = scheduled_vacc.get_fields() 817 for field in fields: 818 print field, ':', scheduled_vacc[field] 819 print "updatable:", scheduled_vacc.get_updatable_fields()
820 #--------------------------------------------------------
821 - def test_vaccination_course():
822 vaccination_course = cVaccinationCourse(aPK_obj=7) 823 print "\nVaccination course:" 824 print vaccination_course 825 fields = vaccination_course.get_fields() 826 for field in fields: 827 print field, ':', vaccination_course[field] 828 print "updatable:", vaccination_course.get_updatable_fields()
829 #--------------------------------------------------------
830 - def test_put_patient_on_schedule():
831 result, msg = put_patient_on_schedule(patient_id=12, course_id=1) 832 print '\nPutting patient id 12 on schedule id 1... %s (%s)' % (result, msg)
833 #--------------------------------------------------------
834 - def test_get_vaccines():
835 836 for vaccine in get_vaccines(): 837 print vaccine
838 839 #-------------------------------------------------------- 840 #test_vaccination_course() 841 #test_put_patient_on_schedule() 842 #test_scheduled_vacc() 843 #test_vacc() 844 #test_due_vacc() 845 #test_due_booster() 846 847 test_get_vaccines() 848 #============================================================ 849