| Trees | Indices | Help |
|
|---|
|
|
1 """GnuMed allergy related business object.
2 """
3 #============================================================
4 # $Source: /cvsroot/gnumed/gnumed/gnumed/client/business/gmAllergy.py,v $
5 # $Id: gmAllergy.py,v 1.34 2009/06/29 14:49:42 ncq Exp $
6 __version__ = "$Revision: 1.34 $"
7 __author__ = "Carlos Moro <cfmoro1976@yahoo.es>"
8 __license__ = "GPL"
9
10 import types, sys, logging, datetime as pyDT
11
12
13 if __name__ == '__main__':
14 sys.path.insert(0, '../../')
15 from Gnumed.pycommon import gmPG2, gmI18N, gmBusinessDBObject, gmDateTime
16
17
18 _log = logging.getLogger('gm.domain')
19 _log.info(__version__)
20 #============================================================
21 # allergy state related code
22 #============================================================
23 allergy_states = [
24 None, # unknown
25 0, # no allergies
26 1 # some allergies
27 ]
28 #------------------------------------------------------------
30
31 args = {'enc': encounter}
32
33 cmd_create = u"""
34 insert into clin.allergy_state (fk_encounter, has_allergy)
35
36 select %(enc)s, NULL
37 where not exists (
38 select 1 from clin.v_pat_allergy_state
39 where pk_patient = (
40 select fk_patient from clin.encounter where pk = %(enc)s
41 )
42 )"""
43
44 cmd_search = u"""
45 select pk_allergy_state from clin.v_pat_allergy_state
46 where pk_patient = (
47 select fk_patient from clin.encounter where pk = %(enc)s
48 )"""
49
50 rows, idx = gmPG2.run_rw_queries (
51 queries = [
52 {'cmd': cmd_create, 'args': args},
53 {'cmd': cmd_search, 'args': args}
54 ],
55 return_data = True
56 )
57
58 return cAllergyState(aPK_obj = rows[0][0])
59 #------------------------------------------------------------
61 """Represents the allergy state of one patient."""
62
63 _cmd_fetch_payload = u"select * from clin.v_pat_allergy_state where pk_allergy_state = %s"
64 _cmds_store_payload = [
65 u"""update clin.allergy_state set
66 last_confirmed = %(last_confirmed)s,
67 has_allergy = %(has_allergy)s,
68 comment = %(comment)s
69 where
70 pk = %(pk_allergy_state)s and
71 xmin = %(xmin_allergy_state)s""",
72 u"""select xmin_allergy_state from clin.v_pat_allergy_state where pk_allergy_state = %(pk_allergy_state)s"""
73 ]
74 _updatable_fields = [
75 'last_confirmed', # special value u'now' will set to datetime.datetime.now() in the local time zone
76 'has_allergy', # verified against allergy_states (see above)
77 'comment' # u'' maps to None / NULL
78 ]
79 #--------------------------------------------------------
80 # properties
81 #--------------------------------------------------------
83 if self._payload[self._idx['has_allergy']] is None:
84 return _('unknown allergy state')
85 if self._payload[self._idx['has_allergy']] == 0:
86 return _('no known allergies')
87 if self._payload[self._idx['has_allergy']] == 1:
88 return _('*does* have allergies')
89 _log.error('unknown allergy state [%s]', self._payload[self._idx['has_allergy']])
90 return _('ERROR: unknown allergy state [%s]') % self._payload[self._idx['has_allergy']]
91
94
95 state_string = property(_get_as_string, _set_string)
96 #--------------------------------------------------------
98 if self._payload[self._idx['has_allergy']] is None:
99 if self._payload[self._idx['comment']] is None:
100 return u'?'
101 else:
102 return u'?!'
103 if self._payload[self._idx['has_allergy']] == 0:
104 if self._payload[self._idx['comment']] is None:
105 return u'\u2300'
106 else:
107 return u'\u2300!'
108 if self._payload[self._idx['has_allergy']] == 1:
109 return '!'
110 _log.error('unknown allergy state [%s]', self._payload[self._idx['has_allergy']])
111 return _('ERROR: unknown allergy state [%s]') % self._payload[self._idx['has_allergy']]
112
115
116 state_symbol = property(_get_as_symbol, _set_symbol)
117 #--------------------------------------------------------
119 if attribute == u'comment':
120 if value is not None:
121 if value.strip() == u'':
122 value = None
123
124 elif attribute == u'last_confirmed':
125 if value == u'now':
126 value = pyDT.datetime.now(tz = gmDateTime.gmCurrentLocalTimezone)
127
128 elif attribute == u'has_allergy':
129 if value not in allergy_states:
130 raise ValueError('invalid allergy state [%s]' % value)
131
132 gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
133 #============================================================
135 """Represents one allergy item.
136
137 Actually, those things are really things to *avoid*.
138 Allergy is just one of several reasons for that.
139 See Adrian's post on gm-dev.
140
141 Another word might be Therapeutic Precautions.
142 """
143 _cmd_fetch_payload = u"select * from clin.v_pat_allergies where pk_allergy=%s"
144 _cmds_store_payload = [
145 u"""update clin.allergy set
146 clin_when=%(date)s,
147 substance=%(substance)s,
148 substance_code=%(substance_code)s,
149 generics=%(generics)s,
150 allergene=%(allergene)s,
151 atc_code=%(atc_code)s,
152 fk_type=%(pk_type)s,
153 generic_specific=%(generic_specific)s::boolean,
154 definite=%(definite)s::boolean,
155 narrative=%(reaction)s
156 where
157 pk=%(pk_allergy)s and
158 xmin=%(xmin_allergy)s""",
159 u"""select xmin_allergy from clin.v_pat_allergies where pk_allergy=%(pk_allergy)s"""
160 ]
161 _updatable_fields = [
162 'date',
163 'substance',
164 'substance_code',
165 'generics',
166 'allergene',
167 'atc_code',
168 'pk_type',
169 'generic_specific',
170 'definite',
171 'reaction'
172 ]
173 #--------------------------------------------------------
175 if attribute == 'pk_type':
176 if value in ['allergy', 'sensitivity']:
177 cmd = u'select pk from clin._enum_allergy_type where value=%s'
178 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [value]}])
179 value = rows[0][0]
180
181 gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
182 #============================================================
183 # convenience functions
184 #------------------------------------------------------------
186 """Creates a new allergy clinical item.
187
188 substance - allergic substance
189 allg_type - allergy or sensitivity, pk or string
190 encounter_id - encounter's primary key
191 episode_id - episode's primary key
192 """
193 # sanity checks:
194 # 1) any of the args being None should fail the SQL code
195 # 2) do episode/encounter belong to the same patient ?
196 cmd = u"""
197 select pk_patient from clin.v_pat_episodes where pk_episode=%s
198 union
199 select fk_patient from clin.encounter where pk=%s"""
200 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [episode_id, encounter_id]}])
201
202 if len(rows) == 0:
203 raise ValueError('error checking episode [%s] <-> encounter [%s] consistency' % (episode_id, encounter_id))
204
205 if len(rows) > 1:
206 raise ValueError('episode [%s] and encounter [%s] belong to different patients !?!' % (episode_id, encounter_id))
207
208 pat_id = rows[0][0]
209
210 cmd = u'select pk_allergy from clin.v_pat_allergies where pk_patient=%(pat)s and substance=%(substance)s'
211 args = {'pat': pat_id, 'substance': substance}
212 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}])
213 if len(rows) > 0:
214 # don't implicitely change existing data
215 return cAllergy(aPK_obj = rows[0][0])
216
217 # insert new allergy
218 queries = []
219
220 if type(allg_type) == types.IntType:
221 cmd = u"""
222 insert into clin.allergy (fk_type, fk_encounter, fk_episode, substance)
223 values (%s, %s, %s, %s)"""
224 else:
225 cmd = u"""
226 insert into clin.allergy (fk_type, fk_encounter, fk_episode, substance)
227 values ((select pk from clin._enum_allergy_type where value = %s), %s, %s, %s)"""
228 queries.append({'cmd': cmd, 'args': [allg_type, encounter_id, episode_id, substance]})
229
230 cmd = u"select currval('clin.allergy_id_seq')"
231 queries.append({'cmd': cmd})
232
233 rows, idx = gmPG2.run_rw_queries(queries=queries, return_data=True)
234 allergy = cAllergy(aPK_obj = rows[0][0])
235
236 return allergy
237 #============================================================
238 # main - unit testing
239 #------------------------------------------------------------
240 if __name__ == '__main__':
241
242 allg = cAllergy(aPK_obj=1)
243 print allg
244 fields = allg.get_fields()
245 for field in fields:
246 print field, ':', allg[field]
247 print "updatable:", allg.get_updatable_fields()
248 enc_id = allg['pk_encounter']
249 epi_id = allg['pk_episode']
250 status, allg = create_allergy (
251 substance = 'test substance',
252 allg_type=1,
253 episode_id = epi_id,
254 encounter_id = enc_id
255 )
256 print allg
257 allg['reaction'] = 'hehehe'
258 status, data = allg.save_payload()
259 print 'status:', status
260 print 'data:', data
261 print allg
262 #============================================================
263 # $Log: gmAllergy.py,v $
264 # Revision 1.34 2009/06/29 14:49:42 ncq
265 # - improved wording of allergy state
266 #
267 # Revision 1.33 2009/02/20 15:41:24 ncq
268 # - fix ensure_has_allergy_state
269 #
270 # Revision 1.32 2008/10/22 12:03:46 ncq
271 # - better documentation
272 # - better allergy state symbols
273 # - improved __setitem__ on allergy state
274 #
275 # Revision 1.31 2008/10/12 15:10:05 ncq
276 # - allergic -> allergy
277 #
278 # Revision 1.30 2008/10/12 15:02:43 ncq
279 # - no more allergy state -1
280 # - ensure_has_allergic_state()
281 # - cAllergyState
282 #
283 # Revision 1.29 2008/01/30 13:34:49 ncq
284 # - switch to std lib logging
285 #
286 # Revision 1.28 2007/10/25 12:17:28 ncq
287 # - robustify stringification of allergic state
288 #
289 # Revision 1.27 2007/08/20 14:17:59 ncq
290 # - note on what an "allergy" really is to capture Adrian Midgleys input
291 #
292 # Revision 1.26 2007/03/26 16:48:34 ncq
293 # - various id -> pk/fk type fixes
294 #
295 # Revision 1.25 2007/03/21 08:09:07 ncq
296 # - add allergic_states
297 # - add allergic_state2str()
298 #
299 # Revision 1.24 2007/03/18 12:54:39 ncq
300 # - allow string and integer for setting pk_type on allergy
301 #
302 # Revision 1.24 2007/03/12 12:23:23 ncq
303 # - error handling now more exception centric
304 #
305 # Revision 1.23 2006/10/28 15:02:24 ncq
306 # - remove superfluous xmin_allergy
307 #
308 # Revision 1.22 2006/10/08 14:27:52 ncq
309 # - convert to cBusinessDBObject
310 # - convert to gmPG2
311 #
312 # Revision 1.21 2006/07/19 20:25:00 ncq
313 # - gmPyCompat.py is history
314 #
315 # Revision 1.20 2005/11/27 12:44:57 ncq
316 # - clinical tables are in schema "clin" now
317 #
318 # Revision 1.19 2005/04/30 13:30:02 sjtan
319 #
320 # id_patient is now pk_patient.
321 #
322 # Revision 1.18 2005/01/02 19:55:30 ncq
323 # - don't need _xmins_refetch_col_pos anymore
324 #
325 # Revision 1.17 2004/12/20 16:45:49 ncq
326 # - gmBusinessDBObject now requires refetching of XMIN after save_payload
327 #
328 # Revision 1.16 2004/12/15 21:52:05 ncq
329 # - improve unit test
330 #
331 # Revision 1.15 2004/11/03 22:32:34 ncq
332 # - support _cmds_lock_rows_for_update in business object base class
333 #
334 # Revision 1.14 2004/10/11 19:42:32 ncq
335 # - add license
336 # - adapt field names
337 # - some cleanup
338 #
339 # Revision 1.13 2004/06/28 12:18:41 ncq
340 # - more id_* -> fk_*
341 #
342 # Revision 1.12 2004/06/26 07:33:54 ncq
343 # - id_episode -> fk/pk_episode
344 #
345 # Revision 1.11 2004/06/14 08:22:10 ncq
346 # - cast to boolean in save payload
347 #
348 # Revision 1.10 2004/06/09 14:32:24 ncq
349 # - remove extraneous ()'s
350 #
351 # Revision 1.9 2004/06/08 00:41:38 ncq
352 # - fix imports, cleanup, improved self-test
353 #
354 # Revision 1.8 2004/06/02 21:47:27 ncq
355 # - improved sanity check in create_allergy() contributed by Carlos
356 #
357 # Revision 1.7 2004/05/30 18:33:28 ncq
358 # - cleanup, create_allergy, done mostly by Carlos
359 #
360 # Revision 1.6 2004/05/12 14:28:52 ncq
361 # - allow dict style pk definition in __init__ for multicolum primary keys (think views)
362 # - self.pk -> self.pk_obj
363 # - __init__(aPKey) -> __init__(aPK_obj)
364 #
365 # Revision 1.5 2004/04/20 13:32:33 ncq
366 # - improved __str__ output
367 #
368 # Revision 1.4 2004/04/20 00:17:55 ncq
369 # - allergies API revamped, kudos to Carlos
370 #
371 # Revision 1.3 2004/04/16 16:17:33 ncq
372 # - test save_payload
373 #
374 # Revision 1.2 2004/04/16 00:00:59 ncq
375 # - Carlos fixes
376 # - save_payload should now work
377 #
378 # Revision 1.1 2004/04/12 22:58:55 ncq
379 # - Carlos sent me this
380 #
381
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Feb 9 04:01:39 2010 | http://epydoc.sourceforge.net |