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