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