Package Gnumed :: Package business :: Module gmAllergy
[frames] | no frames]

Source Code for Module Gnumed.business.gmAllergy

  1  """GNUmed allergy related business object. 
  2  """ 
  3  #============================================================ 
  4  __version__ = "$Revision: 1.34 $" 
  5  __author__ = "Carlos Moro <cfmoro1976@yahoo.es>" 
  6  __license__ = "GPL" 
  7   
  8  import types, sys, logging, datetime as pyDT 
  9   
 10   
 11  if __name__ == '__main__': 
 12          sys.path.insert(0, '../../') 
 13  from Gnumed.pycommon import gmPG2, gmI18N, gmBusinessDBObject, gmDateTime 
 14   
 15   
 16  _log = logging.getLogger('gm.domain') 
 17  _log.info(__version__) 
 18  #============================================================ 
 19  # allergy state related code 
 20  #============================================================ 
 21  allergy_states = [ 
 22          None,           # unknown 
 23          0,                      # no allergies 
 24          1                       # some allergies 
 25  ] 
 26  #------------------------------------------------------------ 
27 -def ensure_has_allergy_state(encounter=None):
28 29 args = {'enc': encounter} 30 31 cmd_create = u""" 32 insert into clin.allergy_state (fk_encounter, has_allergy) 33 34 select %(enc)s, NULL 35 where not exists ( 36 select 1 from clin.v_pat_allergy_state 37 where pk_patient = ( 38 select fk_patient from clin.encounter where pk = %(enc)s 39 ) 40 )""" 41 42 cmd_search = u""" 43 select pk_allergy_state from clin.v_pat_allergy_state 44 where pk_patient = ( 45 select fk_patient from clin.encounter where pk = %(enc)s 46 )""" 47 48 rows, idx = gmPG2.run_rw_queries ( 49 queries = [ 50 {'cmd': cmd_create, 'args': args}, 51 {'cmd': cmd_search, 'args': args} 52 ], 53 return_data = True 54 ) 55 56 return cAllergyState(aPK_obj = rows[0][0])
57 #------------------------------------------------------------
58 -class cAllergyState(gmBusinessDBObject.cBusinessDBObject):
59 """Represents the allergy state of one patient.""" 60 61 _cmd_fetch_payload = u"select * from clin.v_pat_allergy_state where pk_allergy_state = %s" 62 _cmds_store_payload = [ 63 u"""update clin.allergy_state set 64 last_confirmed = %(last_confirmed)s, 65 has_allergy = %(has_allergy)s, 66 comment = %(comment)s 67 where 68 pk = %(pk_allergy_state)s and 69 xmin = %(xmin_allergy_state)s""", 70 u"""select xmin_allergy_state from clin.v_pat_allergy_state where pk_allergy_state = %(pk_allergy_state)s""" 71 ] 72 _updatable_fields = [ 73 'last_confirmed', # special value u'now' will set to datetime.datetime.now() in the local time zone 74 'has_allergy', # verified against allergy_states (see above) 75 'comment' # u'' maps to None / NULL 76 ] 77 #-------------------------------------------------------- 78 # properties 79 #--------------------------------------------------------
80 - def _get_as_string(self):
81 if self._payload[self._idx['has_allergy']] is None: 82 return _('unknown allergy state') 83 if self._payload[self._idx['has_allergy']] == 0: 84 return _('no known allergies') 85 if self._payload[self._idx['has_allergy']] == 1: 86 return _('*does* have allergies') 87 _log.error('unknown allergy state [%s]', self._payload[self._idx['has_allergy']]) 88 return _('ERROR: unknown allergy state [%s]') % self._payload[self._idx['has_allergy']]
89
90 - def _set_string(self, value):
91 raise AttributeError('invalid to set allergy state string')
92 93 state_string = property(_get_as_string, _set_string) 94 #--------------------------------------------------------
95 - def _get_as_symbol(self):
96 if self._payload[self._idx['has_allergy']] is None: 97 if self._payload[self._idx['comment']] is None: 98 return u'?' 99 else: 100 return u'?!' 101 if self._payload[self._idx['has_allergy']] == 0: 102 if self._payload[self._idx['comment']] is None: 103 return u'\u2300' 104 else: 105 return u'\u2300!' 106 if self._payload[self._idx['has_allergy']] == 1: 107 return '!' 108 _log.error('unknown allergy state [%s]', self._payload[self._idx['has_allergy']]) 109 return _('ERROR: unknown allergy state [%s]') % self._payload[self._idx['has_allergy']]
110
111 - def _set_symbol(self, value):
112 raise AttributeError('invalid to set allergy state symbol')
113 114 state_symbol = property(_get_as_symbol, _set_symbol) 115 #--------------------------------------------------------
116 - def __setitem__(self, attribute, value):
117 if attribute == u'comment': 118 if value is not None: 119 if value.strip() == u'': 120 value = None 121 122 elif attribute == u'last_confirmed': 123 if value == u'now': 124 value = pyDT.datetime.now(tz = gmDateTime.gmCurrentLocalTimezone) 125 126 elif attribute == u'has_allergy': 127 if value not in allergy_states: 128 raise ValueError('invalid allergy state [%s]' % value) 129 130 gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
131 #============================================================
132 -class cAllergy(gmBusinessDBObject.cBusinessDBObject):
133 """Represents one allergy item. 134 135 Actually, those things are really things to *avoid*. 136 Allergy is just one of several reasons for that. 137 See Adrian's post on gm-dev. 138 139 Another word might be Therapeutic Precautions. 140 """ 141 _cmd_fetch_payload = u"SELECT * FROM clin.v_pat_allergies WHERE pk_allergy = %s" 142 _cmds_store_payload = [ 143 u"""UPDATE clin.allergy SET 144 clin_when = %(date)s, 145 substance = %(substance)s, 146 substance_code = %(substance_code)s, 147 generics = %(generics)s, 148 allergene = %(allergene)s, 149 atc_code = %(atc_code)s, 150 fk_type = %(pk_type)s, 151 generic_specific = %(generic_specific)s::boolean, 152 definite = %(definite)s::boolean, 153 narrative = %(reaction)s 154 WHERE 155 pk = %(pk_allergy)s AND 156 xmin = %(xmin_allergy)s""", 157 u"""SELECT xmin_allergy FROM clin.v_pat_allergies WHERE pk_allergy=%(pk_allergy)s""" 158 ] 159 _updatable_fields = [ 160 'date', 161 'substance', 162 'substance_code', 163 'generics', 164 'allergene', 165 'atc_code', 166 'pk_type', 167 'generic_specific', 168 'definite', 169 'reaction' 170 ] 171 #--------------------------------------------------------
172 - def __setitem__(self, attribute, value):
173 if attribute == 'pk_type': 174 if value in ['allergy', 'sensitivity']: 175 cmd = u'select pk from clin._enum_allergy_type where value=%s' 176 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [value]}]) 177 value = rows[0][0] 178 179 gmBusinessDBObject.cBusinessDBObject.__setitem__(self, attribute, value)
180 #============================================================ 181 # convenience functions 182 #------------------------------------------------------------
183 -def create_allergy(substance=None, allg_type=None, episode_id=None, encounter_id=None):
184 """Creates a new allergy clinical item. 185 186 substance - allergic substance 187 allg_type - allergy or sensitivity, pk or string 188 encounter_id - encounter's primary key 189 episode_id - episode's primary key 190 """ 191 # sanity checks: 192 # 1) any of the args being None should fail the SQL code 193 # 2) do episode/encounter belong to the same patient ? 194 cmd = u""" 195 select pk_patient from clin.v_pat_episodes where pk_episode=%s 196 union 197 select fk_patient from clin.encounter where pk=%s""" 198 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [episode_id, encounter_id]}]) 199 200 if len(rows) == 0: 201 raise ValueError('error checking episode [%s] <-> encounter [%s] consistency' % (episode_id, encounter_id)) 202 203 if len(rows) > 1: 204 raise ValueError('episode [%s] and encounter [%s] belong to different patients !?!' % (episode_id, encounter_id)) 205 206 pat_id = rows[0][0] 207 208 cmd = u'select pk_allergy from clin.v_pat_allergies where pk_patient=%(pat)s and substance=%(substance)s' 209 args = {'pat': pat_id, 'substance': substance} 210 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}]) 211 if len(rows) > 0: 212 # don't implicitely change existing data 213 return cAllergy(aPK_obj = rows[0][0]) 214 215 # insert new allergy 216 queries = [] 217 218 if type(allg_type) == types.IntType: 219 cmd = u""" 220 insert into clin.allergy (fk_type, fk_encounter, fk_episode, substance) 221 values (%s, %s, %s, %s)""" 222 else: 223 cmd = u""" 224 insert into clin.allergy (fk_type, fk_encounter, fk_episode, substance) 225 values ((select pk from clin._enum_allergy_type where value = %s), %s, %s, %s)""" 226 queries.append({'cmd': cmd, 'args': [allg_type, encounter_id, episode_id, substance]}) 227 228 cmd = u"select currval('clin.allergy_id_seq')" 229 queries.append({'cmd': cmd}) 230 231 rows, idx = gmPG2.run_rw_queries(queries=queries, return_data=True) 232 allergy = cAllergy(aPK_obj = rows[0][0]) 233 234 return allergy
235 #============================================================ 236 # main - unit testing 237 #------------------------------------------------------------ 238 if __name__ == '__main__': 239 240 allg = cAllergy(aPK_obj=1) 241 print allg 242 fields = allg.get_fields() 243 for field in fields: 244 print field, ':', allg[field] 245 print "updatable:", allg.get_updatable_fields() 246 enc_id = allg['pk_encounter'] 247 epi_id = allg['pk_episode'] 248 status, allg = create_allergy ( 249 substance = 'test substance', 250 allg_type=1, 251 episode_id = epi_id, 252 encounter_id = enc_id 253 ) 254 print allg 255 allg['reaction'] = 'hehehe' 256 status, data = allg.save_payload() 257 print 'status:', status 258 print 'data:', data 259 print allg 260 261 #============================================================ 262