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  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>" 
  5  __license__ = "GPL" 
  6   
  7  import sys 
  8  import logging 
  9  import io 
 10   
 11   
 12  if __name__ == '__main__': 
 13          sys.path.insert(0, '../../') 
 14  from Gnumed.pycommon import gmBusinessDBObject 
 15  from Gnumed.pycommon import gmPG2 
 16  from Gnumed.pycommon import gmI18N 
 17  from Gnumed.pycommon import gmTools 
 18  from Gnumed.pycommon import gmDateTime 
 19  if __name__ == '__main__': 
 20          gmI18N.activate_locale() 
 21          gmI18N.install_domain() 
 22  from Gnumed.business import gmMedication 
 23   
 24   
 25  _log = logging.getLogger('gm.vacc') 
 26   
 27  #============================================================ 
 28  URL_vaccination_plan = 'http://www.rki.de/DE/Content/Infekt/EpidBull/Archiv/2017/Ausgaben/34_17.pdf?__blob=publicationFile' 
 29   
 30  #============================================================ 
 31  _SQL_create_substance4vaccine = """-- in case <%(substance_tag)s> already exists: add ATC 
 32  UPDATE ref.substance SET atc = '%(atc)s' WHERE lower(description) = lower('%(desc)s') AND atc IS NULL; 
 33   
 34  INSERT INTO ref.substance (description, atc) 
 35          SELECT 
 36                  '%(desc)s', 
 37                  '%(atc)s' 
 38          WHERE NOT EXISTS ( 
 39                  SELECT 1 FROM ref.substance WHERE 
 40                          atc = '%(atc)s' 
 41                                  AND 
 42                          description = '%(desc)s' 
 43          ); 
 44   
 45  -- generic English 
 46  SELECT i18n.upd_tx('en', '%(orig)s', '%(trans)s'); 
 47  -- user language, if any, fails if not set 
 48  SELECT i18n.upd_tx('%(orig)s', '%(trans)s');""" 
 49   
 50  _SQL_map_indication2substance = """-- old-style "%(v21_ind)s" => "%(desc)s" 
 51  INSERT INTO staging.lnk_vacc_ind2subst_dose (fk_indication, fk_dose, is_live) 
 52          SELECT 
 53                  (SELECT id FROM ref.vacc_indication WHERE description = '%(v21_ind)s'), 
 54                  (SELECT pk_dose FROM ref.v_substance_doses WHERE 
 55                          amount = 1 
 56                                  AND 
 57                          unit = 'dose' 
 58                                  AND 
 59                          dose_unit = 'shot' 
 60                                  AND 
 61                          substance = '%(desc)s' 
 62                  ), 
 63                  %(is_live)s 
 64          WHERE EXISTS ( 
 65                  SELECT 1 FROM ref.vacc_indication WHERE description = '%(v21_ind)s' 
 66          );""" 
 67   
 68  _SQL_create_vacc_product = """-- -------------------------------------------------------------- 
 69  -- in case <%(prod_name)s> exists: add ATC 
 70  UPDATE ref.drug_product SET atc_code = '%(atc_prod)s' WHERE 
 71          atc_code IS NULL 
 72                  AND 
 73          description = '%(prod_name)s' 
 74                  AND 
 75          preparation = '%(prep)s' 
 76                  AND 
 77          is_fake IS TRUE; 
 78   
 79  INSERT INTO ref.drug_product (description, preparation, is_fake, atc_code) 
 80          SELECT 
 81                  '%(prod_name)s', 
 82                  '%(prep)s', 
 83                  TRUE, 
 84                  '%(atc_prod)s' 
 85          WHERE NOT EXISTS ( 
 86                  SELECT 1 FROM ref.drug_product WHERE 
 87                          description = '%(prod_name)s' 
 88                                  AND 
 89                          preparation = '%(prep)s' 
 90                                  AND 
 91                          is_fake = TRUE 
 92                                  AND 
 93                          atc_code = '%(atc_prod)s' 
 94          );""" 
 95   
 96  _SQL_create_vaccine = """-- add vaccine if necessary 
 97  INSERT INTO ref.vaccine (is_live, fk_drug_product) 
 98          SELECT 
 99                  %(is_live)s, 
100                  (SELECT pk FROM ref.drug_product WHERE 
101                          description = '%(prod_name)s' 
102                                  AND 
103                          preparation = '%(prep)s' 
104                                  AND 
105                          is_fake = TRUE 
106                                  AND 
107                          atc_code = '%(atc_prod)s' 
108                  ) 
109          WHERE NOT EXISTS ( 
110                  SELECT 1 FROM ref.vaccine WHERE 
111                          is_live IS %(is_live)s 
112                                  AND 
113                          fk_drug_product = ( 
114                                  SELECT pk FROM ref.drug_product WHERE 
115                                          description = '%(prod_name)s' 
116                                                  AND 
117                                          preparation = '%(prep)s' 
118                                                  AND 
119                                          is_fake = TRUE 
120                                                  AND 
121                                          atc_code = '%(atc_prod)s' 
122                          ) 
123          );""" 
124   
125  _SQL_create_vacc_subst_dose = """-- create dose, assumes substance exists 
126  INSERT INTO ref.dose (fk_substance, amount, unit, dose_unit) 
127          SELECT 
128                  (SELECT pk FROM ref.substance WHERE atc = '%(atc_subst)s' AND description = '%(name_subst)s' LIMIT 1), 
129                  1, 
130                  'dose', 
131                  'shot' 
132          WHERE NOT EXISTS ( 
133                  SELECT 1 FROM ref.dose WHERE 
134                          fk_substance = (SELECT pk FROM ref.substance WHERE atc = '%(atc_subst)s' AND description = '%(name_subst)s' LIMIT 1) 
135                                  AND 
136                          amount = 1 
137                                  AND 
138                          unit = 'dose' 
139                                  AND 
140                          dose_unit IS NOT DISTINCT FROM 'shot' 
141          );""" 
142   
143  _SQL_link_dose2vacc_prod = """-- link dose to product 
144  INSERT INTO ref.lnk_dose2drug (fk_dose, fk_drug_product) 
145          SELECT 
146                  (SELECT pk from ref.dose WHERE 
147                          fk_substance = (SELECT pk FROM ref.substance WHERE atc = '%(atc_subst)s' AND description = '%(name_subst)s' LIMIT 1) 
148                                  AND 
149                          amount = 1 
150                                  AND 
151                          unit = 'dose' 
152                                  AND 
153                          dose_unit IS NOT DISTINCT FROM 'shot' 
154                  ), 
155                  (SELECT pk FROM ref.drug_product WHERE 
156                          description = '%(prod_name)s' 
157                                  AND 
158                          preparation = '%(prep)s' 
159                                  AND 
160                          is_fake = TRUE 
161                                  AND 
162                          atc_code = '%(atc_prod)s' 
163                  ) 
164          WHERE NOT EXISTS ( 
165                  SELECT 1 FROM ref.lnk_dose2drug WHERE 
166                          fk_dose = ( 
167                                  SELECT PK from ref.dose WHERE 
168                                          fk_substance = (SELECT pk FROM ref.substance WHERE atc = '%(atc_subst)s' AND description = '%(name_subst)s' LIMIT 1) 
169                                                  AND 
170                                          amount = 1 
171                                                  AND 
172                                          unit = 'dose' 
173                                                  AND 
174                                          dose_unit IS NOT DISTINCT FROM 'shot' 
175                          ) 
176                                  AND 
177                          fk_drug_product = ( 
178                                  SELECT pk FROM ref.drug_product WHERE 
179                                          description = '%(prod_name)s' 
180                                                  AND 
181                                          preparation = '%(prep)s' 
182                                                  AND 
183                                          is_fake = TRUE 
184                                                  AND 
185                                          atc_code = '%(atc_prod)s' 
186                          ) 
187          );""" 
188   
189  _SQL_create_indications_mapping_table = """-- set up helper table for conversion of vaccines from using 
190  -- linked indications to using linked substances, 
191  -- to be dropped after converting vaccines 
192  DROP TABLE IF EXISTS staging.lnk_vacc_ind2subst_dose CASCADE; 
193   
194  CREATE UNLOGGED TABLE staging.lnk_vacc_ind2subst_dose ( 
195          fk_indication INTEGER 
196                  NOT NULL 
197                  REFERENCES ref.vacc_indication(id) 
198                          ON UPDATE CASCADE 
199                          ON DELETE RESTRICT, 
200          fk_dose INTEGER 
201                  NOT NULL 
202                  REFERENCES ref.dose(pk) 
203                          ON UPDATE CASCADE 
204                          ON DELETE RESTRICT, 
205          is_live 
206                  BOOLEAN 
207                  NOT NULL 
208                  DEFAULT false, 
209          UNIQUE(fk_indication, fk_dose), 
210          UNIQUE(fk_indication, is_live) 
211  ); 
212   
213   
214  DROP VIEW IF EXISTS staging.v_lnk_vacc_ind2subst_dose CASCADE; 
215   
216  CREATE VIEW staging.v_lnk_vacc_ind2subst_dose AS 
217  SELECT 
218          s_lvi2sd.is_live 
219                  as mapping_is_for_live_vaccines, 
220          r_vi.id 
221                  as pk_indication, 
222          r_vi.description 
223                  as indication, 
224          r_vi.atcs_single_indication, 
225          r_vi.atcs_combi_indication, 
226          r_d.pk 
227                  as pk_dose, 
228          r_d.amount, 
229          r_d.unit, 
230          r_d.dose_unit, 
231          r_s.pk 
232                  as pk_substance, 
233          r_s.description 
234                  as substance, 
235          r_s.atc 
236                  as atc_substance 
237  FROM 
238          staging.lnk_vacc_ind2subst_dose s_lvi2sd 
239                  inner join ref.vacc_indication r_vi on (r_vi.id = s_lvi2sd.fk_indication) 
240                  inner join ref.dose r_d on (r_d.pk = s_lvi2sd.fk_dose) 
241                          inner join ref.substance r_s on (r_s.pk = r_d.fk_substance) 
242  ;""" 
243   
244  _SQL_create_generic_vaccines_script = """-- ============================================================== 
245  -- GNUmed database schema change script 
246  -- 
247  -- License: GPL v2 or later 
248  -- Author: karsten.hilbert@gmx.net 
249  -- 
250  -- THIS IS A GENERATED FILE. DO NOT EDIT. 
251  -- 
252  -- ============================================================== 
253  \set ON_ERROR_STOP 1 
254  --set default_transaction_read_only to off; 
255   
256  -- -------------------------------------------------------------- 
257  -- indications mapping helper table 
258  -- -------------------------------------------------------------- 
259  %s 
260   
261  -- -------------------------------------------------------------- 
262  -- generic vaccine "substances" (= indications) 
263  -- -------------------------------------------------------------- 
264  %s 
265   
266  -- -------------------------------------------------------------- 
267  -- generic vaccines 
268  -- -------------------------------------------------------------- 
269  -- new-style vaccines are not linked to indications, so drop 
270  -- trigger asserting that condition, 
271  DROP FUNCTION IF EXISTS clin.trf_sanity_check_vaccine_has_indications() CASCADE; 
272   
273   
274  -- need to disable trigger before running 
275  ALTER TABLE ref.drug_product 
276          DISABLE TRIGGER tr_assert_product_has_components 
277  ; 
278   
279  %s 
280   
281  -- want to re-enable trigger as now all inserted 
282  -- vaccines satisfy the conditions 
283  ALTER TABLE ref.drug_product 
284          ENABLE TRIGGER tr_assert_product_has_components 
285  ; 
286   
287  -- -------------------------------------------------------------- 
288  -- indications mapping data 
289  -- -------------------------------------------------------------- 
290  -- map old style 
291  --              (clin|ref).vacc_indication.description 
292  -- to new style 
293  --              ref.v_substance_doses.substance 
294   
295  %s 
296   
297  -- -------------------------------------------------------------- 
298  select gm.log_script_insertion('v%s-ref-create_generic_vaccines.sql', '%s'); 
299  """ 
300   
301  #============================================================ 
302 -def write_generic_vaccine_sql(version, include_indications_mapping=False, filename=None):
303 if filename is None: 304 filename = gmTools.get_unique_filename(suffix = '.sql') 305 _log.debug('writing SQL for creating generic vaccines to: %s', filename) 306 sql_file = io.open(filename, mode = 'wt', encoding = 'utf8') 307 sql_file.write(create_generic_vaccine_sql ( 308 version, 309 include_indications_mapping = include_indications_mapping 310 )) 311 sql_file.close() 312 return filename
313 314 #------------------------------------------------------------
315 -def create_generic_vaccine_sql(version, include_indications_mapping=False):
316 317 _log.debug('including indications mapping table with generic vaccines creation SQL: %s', include_indications_mapping) 318 319 from Gnumed.business import gmVaccDefs 320 321 sql_create_substances = [] 322 sql_populate_ind2subst_map = [] 323 sql_create_vaccines = [] 324 325 for substance_tag in gmVaccDefs._VACCINE_SUBSTANCES: 326 subst = gmVaccDefs._VACCINE_SUBSTANCES[substance_tag] 327 args = { 328 'substance_tag': substance_tag, 329 'atc': subst['atc4target'], 330 'desc': subst['name'], 331 'orig': subst['target'].split('::')[0], 332 'trans': subst['target'].split('::')[-1] 333 } 334 sql_create_substances.append(_SQL_create_substance4vaccine % args) 335 try: 336 for v21_ind in subst['v21_indications']: 337 args['v21_ind'] = v21_ind 338 args['is_live'] = 'false' 339 sql_populate_ind2subst_map.append(_SQL_map_indication2substance % args) 340 except KeyError: 341 pass 342 try: 343 for v21_ind in subst['v21_indications_live']: 344 args['v21_ind'] = v21_ind 345 args['is_live'] = 'true' 346 sql_populate_ind2subst_map.append(_SQL_map_indication2substance % args) 347 except KeyError: 348 pass 349 args = {} 350 351 for key in gmVaccDefs._GENERIC_VACCINES: 352 vaccine_def = gmVaccDefs._GENERIC_VACCINES[key] 353 # create product 354 args = { 355 'atc_prod': vaccine_def['atc'], 356 'prod_name': vaccine_def['name'], 357 # generic vaccines always have the English preparation 358 'prep': 'vaccine', 359 'is_live': vaccine_def['live'] 360 } 361 sql_create_vaccines.append(_SQL_create_vacc_product % args) 362 # create doses 363 for ingredient_tag in vaccine_def['ingredients']: 364 vacc_subst_def = gmVaccDefs._VACCINE_SUBSTANCES[ingredient_tag] 365 args['atc_subst'] = vacc_subst_def['atc4target'] 366 args['name_subst'] = vacc_subst_def['name'] 367 # substance already created, only need to create dose 368 sql_create_vaccines.append(_SQL_create_vacc_subst_dose % args) 369 # link dose to product 370 sql_create_vaccines.append(_SQL_link_dose2vacc_prod % args) 371 # the following does not work because there are mixed vaccines 372 # any live ingredients included ? 373 # if vacc_subst_def.has_key('v21_indications_live'): 374 # if vaccine_def['live'] is False: 375 # print vaccine_def 376 # raise Exception('vaccine def says "NOT live" but ingredients DO map to <v21_indications_LIVE>') 377 # if vacc_subst_def.has_key('v21_indications'): 378 # if vaccine_def['live'] is True: 379 # print vaccine_def 380 # raise Exception('vaccine def says "live" but ingredients do NOT map to v21_indications_LIVE') 381 382 # create vaccine 383 sql_create_vaccines.append(_SQL_create_vaccine % args) 384 385 # join 386 sql = _SQL_create_generic_vaccines_script % ( 387 gmTools.bool2subst ( 388 include_indications_mapping, 389 _SQL_create_indications_mapping_table, 390 '-- indications mapping table not included' 391 ), 392 '\n\n'.join(sql_create_substances), 393 '\n\n'.join(sql_create_vaccines), 394 gmTools.bool2subst ( 395 include_indications_mapping, 396 '\n\n'.join(sql_populate_ind2subst_map), 397 '-- indications mapping table not populated' 398 ), 399 version, 400 version 401 ) 402 return sql
403 404 #============================================================ 405 # vaccine related code 406 #------------------------------------------------------------ 407 _sql_fetch_vaccine = """SELECT * FROM ref.v_vaccines WHERE %s""" 408
409 -class cVaccine(gmBusinessDBObject.cBusinessDBObject):
410 """Represents one vaccine.""" 411 412 _cmd_fetch_payload = _sql_fetch_vaccine % "pk_vaccine = %s" 413 414 _cmds_store_payload = [ 415 """UPDATE ref.vaccine SET 416 --id_route = %(pk_route)s, 417 is_live = %(is_live)s, 418 min_age = %(min_age)s, 419 max_age = %(max_age)s, 420 comment = gm.nullify_empty_string(%(comment)s), 421 fk_drug_product = %(pk_drug_product)s 422 WHERE 423 pk = %(pk_vaccine)s 424 AND 425 xmin = %(xmin_vaccine)s 426 RETURNING 427 xmin as xmin_vaccine 428 """ 429 ] 430 431 _updatable_fields = [ 432 #u'pk_route', 433 'is_live', 434 'min_age', 435 'max_age', 436 'comment', 437 'pk_drug_product' 438 ] 439 440 #--------------------------------------------------------
441 - def format(self, *args, **kwargs):
442 lines = [] 443 lines.append(_('%s with %s %s #%s') % ( 444 gmTools.bool2subst(self._payload[self._idx['is_live']], _('Live vaccine'), _('Inactive vaccine'), '<liveness error in DB>'), 445 len(self._payload[self._idx['indications']]), 446 gmTools.bool2subst(len(self._payload[self._idx['indications']]) == 1, _('indication'), _('indications'), _('indication(s)')), 447 self._payload[self._idx['pk_vaccine']] 448 )) 449 lines.append(_(' Product: "%s" #%s') % ( 450 self._payload[self._idx['vaccine']], 451 self._payload[self._idx['pk_drug_product']] 452 )) 453 lines.append(_(' %s%s%s%s') % ( 454 self._payload[self._idx['l10n_preparation']], 455 gmTools.coalesce(gmTools.bool2subst(self._payload[self._idx['is_fake_vaccine']], _('fake product'), None, None), '', ', %s'), 456 gmTools.coalesce(self._payload[self._idx['atc_code']], '', ' [ATC:%s]'), 457 gmTools.coalesce(self._payload[self._idx['external_code']], '', ' [%s:%%s]' % self._payload[self._idx['external_code_type']]) 458 )) 459 #lines.append(_(u' %sage %s - %s') % ( 460 # gmTools.coalesce(self._payload[self._idx['route_description']], u'', u'%s, '), #route_abbreviation 461 lines.append(_(' Age %s - %s') % ( 462 gmTools.coalesce(self._payload[self._idx['min_age']], '?'), 463 gmTools.coalesce(self._payload[self._idx['max_age']], '?') 464 )) 465 if self._payload[self._idx['comment']] is not None: 466 lines.extend([ ' %s' % l for l in self._payload[self._idx['comment']].split('\n')] ) 467 lines.append(_(' Indications')) 468 lines.extend( [ ' %s [ATC:%s]' % (i['l10n_indication'], i['atc_indication']) for i in self._payload[self._idx['indications']] ]) 469 470 return lines
471 472 #-------------------------------------------------------- 473 # properties 474 #--------------------------------------------------------
475 - def _get_product(self):
476 return gmMedication.cDrugProduct(aPK_obj = self._payload[self._idx['pk_drug_product']])
477 478 product = property(_get_product, lambda x:x) 479 480 #--------------------------------------------------------
481 - def _get_is_in_use(self):
482 cmd = 'SELECT EXISTS(SELECT 1 FROM clin.vaccination WHERE fk_vaccine = %(pk)s)' 483 args = {'pk': self._payload[self._idx['pk_vaccine']]} 484 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False) 485 return rows[0][0]
486 487 is_in_use = property(_get_is_in_use, lambda x:x)
488 489 #------------------------------------------------------------
490 -def create_vaccine(pk_drug_product=None, product_name=None, indications=None):
491 492 conn = gmPG2.get_connection(readonly = False) 493 494 if pk_drug_product is None: 495 #prep = _('vaccine') 496 prep = 'vaccine' 497 _log.debug('creating vaccine drug product [%s %s]', product_name, prep) 498 vacc_prod = gmMedication.create_drug_product ( 499 product_name = product_name, 500 preparation = prep, 501 return_existing = True, 502 # indications are ref.dose rows 503 doses = indications, 504 link_obj = conn 505 ) 506 #conn.commit() 507 vacc_prod['atc'] = 'J07' 508 vacc_prod.save(conn = conn) 509 pk_drug_product = vacc_prod['pk_drug_product'] 510 511 cmd = 'INSERT INTO ref.vaccine (fk_drug_product) values (%(pk_drug_product)s) RETURNING pk' 512 queries = [{'cmd': cmd, 'args': {'pk_drug_product': pk_drug_product}}] 513 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = queries, get_col_idx = False, return_data = True, end_tx = True) 514 conn.close() 515 return cVaccine(aPK_obj = rows[0]['pk'])
516 517 #------------------------------------------------------------
518 -def delete_vaccine(vaccine=None):
519 520 cmd = 'DELETE FROM ref.vaccine WHERE pk = %(pk)s' 521 args = {'pk': vaccine} 522 523 try: 524 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}]) 525 except gmPG2.dbapi.IntegrityError: 526 _log.exception('cannot delete vaccine [%s]', vaccine) 527 return False 528 529 return True
530 531 #------------------------------------------------------------
532 -def get_vaccines(order_by=None):
533 534 if order_by is None: 535 cmd = _sql_fetch_vaccine % 'TRUE' 536 else: 537 cmd = _sql_fetch_vaccine % ('TRUE\nORDER BY %s' % order_by) 538 539 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 540 541 return [ cVaccine(row = {'data': r, 'idx': idx, 'pk_field': 'pk_vaccine'}) for r in rows ]
542 543 #============================================================ 544 # vaccination related classes 545 #============================================================ 546 sql_fetch_vaccination = """SELECT * FROM clin.v_vaccinations WHERE %s""" 547
548 -class cVaccination(gmBusinessDBObject.cBusinessDBObject):
549 550 _cmd_fetch_payload = sql_fetch_vaccination % "pk_vaccination = %s" 551 552 _cmds_store_payload = [ 553 """UPDATE clin.vaccination SET 554 soap_cat = %(soap_cat)s, 555 clin_when = %(date_given)s, 556 site = gm.nullify_empty_string(%(site)s), 557 batch_no = gm.nullify_empty_string(%(batch_no)s), 558 reaction = gm.nullify_empty_string(%(reaction)s), 559 narrative = gm.nullify_empty_string(%(comment)s), 560 fk_vaccine = %(pk_vaccine)s, 561 fk_provider = %(pk_provider)s, 562 fk_encounter = %(pk_encounter)s, 563 fk_episode = %(pk_episode)s 564 WHERE 565 pk = %(pk_vaccination)s 566 AND 567 xmin = %(xmin_vaccination)s 568 RETURNING 569 xmin as xmin_vaccination 570 """ 571 ] 572 573 _updatable_fields = [ 574 'soap_cat', 575 'date_given', 576 'site', 577 'batch_no', 578 'reaction', 579 'comment', 580 'pk_vaccine', 581 'pk_provider', 582 'pk_encounter', 583 'pk_episode' 584 ] 585 586 #--------------------------------------------------------
587 - def format_maximum_information(self, patient=None):
588 return self.format ( 589 with_indications = True, 590 with_comment = True, 591 with_reaction = True, 592 date_format = '%Y %b %d' 593 )
594 595 #--------------------------------------------------------
596 - def format(self, with_indications=False, with_comment=False, with_reaction=False, date_format='%Y-%m-%d'):
597 598 lines = [] 599 600 lines.append (' %s: %s [%s]%s' % ( 601 self._payload[self._idx['date_given']].strftime(date_format), 602 self._payload[self._idx['vaccine']], 603 self._payload[self._idx['batch_no']], 604 gmTools.coalesce(self._payload[self._idx['site']], '', ' (%s)') 605 )) 606 607 if with_comment: 608 if self._payload[self._idx['comment']] is not None: 609 lines.append(' %s' % self._payload[self._idx['comment']]) 610 611 if with_reaction: 612 if self._payload[self._idx['reaction']] is not None: 613 lines.append(' %s' % self._payload[self._idx['reaction']]) 614 615 if with_indications: 616 lines.append(' %s' % ' / '.join([ i['l10n_indication'] for i in self._payload[self._idx['indications']] ])) 617 618 return lines
619 620 #--------------------------------------------------------
621 - def _get_vaccine(self):
622 return cVaccine(aPK_obj = self._payload[self._idx['pk_vaccine']])
623 624 vaccine = property(_get_vaccine, lambda x:x)
625 626 #------------------------------------------------------------
627 -def create_vaccination(encounter=None, episode=None, vaccine=None, batch_no=None):
628 629 cmd = """ 630 INSERT INTO clin.vaccination ( 631 fk_encounter, 632 fk_episode, 633 fk_vaccine, 634 batch_no 635 ) VALUES ( 636 %(enc)s, 637 %(epi)s, 638 %(vacc)s, 639 %(batch)s 640 ) RETURNING pk; 641 """ 642 args = { 643 'enc': encounter, 644 'epi': episode, 645 'vacc': vaccine, 646 'batch': batch_no 647 } 648 649 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False, return_data = True) 650 651 return cVaccination(aPK_obj = rows[0][0])
652 653 #------------------------------------------------------------
654 -def delete_vaccination(vaccination=None):
655 cmd = """DELETE FROM clin.vaccination WHERE pk = %(pk)s""" 656 args = {'pk': vaccination} 657 658 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
659 660 #------------------------------------------------------------ 661
662 -def format_latest_vaccinations(output_format='latex', emr=None):
663 664 _log.debug('formatting latest vaccinations into [%s]', output_format) 665 666 vaccs = emr.get_latest_vaccinations() 667 668 if output_format == 'latex': 669 return __format_latest_vaccinations_latex(vaccinations = vaccs) 670 671 msg = _('unknown vaccinations output format [%s]') % output_format 672 _log.error(msg) 673 return msg
674 675 #------------------------------------------------------------ 676
677 -def __format_latest_vaccinations_latex(vaccinations=None):
678 679 if len(vaccinations) == 0: 680 return '\\noindent %s' % _('No vaccinations to format.') 681 682 tex = '\\noindent %s {\\tiny (%s)\\par}\n' % (_('Latest vaccinations'), _('per target condition')) 683 tex += '\n' 684 tex += '\\noindent \\begin{tabular}{|l|l|l|l|l|l|}\n' 685 tex += '\\hline\n' 686 tex += '%s & %s & {\\footnotesize %s} & {\\footnotesize %s} & {\\footnotesize %s\\footnotemark} & {\\footnotesize %s\\footnotemark} \\\\ \n' % ( 687 _('Target'), 688 _('Last given'), 689 _('Vaccine'), 690 _('Lot \#'), 691 _('SoaP'), 692 gmTools.u_sum 693 ) 694 tex += '\\hline\n' 695 tex += '\n' 696 tex += '\\hline\n' 697 tex += '%s' 698 tex += '\n' 699 tex += '\\end{tabular}\n' 700 tex += '\n' 701 tex += '\\addtocounter{footnote}{-1} \n' 702 tex += '\\footnotetext{%s} \n' % _('SoaP -- "S"ubjective: vaccination was remembered by patient. "P"lan: vaccination was administered in the practice or copied from trustworthy records.') 703 tex += '\\addtocounter{footnote}{1} \n' 704 tex += '\\footnotetext{%s -- %s} \n' % (gmTools.u_sum, _('Total number of vaccinations recorded for the corresponding target condition.')) 705 tex += '\n' 706 707 row_template = '%s & %s & {\\scriptsize %s} & {\\scriptsize %s} & {\\scriptsize %s} & {\\scriptsize %s} \\\\ \n' 708 lines = '' 709 targets = sorted(vaccinations.keys()) 710 for target in targets: 711 target_count, vacc = vaccinations[target] 712 lines += row_template % ( 713 target, 714 gmDateTime.pydt_strftime(vacc['date_given'], '%Y %b %d'), 715 vacc['vaccine'], 716 gmTools.tex_escape_string(vacc['batch_no'].strip()), 717 vacc['soap_cat'].upper(), 718 target_count 719 ) 720 if vacc['site'] is not None: 721 lines += ' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par} \\\\ \n' % (_('Injection site'), vacc['site'].strip()) 722 if vacc['reaction'] is not None: 723 lines += ' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par} \\\\ \n' % (_('Reaction'), vacc['reaction'].strip()) 724 if vacc['comment'] is not None: 725 lines += ' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par} \\\\ \n' % (_('Comment'), vacc['comment'].strip()) 726 lines += '\\hline \n' 727 728 return tex % lines
729 730 #============================================================ 731 # main - unit testing 732 #------------------------------------------------------------ 733 if __name__ == '__main__': 734 735 if len(sys.argv) < 2: 736 sys.exit() 737 738 if sys.argv[1] != 'test': 739 sys.exit() 740 741 # from Gnumed.pycommon import gmPG 742 #--------------------------------------------------------
743 - def test_vacc():
744 vacc = cVaccination(aPK_obj=1) 745 print(vacc) 746 fields = vacc.get_fields() 747 for field in fields: 748 print(field, ':', vacc[field]) 749 print("updatable:", vacc.get_updatable_fields())
750 751 #--------------------------------------------------------
752 - def test_due_vacc():
753 # Test for a due vaccination 754 pk_args = { 755 'pat_id': 12, 756 'indication': 'meningococcus C', 757 'seq_no': 1 758 } 759 missing_vacc = cMissingVaccination(aPK_obj=pk_args) 760 fields = missing_vacc.get_fields() 761 print("\nDue vaccination:") 762 print(missing_vacc) 763 for field in fields: 764 print(field, ':', missing_vacc[field]) 765 # Test for an overdue vaccination 766 pk_args = { 767 'pat_id': 12, 768 'indication': 'haemophilus influenzae b', 769 'seq_no': 2 770 } 771 missing_vacc = cMissingVaccination(aPK_obj=pk_args) 772 fields = missing_vacc.get_fields() 773 print("\nOverdue vaccination (?):") 774 print(missing_vacc) 775 for field in fields: 776 print(field, ':', missing_vacc[field])
777 778 #--------------------------------------------------------
779 - def test_due_booster():
780 pk_args = { 781 'pat_id': 12, 782 'indication': 'tetanus' 783 } 784 missing_booster = cMissingBooster(aPK_obj=pk_args) 785 fields = missing_booster.get_fields() 786 print("\nDue booster:") 787 print(missing_booster) 788 for field in fields: 789 print(field, ':', missing_booster[field])
790 791 #--------------------------------------------------------
792 - def test_scheduled_vacc():
793 scheduled_vacc = cScheduledVaccination(aPK_obj=20) 794 print("\nScheduled vaccination:") 795 print(scheduled_vacc) 796 fields = scheduled_vacc.get_fields() 797 for field in fields: 798 print(field, ':', scheduled_vacc[field]) 799 print("updatable:", scheduled_vacc.get_updatable_fields())
800 801 #--------------------------------------------------------
802 - def test_vaccination_course():
803 vaccination_course = cVaccinationCourse(aPK_obj=7) 804 print("\nVaccination course:") 805 print(vaccination_course) 806 fields = vaccination_course.get_fields() 807 for field in fields: 808 print(field, ':', vaccination_course[field]) 809 print("updatable:", vaccination_course.get_updatable_fields())
810 811 #--------------------------------------------------------
812 - def test_put_patient_on_schedule():
813 result, msg = put_patient_on_schedule(patient_id=12, course_id=1) 814 print('\nPutting patient id 12 on schedule id 1... %s (%s)' % (result, msg))
815 816 #--------------------------------------------------------
817 - def test_get_vaccines():
818 for vaccine in get_vaccines(): 819 print('--------------------------------') 820 #print u'%s' % vaccine 821 print('\n'.join(vaccine.format()))
822 823 #--------------------------------------------------------
824 - def test_get_vaccinations():
825 for v in get_vaccinations(): 826 print(v)
827 828 #--------------------------------------------------------
829 - def test_create_generic_vaccine_sql():
830 print(create_generic_vaccine_sql('22.0'))
831 832 #--------------------------------------------------------
833 - def test_write_generic_vaccine_sql(version, filename):
834 print(write_generic_vaccine_sql ( 835 version, 836 include_indications_mapping = True, 837 filename = filename 838 ))
839 840 #-------------------------------------------------------- 841 #test_vaccination_course() 842 #test_put_patient_on_schedule() 843 #test_scheduled_vacc() 844 #test_vacc() 845 #test_due_vacc() 846 #test_due_booster() 847 848 #test_get_vaccines() 849 #test_get_vaccinations() 850 #test_create_generic_vaccine_sql() 851 test_write_generic_vaccine_sql(sys.argv[2], sys.argv[3]) 852