| Home | Trees | Indices | Help |
|
|---|
|
|
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 #============================================================
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 #------------------------------------------------------------
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
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 #--------------------------------------------------------
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 #--------------------------------------------------------
480
481 product = property(_get_product, lambda x:x)
482
483 #--------------------------------------------------------
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 #------------------------------------------------------------
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 #------------------------------------------------------------
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 #------------------------------------------------------------
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
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 #--------------------------------------------------------
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 #--------------------------------------------------------
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(order_by, '', 'ORDER BY %s' % order_by)
653 if len(where_parts) == 0:
654 WHERE = 'True'
655 else:
656 WHERE = '\nAND '.join(where_parts)
657
658 SQL = '%s %s' % (
659 _SQL_get_vaccination_fields % WHERE,
660 ORDER_BY
661 )
662 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': SQL, 'args': args}], get_col_idx = True)
663 if return_pks:
664 return [ r['pk_vaccination'] for r in rows ]
665 vaccs = [ cVaccination(row = {'idx': idx, 'data': r, 'pk_field': 'pk_vaccination'}) for r in rows ]
666 return vaccs
667
668 #------------------------------------------------------------
670
671 cmd = """
672 INSERT INTO clin.vaccination (
673 fk_encounter,
674 fk_episode,
675 fk_vaccine,
676 batch_no
677 ) VALUES (
678 %(enc)s,
679 %(epi)s,
680 %(vacc)s,
681 %(batch)s
682 ) RETURNING pk;
683 """
684 args = {
685 'enc': encounter,
686 'epi': episode,
687 'vacc': vaccine,
688 'batch': batch_no
689 }
690
691 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False, return_data = True)
692
693 return cVaccination(aPK_obj = rows[0][0])
694
695 #------------------------------------------------------------
697 cmd = """DELETE FROM clin.vaccination WHERE pk = %(pk)s"""
698 args = {'pk': vaccination}
699
700 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
701
702 #------------------------------------------------------------
703
705
706 _log.debug('formatting latest vaccinations into [%s]', output_format)
707
708 vaccs = emr.get_latest_vaccinations()
709
710 if output_format == 'latex':
711 return __format_latest_vaccinations_latex(vaccinations = vaccs)
712
713 msg = _('unknown vaccinations output format [%s]') % output_format
714 _log.error(msg)
715 return msg
716
717 #------------------------------------------------------------
718
720
721 if len(vaccinations) == 0:
722 return '\\noindent %s' % _('No vaccinations recorded.')
723
724 tex = '\\noindent %s {\\tiny (%s)\\par}\n' % (_('Latest vaccinations'), _('per target condition'))
725 tex += '\n'
726 tex += '\\noindent \\begin{tabular}{|l|l|l|l|l|l|}\n'
727 tex += '\\hline\n'
728 tex += '%s & %s & {\\footnotesize %s} & {\\footnotesize %s} & {\\footnotesize %s\\footnotemark} & {\\footnotesize $\\Sigma$\\footnotemark}\\\\\n' % (
729 _('Target'),
730 _('Last given'),
731 _('Vaccine'),
732 _('Lot \#'),
733 _('SoaP')
734 )
735 tex += '\\hline\n'
736 tex += '\n'
737 tex += '\\hline\n'
738 tex += '%s' # this is where the actual vaccination rows end up
739 tex += '\n'
740 tex += '\\end{tabular}\n'
741 tex += '\n'
742 tex += '\\addtocounter{footnote}{-1}\n'
743 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.')
744 tex += '\\addtocounter{footnote}{1}\n'
745 tex += '\\footnotetext{$\\Sigma$ -- %s}\n' % _('Total number of vaccinations recorded for the corresponding target condition.')
746 tex += '\n'
747
748 row_template = '%s & %s & {\\scriptsize %s} & {\\scriptsize %s} & {\\scriptsize %s} & {\\scriptsize %s}\\\\\n'
749 lines = ''
750 targets = sorted(vaccinations.keys())
751 for target in targets:
752 target_count, vacc = vaccinations[target]
753 lines += row_template % (
754 target,
755 gmDateTime.pydt_strftime(vacc['date_given'], '%Y %b %d'),
756 vacc['vaccine'],
757 gmTools.tex_escape_string(vacc['batch_no'].strip()),
758 vacc['soap_cat'].upper(),
759 target_count
760 )
761 if vacc['site'] is not None:
762 lines += ' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par}\\\\\n' % (_('Injection site'), vacc['site'].strip())
763 if vacc['reaction'] is not None:
764 lines += ' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par}\\\\\n' % (_('Reaction'), vacc['reaction'].strip())
765 if vacc['comment'] is not None:
766 lines += ' & \\multicolumn{5}{l|}{\\scriptsize %s: %s\\par}\\\\\n' % (_('Comment'), vacc['comment'].strip())
767 lines += '\\hline\n'
768
769 return tex % lines
770
771 #============================================================
772 # main - unit testing
773 #------------------------------------------------------------
774 if __name__ == '__main__':
775
776 if len(sys.argv) < 2:
777 sys.exit()
778
779 if sys.argv[1] != 'test':
780 sys.exit()
781
782 # from Gnumed.pycommon import gmPG
783 #--------------------------------------------------------
785 vacc = cVaccination(aPK_obj=1)
786 print(vacc)
787 fields = vacc.get_fields()
788 for field in fields:
789 print(field, ':', vacc[field])
790 print("updatable:", vacc.get_updatable_fields())
791
792 #--------------------------------------------------------
794 # Test for a due vaccination
795 pk_args = {
796 'pat_id': 12,
797 'indication': 'meningococcus C',
798 'seq_no': 1
799 }
800 missing_vacc = cMissingVaccination(aPK_obj=pk_args)
801 fields = missing_vacc.get_fields()
802 print("\nDue vaccination:")
803 print(missing_vacc)
804 for field in fields:
805 print(field, ':', missing_vacc[field])
806 # Test for an overdue vaccination
807 pk_args = {
808 'pat_id': 12,
809 'indication': 'haemophilus influenzae b',
810 'seq_no': 2
811 }
812 missing_vacc = cMissingVaccination(aPK_obj=pk_args)
813 fields = missing_vacc.get_fields()
814 print("\nOverdue vaccination (?):")
815 print(missing_vacc)
816 for field in fields:
817 print(field, ':', missing_vacc[field])
818
819 #--------------------------------------------------------
821 pk_args = {
822 'pat_id': 12,
823 'indication': 'tetanus'
824 }
825 missing_booster = cMissingBooster(aPK_obj=pk_args)
826 fields = missing_booster.get_fields()
827 print("\nDue booster:")
828 print(missing_booster)
829 for field in fields:
830 print(field, ':', missing_booster[field])
831
832 #--------------------------------------------------------
834 scheduled_vacc = cScheduledVaccination(aPK_obj=20)
835 print("\nScheduled vaccination:")
836 print(scheduled_vacc)
837 fields = scheduled_vacc.get_fields()
838 for field in fields:
839 print(field, ':', scheduled_vacc[field])
840 print("updatable:", scheduled_vacc.get_updatable_fields())
841
842 #--------------------------------------------------------
844 vaccination_course = cVaccinationCourse(aPK_obj=7)
845 print("\nVaccination course:")
846 print(vaccination_course)
847 fields = vaccination_course.get_fields()
848 for field in fields:
849 print(field, ':', vaccination_course[field])
850 print("updatable:", vaccination_course.get_updatable_fields())
851
852 #--------------------------------------------------------
854 result, msg = put_patient_on_schedule(patient_id=12, course_id=1)
855 print('\nPutting patient id 12 on schedule id 1... %s (%s)' % (result, msg))
856
857 #--------------------------------------------------------
859 for vaccine in get_vaccines():
860 print('--------------------------------')
861 #print u'%s' % vaccine
862 print('\n'.join(vaccine.format()))
863
864 #--------------------------------------------------------
866 v1 = get_vaccinations(return_pks = True)
867 v2 = get_vaccinations2(return_pks = True)
868 print(v1)
869 print(v2)
870 for v in v1:
871 if v not in v2:
872 print('ERROR')
873 for v in v2:
874 if v not in v1:
875 print('ERROR')
876
877 # for v in get_vaccinations():
878 # print(v)
879
880 #--------------------------------------------------------
882 print(create_generic_vaccine_sql('22.0'))
883
884 #--------------------------------------------------------
886 print(write_generic_vaccine_sql (
887 version,
888 include_indications_mapping = True,
889 filename = filename
890 ))
891
892 #--------------------------------------------------------
893 #test_vaccination_course()
894 #test_put_patient_on_schedule()
895 #test_scheduled_vacc()
896 #test_vacc()
897 #test_due_vacc()
898 #test_due_booster()
899
900 #test_get_vaccines()
901 test_get_vaccinations()
902 #test_create_generic_vaccine_sql()
903 #test_write_generic_vaccine_sql(sys.argv[2], sys.argv[3])
904
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Feb 29 02:55:27 2020 | http://epydoc.sourceforge.net |