| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
2 """GNUmed auto hints middleware.
3
4 This should eventually end up in a class cPractice.
5 """
6 #============================================================
7 __license__ = "GPL"
8 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
9
10
11 import sys
12 import logging
13
14
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17 from Gnumed.pycommon import gmPG2
18 from Gnumed.pycommon import gmBusinessDBObject
19 from Gnumed.pycommon import gmTools
20 from Gnumed.pycommon import gmDateTime
21
22 from Gnumed.business import gmStaff
23
24 _log = logging.getLogger('gm.hints')
25
26 #============================================================
27 # dynamic hints API
28 #------------------------------------------------------------
29 _SQL_get_dynamic_hints = "SELECT * FROM ref.v_auto_hints WHERE %s"
30
32 """Represents dynamic hints to be run against the database."""
33
34 _cmd_fetch_payload = _SQL_get_dynamic_hints % "pk_auto_hint = %s"
35 _cmds_store_payload = [
36 """UPDATE ref.auto_hint SET
37 query = gm.nullify_empty_string(%(query)s),
38 recommendation_query = gm.nullify_empty_string(%(recommendation_query)s),
39 title = gm.nullify_empty_string(%(title)s),
40 hint = gm.nullify_empty_string(%(hint)s),
41 url = gm.nullify_empty_string(%(url)s),
42 source = gm.nullify_empty_string(%(source)s),
43 is_active = %(is_active)s,
44 popup_type = %(popup_type)s,
45 highlight_as_priority = %(highlight_as_priority)s
46 WHERE
47 pk = %(pk_auto_hint)s
48 AND
49 xmin = %(xmin_auto_hint)s
50 RETURNING
51 xmin AS xmin_auto_hint
52 """
53 ]
54 _updatable_fields = [
55 'query',
56 'recommendation_query',
57 'title',
58 'hint',
59 'url',
60 'source',
61 'is_active',
62 'popup_type',
63 'highlight_as_priority'
64 ]
65 #--------------------------------------------------------
67 return self.format(include_sql = True).split('\n')
68
69 #--------------------------------------------------------
71 txt = '%s [#%s]\n' % (
72 gmTools.bool2subst(self._payload[self._idx['is_active']], _('Active clinical hint'), _('Inactive clinical hint')),
73 self._payload[self._idx['pk_auto_hint']]
74 )
75 txt += '\n'
76 txt += self._payload[self._idx['title']]
77 txt += '\n'
78 txt += '\n'
79 txt += _('Source: %s\n') % self._payload[self._idx['source']]
80 txt += _('Language: %s\n') % self._payload[self._idx['lang']]
81 txt += '\n'
82 txt += gmTools.wrap(self._payload[self._idx['hint']], width = 50, initial_indent = ' ', subsequent_indent = ' ')
83 txt += '\n'
84 txt += '\n'
85 if self._payload[self._idx['recommendation']] is not None:
86 txt += gmTools.wrap(self._payload[self._idx['recommendation']], width = 50, initial_indent = ' ', subsequent_indent = ' ')
87 txt += '\n'
88 txt += '\n'
89 txt += gmTools.wrap (
90 gmTools.coalesce(self._payload[self._idx['url']], ''),
91 width = 50,
92 initial_indent = ' ',
93 subsequent_indent = ' '
94 )
95 txt += '\n'
96 if include_sql:
97 txt += '\n'
98 txt += gmTools.wrap(self._payload[self._idx['query']], width = 50, initial_indent = ' ', subsequent_indent = ' ')
99 txt += '\n'
100 if self._payload[self._idx['recommendation_query']] is not None:
101 txt += '\n'
102 txt += gmTools.wrap(self._payload[self._idx['recommendation_query']], width = 50, initial_indent = ' ', subsequent_indent = ' ')
103 txt += '\n'
104 if self._payload[self._idx['rationale4suppression']] is not None:
105 txt += '\n'
106 txt += _('Rationale for suppression:')
107 txt += '\n'
108 txt += gmTools.wrap(self._payload[self._idx['rationale4suppression']], width = 50, initial_indent = ' ', subsequent_indent = ' ')
109 txt += '\n'
110 return txt
111
112 #--------------------------------------------------------
114 return suppress_dynamic_hint (
115 pk_hint = self._payload[self._idx['pk_auto_hint']],
116 pk_encounter = pk_encounter,
117 rationale = rationale
118 )
119 #--------------------------------------------------------
121 return invalidate_hint_suppression (
122 pk_hint = self._payload[self._idx['pk_auto_hint']],
123 pk_encounter = pk_encounter
124 )
125
126 #------------------------------------------------------------
128 if order_by is None:
129 order_by = 'TRUE'
130 else:
131 order_by = 'TRUE ORDER BY %s' % order_by
132 cmd = _SQL_get_dynamic_hints % order_by
133 rows, idx = gmPG2.run_ro_queries(link_obj = link_obj, queries = [{'cmd': cmd}], get_col_idx = True)
134 if return_pks:
135 return [ r['pk_auto_hint'] for r in rows ]
136 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_auto_hint'}) for r in rows ]
137
138 #------------------------------------------------------------
140 args = {
141 'query': query,
142 'title': title,
143 'hint': hint,
144 'source': source,
145 'usr': gmStaff.gmCurrentProvider()['db_user']
146 }
147 cmd = """
148 INSERT INTO ref.auto_hint (
149 query,
150 title,
151 hint,
152 source,
153 lang
154 ) VALUES (
155 gm.nullify_empty_string(%(query)s),
156 gm.nullify_empty_string(%(title)s),
157 gm.nullify_empty_string(%(hint)s),
158 gm.nullify_empty_string(%(source)s),
159 i18n.get_curr_lang(%(usr)s)
160 )
161 RETURNING pk
162 """
163 rows, idx = gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = True)
164 return cDynamicHint(aPK_obj = rows[0]['pk'], link_obj = link_obj)
165
166 #------------------------------------------------------------
168 args = {'pk': pk_hint}
169 cmd = "DELETE FROM ref.auto_hint WHERE pk = %(pk)s"
170 gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}])
171 return True
172
173 #------------------------------------------------------------
175 conn = gmPG2.get_connection()
176 curs = conn.cursor()
177 curs.callproc('clin.get_hints_for_patient', [pk_identity])
178 rows = curs.fetchall()
179 idx = gmPG2.get_col_indices(curs)
180 curs.close()
181 conn.rollback()
182
183 applying_rows = []
184 for row in rows:
185 if row['rationale4suppression'] is None:
186 applying_rows.append(row)
187 continue
188 if row['rationale4suppression'].startswith('magic_tag::'):
189 _log.debug('hint with magic tag: %s', row['rationale4suppression'])
190 if 'suppression_needs_invalidation' in row['rationale4suppression']:
191 _log.debug('database asks for invalidation of suppression of hint [%s]', row)
192 if pk_encounter is not None:
193 invalidate_hint_suppression(pk_hint = row['pk_auto_hint'], pk_encounter = pk_encounter)
194 if 'does_not_apply' in row['rationale4suppression']:
195 continue
196 # we would need to reload the relevant hint at this time,
197 # however currently, only hints which do not apply ask
198 # for invalidation of suppression
199 applying_rows.append(row)
200
201 return [ cDynamicHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_auto_hint'}) for r in applying_rows ]
202
203 #------------------------------------------------------------
205 args = {
206 'hint': pk_hint,
207 'rationale': rationale,
208 'enc': pk_encounter
209 }
210 cmd = """
211 DELETE FROM clin.suppressed_hint
212 WHERE
213 fk_hint = %(hint)s
214 AND
215 fk_encounter IN (
216 SELECT pk FROM clin.encounter WHERE fk_patient = (
217 SELECT fk_patient FROM clin.encounter WHERE pk = %(enc)s
218 )
219 )
220 """
221 queries = [{'cmd': cmd, 'args': args}]
222 cmd = """
223 INSERT INTO clin.suppressed_hint (
224 fk_encounter,
225 fk_hint,
226 rationale,
227 md5_sum
228 ) VALUES (
229 %(enc)s,
230 %(hint)s,
231 %(rationale)s,
232 (SELECT r_vah.md5_sum FROM ref.v_auto_hints r_vah WHERE r_vah.pk_auto_hint = %(hint)s)
233 )
234 """
235 queries.append({'cmd': cmd, 'args': args})
236 gmPG2.run_rw_queries(queries = queries)
237 return True
238
239 #------------------------------------------------------------
240 # suppressed dynamic hints
241 #------------------------------------------------------------
242 _SQL_get_suppressed_hints = "SELECT * FROM clin.v_suppressed_hints WHERE %s"
243
245 """Represents suppressed dynamic hints per patient."""
246
247 _cmd_fetch_payload = _SQL_get_suppressed_hints % "pk_suppressed_hint = %s"
248 _cmds_store_payload = []
249 _updatable_fields = []
250 #--------------------------------------------------------
252 txt = '%s [#%s]\n' % (
253 gmTools.bool2subst(self._payload[self._idx['is_active']], _('Suppressed active dynamic hint'), _('Suppressed inactive dynamic hint')),
254 self._payload[self._idx['pk_suppressed_hint']]
255 )
256 txt += '\n'
257 txt += '%s\n\n' % self._payload[self._idx['title']]
258 txt += _('Suppressed by: %s\n') % self._payload[self._idx['suppressed_by']]
259 txt += _('Suppressed at: %s\n') % gmDateTime.pydt_strftime(self._payload[self._idx['suppressed_when']], '%Y %b %d')
260 txt += _('Hint #: %s\n') % self._payload[self._idx['pk_hint']]
261 txt += _('Patient #: %s\n') % self._payload[self._idx['pk_identity']]
262 txt += _('MD5 (currently): %s\n') % self._payload[self._idx['md5_hint']]
263 txt += _('MD5 (at suppression): %s\n') % self._payload[self._idx['md5_suppressed']]
264 txt += _('Source: %s\n') % self._payload[self._idx['source']]
265 txt += _('Language: %s\n') % self._payload[self._idx['lang']]
266 txt += '\n'
267 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['hint']], width = 50, initial_indent = ' ', subsequent_indent = ' ')
268 txt += '\n'
269 if self._payload[self._idx['recommendation']] is not None:
270 txt += '\n'
271 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['recommendation']], width = 50, initial_indent = ' ', subsequent_indent = ' ')
272 txt += '\n'
273 txt += '%s\n' % gmTools.wrap (
274 gmTools.coalesce(self._payload[self._idx['url']], ''),
275 width = 50,
276 initial_indent = ' ',
277 subsequent_indent = ' '
278 )
279 txt += '\n'
280 txt += '%s\n' % gmTools.wrap(self._payload[self._idx['query']], width = 50, initial_indent = ' ', subsequent_indent = ' ')
281 return txt
282
283 #------------------------------------------------------------
285 args = {'pat': pk_identity}
286 if pk_identity is None:
287 where = 'true'
288 else:
289 where = "pk_identity = %(pat)s"
290 if order_by is None:
291 order_by = ''
292 else:
293 order_by = ' ORDER BY %s' % order_by
294 cmd = (_SQL_get_suppressed_hints % where) + order_by
295 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
296 if return_pks:
297 return [ r['pk_suppressed_hint'] for r in rows ]
298 return [ cSuppressedHint(row = {'data': r, 'idx': idx, 'pk_field': 'pk_suppressed_hint'}) for r in rows ]
299
300 #------------------------------------------------------------
302 args = {'pk': pk_suppressed_hint}
303 cmd = "DELETE FROM clin.suppressed_hint WHERE pk = %(pk)s"
304 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
305 return True
306
307 #------------------------------------------------------------
309 _log.debug('invalidating suppression of hint #%s', pk_hint)
310 args = {
311 'pk_hint': pk_hint,
312 'enc': pk_encounter,
313 'fake_md5': '***INVALIDATED***' # only needs to NOT match ANY md5 sum
314 }
315 cmd = """
316 UPDATE clin.suppressed_hint SET
317 fk_encounter = %(enc)s,
318 md5_sum = %(fake_md5)s
319 WHERE
320 pk = (
321 SELECT pk_suppressed_hint
322 FROM clin.v_suppressed_hints
323 WHERE
324 pk_hint = %(pk_hint)s
325 AND
326 pk_identity = (
327 SELECT fk_patient FROM clin.encounter WHERE pk = %(enc)s
328 )
329 )
330 """
331 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
332 return True
333
334 #============================================================
335 if __name__ == '__main__':
336
337 if len(sys.argv) < 2:
338 sys.exit()
339
340 if sys.argv[1] != 'test':
341 sys.exit()
342
343 from Gnumed.pycommon import gmI18N
344
345 gmI18N.activate_locale()
346 gmI18N.install_domain()
347
348 #---------------------------------------
350 # for row in get_dynamic_hints():
351 # print row
352 for row in get_hints_for_patient(pk_identity = 12):
353 print(row)
354 #---------------------------------------
355 test_auto_hints()
356
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Feb 29 02:55:27 2020 | http://epydoc.sourceforge.net |