Package Gnumed :: Package wxpython :: Module gmHospitalStayWidgets
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gmHospitalStayWidgets

  1  """GNUmed hospital stay widgets""" 
  2  #================================================================ 
  3  __author__ = "cfmoro1976@yahoo.es, karsten.hilbert@gmx.net" 
  4  __license__ = "GPL v2 or later" 
  5   
  6  # stdlib 
  7  import sys 
  8  import logging 
  9  import datetime as pydt 
 10   
 11   
 12  # 3rd party 
 13  import wx 
 14   
 15   
 16  # GNUmed 
 17  if __name__ == '__main__': 
 18          sys.path.insert(0, '../../') 
 19  from Gnumed.pycommon import gmI18N 
 20  from Gnumed.pycommon import gmDateTime 
 21  if __name__ == '__main__': 
 22          gmI18N.activate_locale() 
 23          gmI18N.install_domain() 
 24          gmDateTime.init() 
 25   
 26  from Gnumed.pycommon import gmTools 
 27  from Gnumed.pycommon import gmDispatcher 
 28  from Gnumed.pycommon import gmMatchProvider 
 29   
 30  from Gnumed.business import gmEMRStructItems 
 31  from Gnumed.business import gmPerson 
 32   
 33  from Gnumed.wxpython import gmPhraseWheel 
 34  from Gnumed.wxpython import gmListWidgets 
 35  from Gnumed.wxpython import gmEditArea 
 36   
 37   
 38  _log = logging.getLogger('gm.ui') 
 39   
 40  #================================================================ 
 41  # hospitalizations related widgets/functions 
 42  #---------------------------------------------------------------- 
