1
2 """GNUmed provider inbox 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.inbox')
25
26
27
28
29 _SQL_get_inbox_messages = """SELECT * FROM dem.v_message_inbox d_vi WHERE %s"""
30
32
33 _cmd_fetch_payload = _SQL_get_inbox_messages % "pk_inbox_message = %s"
34 _cmds_store_payload = [
35 """
36 UPDATE dem.message_inbox SET
37 fk_staff = %(pk_staff)s,
38 fk_inbox_item_type = %(pk_type)s,
39 comment = gm.nullify_empty_string(%(comment)s),
40 data = gm.nullify_empty_string(%(data)s),
41 importance = %(importance)s,
42 fk_patient = %(pk_patient)s,
43 ufk_context = NULLIF(%(pk_context)s::integer[], ARRAY[NULL::integer]),
44 due_date = %(due_date)s,
45 expiry_date = %(expiry_date)s
46 WHERE
47 pk = %(pk_inbox_message)s
48 AND
49 xmin = %(xmin_message_inbox)s
50 RETURNING
51 pk as pk_inbox_message,
52 xmin as xmin_message_inbox
53 """
54 ]
55 _updatable_fields = [
56 'pk_staff',
57 'pk_type',
58 'comment',
59 'data',
60 'importance',
61 'pk_patient',
62 'pk_context',
63 'due_date',
64 'expiry_date'
65 ]
66
127
129
130 if order_by is None:
131 order_by = '%s ORDER BY due_date, importance DESC, received_when DESC'
132 else:
133 order_by = '%%s ORDER BY %s' % order_by
134
135 args = {'pat': pk_patient}
136 where_parts = [
137 'pk_patient = %(pat)s',
138 'due_date IS NOT NULL'
139 ]
140
141 cmd = "SELECT * FROM dem.v_message_inbox WHERE %s" % (
142 order_by % ' AND '.join(where_parts)
143 )
144 _log.debug('SQL: %s', cmd)
145 _log.debug('args: %s', args)
146 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
147
148 return [ cInboxMessage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_inbox_message'}) for r in rows ]
149
150
152
153 if order_by is None:
154 order_by = '%s ORDER BY due_date, importance DESC, received_when DESC'
155 else:
156 order_by = '%%s ORDER BY %s' % order_by
157
158 args = {'pat': pk_patient}
159 where_parts = [
160 'pk_patient = %(pat)s',
161 'is_overdue IS TRUE'
162 ]
163
164 cmd = "SELECT * FROM dem.v_message_inbox WHERE %s" % (
165 order_by % ' AND '.join(where_parts)
166 )
167 _log.debug('SQL: %s', cmd)
168 _log.debug('args: %s', args)
169 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
170
171 return [ cInboxMessage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_inbox_message'}) for r in rows ]
172
173
174 -def get_relevant_messages(pk_staff=None, pk_patient=None, include_without_provider=False, order_by=None):
175
176 if order_by is None:
177 order_by = '%s ORDER BY importance desc, received_when desc'
178 else:
179 order_by = '%%s ORDER BY %s' % order_by
180
181 args = {}
182 where_parts = []
183
184 if pk_staff is not None:
185 if include_without_provider:
186 where_parts.append('((pk_staff IN (%(staff)s, NULL)) OR (modified_by = (SELECT short_alias FROM dem.staff WHERE pk = %(staff)s)))')
187 else:
188 where_parts.append('((pk_staff = %(staff)s) OR (modified_by = (SELECT short_alias FROM dem.staff WHERE pk = %(staff)s)))')
189 args['staff'] = pk_staff
190
191 if pk_patient is not None:
192 where_parts.append('pk_patient = %(pat)s')
193 args['pat'] = pk_patient
194
195 where_parts.append("""
196 -- messages which have no due date and are not expired
197 ((due_date IS NULL) AND ((expiry_date IS NULL) OR (expiry_date > now())))
198 OR
199 -- messages which are due and not expired
200 ((due_date IS NOT NULL) AND (due_date < now()) AND ((expiry_date IS NULL) OR (expiry_date > now())))
201 """)
202
203 cmd = _SQL_get_inbox_messages % (
204 order_by % ' AND '.join(where_parts)
205 )
206 _log.debug('SQL: %s', cmd)
207 _log.debug('args: %s', args)
208 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
209
210 return [ cInboxMessage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_inbox_message'}) for r in rows ]
211
212
213 -def get_inbox_messages(pk_staff=None, pk_patient=None, include_without_provider=False, exclude_expired=False, expired_only=False, overdue_only=False, unscheduled_only=False, exclude_unscheduled=False, order_by=None):
214
215 if order_by is None:
216 order_by = '%s ORDER BY importance desc, received_when desc'
217 else:
218 order_by = '%%s ORDER BY %s' % order_by
219
220 args = {}
221 where_parts = []
222
223 if pk_staff is not None:
224 if include_without_provider:
225 where_parts.append('((pk_staff IN (%(staff)s, NULL)) OR (modified_by = (SELECT short_alias FROM dem.staff WHERE pk = %(staff)s)))')
226 else:
227 where_parts.append('((pk_staff = %(staff)s) OR (modified_by = (SELECT short_alias FROM dem.staff WHERE pk = %(staff)s)))')
228 args['staff'] = pk_staff
229
230 if pk_patient is not None:
231 where_parts.append('pk_patient = %(pat)s')
232 args['pat'] = pk_patient
233
234 if exclude_expired:
235 where_parts.append('is_expired IS FALSE')
236
237 if expired_only:
238 where_parts.append('is_expired IS TRUE')
239
240 if overdue_only:
241 where_parts.append('is_overdue IS TRUE')
242
243 if unscheduled_only:
244 where_parts.append('due_date IS NULL')
245
246 if exclude_unscheduled:
247 where_parts.append('due_date IS NOT NULL')
248
249 cmd = _SQL_get_inbox_messages % (
250 order_by % ' AND '.join(where_parts)
251 )
252 _log.debug('SQL: %s', cmd)
253 _log.debug('args: %s', args)
254 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True)
255
256 return [ cInboxMessage(row = {'data': r, 'idx': idx, 'pk_field': 'pk_inbox_message'}) for r in rows ]
257
258
259 -def create_inbox_message(message_type=None, subject=None, patient=None, staff=None, message_category='clinical'):
260
261 success, pk_type = gmTools.input2int(initial = message_type)
262 if not success:
263 pk_type = create_inbox_item_type(message_type = message_type, category = message_category)
264
265 cmd = """
266 INSERT INTO dem.message_inbox (
267 fk_staff,
268 fk_patient,
269 fk_inbox_item_type,
270 comment
271 ) VALUES (
272 %(staff)s,
273 %(pat)s,
274 %(type)s,
275 gm.nullify_empty_string(%(subject)s)
276 )
277 RETURNING pk
278 """
279 args = {
280 'staff': staff,
281 'pat': patient,
282 'type': pk_type,
283 'subject': subject
284 }
285 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False)
286
287 return cInboxMessage(aPK_obj = rows[0]['pk'])
288
289
291 args = {'pk': inbox_message}
292 cmd = "DELETE FROM dem.message_inbox WHERE pk = %(pk)s"
293 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
294 return True
295
296
298
299
300 success, pk_cat = gmTools.input2int(initial = category)
301 if not success:
302 args = {'cat': category}
303 cmd = """SELECT COALESCE (
304 (SELECT pk FROM dem.inbox_item_category WHERE _(description) = %(cat)s),
305 (SELECT pk FROM dem.inbox_item_category WHERE description = %(cat)s)
306 ) AS pk"""
307 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
308 if rows[0]['pk'] is None:
309 cmd = "INSERT INTO dem.inbox_item_category (description) VALUES (%(cat)s) RETURNING pk"
310 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
311 pk_cat = rows[0]['pk']
312 else:
313 pk_cat = rows[0]['pk']
314
315
316 args = {'pk_cat': pk_cat, 'type': message_type}
317 cmd = """SELECT COALESCE (
318 (SELECT pk FROM dem.inbox_item_type where fk_inbox_item_category = %(pk_cat)s AND _(description) = %(type)s),
319 (SELECT pk FROM dem.inbox_item_type where fk_inbox_item_category = %(pk_cat)s AND description = %(type)s)
320 ) AS pk"""
321 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
322 if rows[0]['pk'] is None:
323 cmd = """
324 INSERT INTO dem.inbox_item_type (
325 fk_inbox_item_category,
326 description,
327 is_user
328 ) VALUES (
329 %(pk_cat)s,
330 %(type)s,
331 TRUE
332 ) RETURNING pk"""
333 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True)
334
335 return rows[0]['pk']
336
337
340 if provider_id is None:
341 self.__provider_id = gmStaff.gmCurrentProvider()['pk_staff']
342 else:
343 self.__provider_id = provider_id
344
347
348 - def add_message(message_type=None, subject=None, patient=None):
355
356
357
358 - def get_messages(self, pk_patient=None, include_without_provider=False, exclude_expired=False, expired_only=False, overdue_only=False, unscheduled_only=False, exclude_unscheduled=False, order_by=None):
359 return get_inbox_messages (
360 pk_staff = self.__provider_id,
361 pk_patient = pk_patient,
362 include_without_provider = include_without_provider,
363 exclude_expired = exclude_expired,
364 expired_only = expired_only,
365 overdue_only = overdue_only,
366 unscheduled_only = unscheduled_only,
367 exclude_unscheduled = exclude_unscheduled,
368 order_by = order_by
369 )
370
371 messages = property(get_messages, lambda x:x)
372
373
375 return get_relevant_messages (
376 pk_staff = self.__provider_id,
377 pk_patient = pk_patient,
378 include_without_provider = include_without_provider
379 )
380
381
382 if __name__ == '__main__':
383
384 if len(sys.argv) < 2:
385 sys.exit()
386
387 if sys.argv[1] != 'test':
388 sys.exit()
389
390 from Gnumed.pycommon import gmI18N
391
392 gmI18N.activate_locale()
393 gmI18N.install_domain()
394
395
401
405
408
412
413
414
415
416
417
418
419