43 -def manage_hospital_stays(parent=None):
44 45 pat = gmPerson.gmCurrentPatient() 46 emr = pat.emr 47 48 if parent is None: 49 parent = wx.GetApp().GetTopWindow() 50 51 #----------------------------------------- 52 def get_tooltip(stay=None): 53 if stay is None: 54 return None 55 return stay.format ( 56 include_procedures = True, 57 include_docs = True 58 )
59 60 #----------------------------------------- 61 def edit(stay=None): 62 return edit_hospital_stay(parent = parent, hospital_stay = stay) 63 64 #----------------------------------------- 65 def delete(stay=None): 66 if gmEMRStructItems.delete_hospital_stay(stay = stay['pk_hospital_stay']): 67 return True 68 gmDispatcher.send ( 69 signal = 'statustext', 70 msg = _('Cannot delete hospitalization.'), 71 beep = True 72 ) 73 return False 74 75 #----------------------------------------- 76 def refresh(lctrl): 77 stays = emr.get_hospital_stays() 78 items = [ 79 [ 80 s['admission'].strftime('%Y-%m-%d'), 81 gmTools.coalesce(s['discharge'], '', function4value = ('strftime', '%Y-%m-%d')), 82 s['episode'], 83 '%s @ %s' % (s['ward'], s['hospital']) 84 ] for s in stays 85 ] 86 lctrl.set_string_items(items = items) 87 lctrl.set_data(data = stays) 88 #----------------------------------------- 89 gmListWidgets.get_choices_from_list ( 90 parent = parent, 91 msg = _("The patient's hospitalizations:\n"), 92 caption = _('Editing hospitalizations ...'), 93 columns = [_('Admission'), _('Discharge'), _('Reason'), _('Hospital')], 94 single_selection = True, 95 edit_callback = edit, 96 new_callback = edit, 97 delete_callback = delete, 98 refresh_callback = refresh, 99 list_tooltip_callback = get_tooltip 100 ) 101 102 #----------------------------------------------------------------
103 -def edit_hospital_stay(parent=None, hospital_stay=None, single_entry=True):
104 ea = cHospitalStayEditAreaPnl(parent, -1) 105 ea.data = hospital_stay 106 ea.mode = gmTools.coalesce(hospital_stay, 'new', 'edit') 107 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = single_entry) 108 dlg.SetTitle(gmTools.coalesce(hospital_stay, _('Adding a hospitalization'), _('Editing a hospitalization'))) 109 if dlg.ShowModal() == wx.ID_OK: 110 dlg.DestroyLater() 111 return True 112 dlg.DestroyLater() 113 return False
114 115 #----------------------------------------------------------------
116 -class cHospitalWardPhraseWheel(gmPhraseWheel.cPhraseWheel):
117 """Phrasewheel to allow selection of a hospitalization."""
118 - def __init__(self, *args, **kwargs):
119 120 gmPhraseWheel.cPhraseWheel.__init__ (self, *args, **kwargs) 121 122 query = """ 123 SELECT data, list_label, field_label FROM ( 124 SELECT DISTINCT ON (data) * FROM (( 125 126 -- already-used org_units 127 SELECT 128 pk_org_unit 129 AS data, 130 ward || ' @ ' || hospital 131 AS list_label, 132 ward || ' @ ' || hospital 133 AS field_label, 134 1 135 AS rank 136 FROM 137 clin.v_hospital_stays 138 WHERE 139 ward %(fragment_condition)s 140 OR 141 hospital %(fragment_condition)s 142 143 ) UNION ALL ( 144 -- wards 145 SELECT 146 pk_org_unit 147 AS data, 148 unit || ' (' || l10n_unit_category || ') @ ' || organization 149 AS list_label, 150 unit || ' @ ' || organization 151 AS field_label, 152 2 153 AS rank 154 FROM 155 dem.v_org_units 156 WHERE 157 unit_category = 'Ward' 158 AND 159 unit %(fragment_condition)s 160 AND 161 NOT EXISTS ( 162 SELECT 1 FROM clin.v_hospital_stays WHERE clin.v_hospital_stays.pk_org_unit = dem.v_org_units.pk_org_unit 163 ) 164 165 ) UNION ALL ( 166 -- hospital units 167 SELECT 168 pk_org_unit 169 AS data, 170 unit || coalesce(' (' || l10n_unit_category || ')', '') || ' @ ' || organization || ' (' || l10n_organization_category || ')' 171 AS list_label, 172 unit || ' @ ' || organization 173 AS field_label, 174 3 175 AS rank 176 FROM 177 dem.v_org_units 178 WHERE 179 unit_category <> 'Ward' 180 AND 181 organization_category = 'Hospital' 182 AND 183 unit %(fragment_condition)s 184 AND 185 NOT EXISTS ( 186 SELECT 1 FROM clin.v_hospital_stays WHERE clin.v_hospital_stays.pk_org_unit = dem.v_org_units.pk_org_unit 187 ) 188 189 ) UNION ALL ( 190 -- any other units 191 SELECT 192 pk_org_unit 193 AS data, 194 unit || coalesce(' (' || l10n_unit_category || ')', '') || ' @ ' || organization || ' (' || l10n_organization_category || ')' 195 AS list_label, 196 unit || ' @ ' || organization 197 AS field_label, 198 3 199 AS rank 200 FROM 201 dem.v_org_units 202 WHERE 203 unit_category <> 'Ward' 204 AND 205 organization_category <> 'Hospital' 206 AND 207 unit %(fragment_condition)s 208 AND 209 NOT EXISTS ( 210 SELECT 1 FROM clin.v_hospital_stays WHERE clin.v_hospital_stays.pk_org_unit = dem.v_org_units.pk_org_unit 211 ) 212 )) AS all_matches 213 ORDER BY data, rank 214 ) AS distinct_matches 215 ORDER BY rank, list_label 216 LIMIT 50 217 """ 218 219 mp = gmMatchProvider.cMatchProvider_SQL2(queries = [query]) 220 mp.setThresholds(2, 4, 6) 221 self.matcher = mp 222 self.selection_only = True
223 224 #----------------------------------------------------------------
225 -class cHospitalStayPhraseWheel(gmPhraseWheel.cPhraseWheel):
226 """Phrasewheel to allow selection of a hospital-type org_unit."""
227 - def __init__(self, *args, **kwargs):
228 229 gmPhraseWheel.cPhraseWheel.__init__ (self, *args, **kwargs) 230 231 ctxt = {'ctxt_pat': {'where_part': '(pk_patient = %(pat)s) AND', 'placeholder': 'pat'}} 232 233 mp = gmMatchProvider.cMatchProvider_SQL2 ( 234 queries = [ 235 """ 236 SELECT 237 pk_hospital_stay, 238 descr 239 FROM ( 240 SELECT DISTINCT ON (pk_hospital_stay) 241 pk_hospital_stay, 242 descr 243 FROM 244 (SELECT 245 pk_hospital_stay, 246 ( 247 to_char(admission, 'YYYY-Mon-DD') 248 || ' (' || ward || ' @ ' || hospital || '):' 249 || episode 250 || coalesce((' (' || health_issue || ')'), '') 251 ) AS descr 252 FROM 253 clin.v_hospital_stays 254 WHERE 255 %(ctxt_pat)s ( 256 hospital %(fragment_condition)s 257 OR 258 ward %(fragment_condition)s 259 OR 260 episode %(fragment_condition)s 261 OR 262 health_issue %(fragment_condition)s 263 ) 264 ) AS the_stays 265 ) AS distinct_stays 266 ORDER BY descr 267 LIMIT 25 268 """ ], 269 context = ctxt 270 ) 271 mp.setThresholds(3, 4, 6) 272 mp.set_context('pat', gmPerson.gmCurrentPatient().ID) 273 274 self.matcher = mp 275 self.selection_only = True
276 277 #---------------------------------------------------------------- 278 from Gnumed.wxGladeWidgets import wxgHospitalStayEditAreaPnl 279
280 -class cHospitalStayEditAreaPnl(wxgHospitalStayEditAreaPnl.wxgHospitalStayEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
281
282 - def __init__(self, *args, **kwargs):
285 286 #---------------------------------------------------------------- 287 # generic Edit Area mixin API 288 #----------------------------------------------------------------
289 - def _valid_for_save(self):
290 291 valid = True 292 293 if self._PRW_episode.GetValue().strip() == '': 294 valid = False 295 self._PRW_episode.display_as_valid(False) 296 self.StatusText = _('Must select an episode or enter a name for a new one. Cannot save hospitalization.') 297 self._PRW_episode.SetFocus() 298 299 if not self._PRW_admission.is_valid_timestamp(empty_is_valid = False): 300 valid = False 301 self.StatusText = _('Missing admission data. Cannot save hospitalization.') 302 self._PRW_admission.SetFocus() 303 304 if self._PRW_discharge.is_valid_timestamp(empty_is_valid = True): 305 if self._PRW_discharge.date is not None: 306 adm = self._PRW_admission.date 307 discharge = self._PRW_discharge.date 308 # normalize for comparison 309 discharge = discharge.replace ( 310 hour = adm.hour, 311 minute = adm.minute, 312 second = adm.second, 313 microsecond = adm.microsecond 314 ) 315 if adm is not None: 316 if discharge == adm: 317 self._PRW_discharge.SetData(discharge + pydt.timedelta(seconds = 1)) 318 elif not self._PRW_discharge.date > self._PRW_admission.date: 319 valid = False 320 self._PRW_discharge.display_as_valid(False) 321 self.StatusText = _('Discharge date must be empty or later than admission. Cannot save hospitalization.') 322 self._PRW_discharge.SetFocus() 323 324 if self._PRW_hospital.GetData() is None: 325 valid = False 326 self._PRW_hospital.display_as_valid(False) 327 self.StatusText = _('Must select a hospital. Cannot save hospitalization.') 328 self._PRW_hospital.SetFocus() 329 else: 330 self._PRW_hospital.display_as_valid(True) 331 332 return (valid is True)
333 #----------------------------------------------------------------
334 - def _save_as_new(self):
335 336 pat = gmPerson.gmCurrentPatient() 337 emr = pat.emr 338 stay = emr.add_hospital_stay(episode = self._PRW_episode.GetData(can_create = True), fk_org_unit = self._PRW_hospital.GetData()) 339 stay['comment'] = self._TCTRL_comment.GetValue().strip() 340 stay['admission'] = self._PRW_admission.GetData() 341 stay['discharge'] = self._PRW_discharge.GetData() 342 stay['comment'] = self._TCTRL_comment.GetValue() 343 stay.save_payload() 344 345 self.data = stay 346 return True
347 #----------------------------------------------------------------
348 - def _save_as_update(self):
349 350 self.data['pk_episode'] = self._PRW_episode.GetData(can_create = True) 351 self.data['pk_org_unit'] = self._PRW_hospital.GetData() 352 self.data['admission'] = self._PRW_admission.GetData() 353 self.data['discharge'] = self._PRW_discharge.GetData() 354 self.data['comment'] = self._TCTRL_comment.GetValue() 355 self.data.save_payload() 356 357 return True
358 #----------------------------------------------------------------
359 - def _refresh_as_new(self):
360 self._PRW_hospital.SetText(value = '', data = None) 361 self._PRW_episode.SetText(value = '') 362 self._PRW_admission.SetText(data = gmDateTime.pydt_now_here()) 363 self._PRW_discharge.SetText() 364 self._TCTRL_comment.SetValue('') 365 self._PRW_hospital.SetFocus()
366 #----------------------------------------------------------------
367 - def _refresh_from_existing(self):
368 self._PRW_hospital.SetText(value = '%s @ %s' % (self.data['ward'], self.data['hospital']), data = self.data['pk_org_unit']) 369 370 if self.data['pk_episode'] is not None: 371 self._PRW_episode.SetText(value = self.data['episode'], data = self.data['pk_episode']) 372 373 self._PRW_admission.SetText(data = self.data['admission']) 374 self._PRW_discharge.SetText(data = self.data['discharge']) 375 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], '')) 376 377 self._PRW_hospital.SetFocus()
378 #----------------------------------------------------------------
380 print("this was not expected to be used in this edit area")
381 382 #================================================================ 383 # main 384 #---------------------------------------------------------------- 385 if __name__ == '__main__': 386 387 if len(sys.argv) < 2: 388 sys.exit() 389 390 if sys.argv[1] != 'test': 391 sys.exit() 392 393 from Gnumed.business import gmPersonSearch 394 from Gnumed.wxpython import gmPatSearchWidgets 395 396 #================================================================ 397 # obtain patient 398 pat = gmPersonSearch.ask_for_patient() 399 if pat is None: 400 print("No patient. Exiting gracefully...") 401 sys.exit(0) 402 gmPatSearchWidgets.set_active_patient(patient=pat) 403 404 #----------------------------------------------------------------
405 - def test_hospital_stay_prw():
406 app = wx.PyWidgetTester(size = (400, 40)) 407 app.SetWidget(cHospitalStayPhraseWheel, id=-1, size=(180,20), pos=(10,20)) 408 app.MainLoop()
409 410 test_hospital_stay_prw() 411