def _refresh_from_existing(self):

        self._TCTRL_subject.SetValue(
            gmTools.coalesce(self.data['comment'], u''))
        self._PRW_type.SetData(data=self.data['pk_type'])

        curr_prov = gmStaff.gmCurrentProvider()
        curr_pat = gmPerson.gmCurrentPatient()

        if curr_prov['pk_staff'] == self.data['pk_staff']:
            self._CHBOX_send_to_me.SetValue(True)
            self._PRW_receiver.Enable(False)
            self._PRW_receiver.SetData(
                data=gmStaff.gmCurrentProvider()['pk_staff'])
        else:
            self._CHBOX_send_to_me.SetValue(False)
            self._PRW_receiver.Enable(True)
            self._PRW_receiver.SetData(data=self.data['pk_staff'])

        self._TCTRL_message.SetValue(gmTools.coalesce(self.data['data'], u''))

        if curr_pat.connected:
            self._CHBOX_active_patient.Enable(True)
            if curr_pat.ID == self.data['pk_patient']:
                self._CHBOX_active_patient.SetValue(True)
                self._PRW_patient.Enable(False)
                self._PRW_patient.person = None
            else:
                self._CHBOX_active_patient.SetValue(False)
                self._PRW_patient.Enable(True)
                if self.data['pk_patient'] is None:
                    self._PRW_patient.person = None
                else:
                    self._PRW_patient.person = gmPerson.cPerson(
                        aPK_obj=self.data['pk_patient'])
        else:
            self._CHBOX_active_patient.Enable(False)
            self._CHBOX_active_patient.SetValue(False)
            self._PRW_patient.Enable(True)
            if self.data['pk_patient'] is None:
                self._PRW_patient.person = None
            else:
                self._PRW_patient.person = gmPerson.cPerson(
                    aPK_obj=self.data['pk_patient'])

        self._PRW_due.SetText(data=self.data['due_date'])
        self._PRW_expiry.SetText(data=self.data['expiry_date'])

        self._RBTN_normal.SetValue(False)
        self._RBTN_high.SetValue(False)
        self._RBTN_low.SetValue(False)
        {
            -1: self._RBTN_low,
            0: self._RBTN_normal,
            1: self._RBTN_high
        }[self.data['importance']].SetValue(True)

        self._TCTRL_subject.SetFocus()
Exemple #2
0
	def _refresh_from_existing(self):

		self._TCTRL_subject.SetValue(gmTools.coalesce(self.data['comment'], u''))
		self._PRW_type.SetData(data = self.data['pk_type'])

		curr_prov = gmStaff.gmCurrentProvider()
		curr_pat = gmPerson.gmCurrentPatient()

		if curr_prov['pk_staff'] == self.data['pk_staff']:
			self._CHBOX_send_to_me.SetValue(True)
			self._PRW_receiver.Enable(False)
			self._PRW_receiver.SetData(data = gmStaff.gmCurrentProvider()['pk_staff'])
		else:
			self._CHBOX_send_to_me.SetValue(False)
			self._PRW_receiver.Enable(True)
			self._PRW_receiver.SetData(data = self.data['pk_staff'])

		self._TCTRL_message.SetValue(gmTools.coalesce(self.data['data'], u''))

		if curr_pat.connected:
			self._CHBOX_active_patient.Enable(True)
			if curr_pat.ID == self.data['pk_patient']:
				self._CHBOX_active_patient.SetValue(True)
				self._PRW_patient.Enable(False)
				self._PRW_patient.person = None
			else:
				self._CHBOX_active_patient.SetValue(False)
				self._PRW_patient.Enable(True)
				if self.data['pk_patient'] is None:
					self._PRW_patient.person = None
				else:
					self._PRW_patient.person = gmPerson.cPerson(aPK_obj = self.data['pk_patient'])
		else:
			self._CHBOX_active_patient.Enable(False)
			self._CHBOX_active_patient.SetValue(False)
			self._PRW_patient.Enable(True)
			if self.data['pk_patient'] is None:
				self._PRW_patient.person = None
			else:
				self._PRW_patient.person = gmPerson.cPerson(aPK_obj = self.data['pk_patient'])

		self._PRW_due.SetText(data = self.data['due_date'])
		self._PRW_expiry.SetText(data = self.data['expiry_date'])

		self._RBTN_normal.SetValue(False)
		self._RBTN_high.SetValue(False)
		self._RBTN_low.SetValue(False)
		{	-1: self._RBTN_low,
			0: self._RBTN_normal,
			1: self._RBTN_high
		}[self.data['importance']].SetValue(True)

		self._TCTRL_subject.SetFocus()
Exemple #3
0
	def _on_delete_focussed_msg(self, evt):
		if self.__focussed_msg['is_virtual']:
			gmDispatcher.send(signal = 'statustext', msg = _('You must deal with the reason for this message to remove it from your inbox.'), beep = True)
			return False

		# if not "to" current provider, then don't delete
		if self.__focussed_msg['pk_staff'] != gmStaff.gmCurrentProvider()['pk_staff']:
			gmDispatcher.send(signal = 'statustext', msg = _('This message can only be deleted by [%s].') % self.__focussed_msg['provider'], beep = True)
			return False

		pk_patient = self.__focussed_msg['pk_patient']
		if pk_patient is not None:
			emr = gmClinicalRecord.cClinicalRecord(aPKey = pk_patient)
			epi = emr.add_episode(episode_name = 'administrative', is_open = False)
			soap_cat = gmTools.bool2subst (
				(self.__focussed_msg['category'] == 'clinical'),
				'u',
				None
			)
			narr = _('Deleted inbox message:\n%s') % self.__focussed_msg.format(with_patient = False)
			emr.add_clin_narrative(note = narr, soap_cat = soap_cat, episode = epi)
			gmDispatcher.send(signal = 'statustext', msg = _('Recorded deletion of inbox message in EMR.'), beep = False)

		if not self.provider.inbox.delete_message(self.__focussed_msg['pk_inbox_message']):
			gmDispatcher.send(signal='statustext', msg=_('Problem removing message from Inbox.'))
			return False

		return True
Exemple #4
0
	def _on_send_to_me_checked(self, event):
		if self._CHBOX_send_to_me.IsChecked():
			self._PRW_receiver.Enable(False)
			self._PRW_receiver.SetData(data = gmStaff.gmCurrentProvider()['pk_staff'])
		else:
			self._PRW_receiver.Enable(True)
			self._PRW_receiver.SetText(value = '', data = None)
    def _save_as_update(self):

        self.data['comment'] = self._TCTRL_subject.GetValue().strip()
        self.data['pk_type'] = self._PRW_type.GetData(can_create=True)

        if self._CHBOX_send_to_me.IsChecked():
            self.data['pk_staff'] = gmStaff.gmCurrentProvider()['pk_staff']
        else:
            self.data['pk_staff'] = self._PRW_receiver.GetData()

        self.data['data'] = self._TCTRL_message.GetValue().strip()

        if self._CHBOX_active_patient.GetValue() is True:
            self.data['pk_patient'] = gmPerson.gmCurrentPatient().ID
        else:
            if self._PRW_patient.person is None:
                self.data['pk_patient'] = None
            else:
                self.data['pk_patient'] = self._PRW_patient.person.ID

        if self._PRW_due.is_valid_timestamp():
            self.data['due_date'] = self._PRW_due.date

        if self._PRW_expiry.is_valid_timestamp():
            self.data['expiry_date'] = self._PRW_expiry.date

        if self._RBTN_normal.GetValue() is True:
            self.data['importance'] = 0
        elif self._RBTN_high.GetValue() is True:
            self.data['importance'] = 1
        else:
            self.data['importance'] = -1

        self.data.save()
        return True
Exemple #6
0
	def _refresh_as_new(self):
		self._TCTRL_subject.SetValue(u'')
		self._PRW_type.SetText(value = u'', data = None)
		self._CHBOX_send_to_me.SetValue(True)
		self._PRW_receiver.Enable(False)
		self._PRW_receiver.SetData(data = gmStaff.gmCurrentProvider()['pk_staff'])
		self._TCTRL_message.SetValue(u'')
		self._PRW_due.SetText(data = None)
		self._PRW_expiry.SetText(data = None)
		self._RBTN_normal.SetValue(True)
		self._RBTN_high.SetValue(False)
		self._RBTN_low.SetValue(False)

		self._PRW_patient.person = None

		if gmPerson.gmCurrentPatient().connected:
			self._CHBOX_active_patient.Enable(True)
			self._CHBOX_active_patient.SetValue(True)
			self._PRW_patient.Enable(False)
		else:
			self._CHBOX_active_patient.Enable(False)
			self._CHBOX_active_patient.SetValue(False)
			self._PRW_patient.Enable(True)

		self._TCTRL_subject.SetFocus()
Exemple #7
0
def create_dynamic_hint(link_obj=None, query=None, title=None, hint=None, source=None):
	args = {
		u'query': query,
		u'title': title,
		u'hint': hint,
		u'source': source,
		u'usr': gmStaff.gmCurrentProvider()['db_user']
	}
	cmd = u"""
		INSERT INTO ref.auto_hint (
			query,
			title,
			hint,
			source,
			lang
		) VALUES (
			gm.nullify_empty_string(%(query)s),
			gm.nullify_empty_string(%(title)s),
			gm.nullify_empty_string(%(hint)s),
			gm.nullify_empty_string(%(source)s),
			i18n.get_curr_lang(%(usr)s)
		)
		RETURNING pk
	"""
	rows, idx = gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = True)
	return cDynamicHint(aPK_obj = rows[0]['pk'], link_obj = link_obj)
Exemple #8
0
	def _save_as_update(self):

		self.data['comment'] = self._TCTRL_subject.GetValue().strip()
		self.data['pk_type'] = self._PRW_type.GetData(can_create = True)

		if self._CHBOX_send_to_me.IsChecked():
			self.data['pk_staff'] = gmStaff.gmCurrentProvider()['pk_staff']
		else:
			self.data['pk_staff'] = self._PRW_receiver.GetData()

		self.data['data'] = self._TCTRL_message.GetValue().strip()

		if self._CHBOX_active_patient.GetValue() is True:
			self.data['pk_patient'] = gmPerson.gmCurrentPatient().ID
		else:
			if self._PRW_patient.person is None:
				self.data['pk_patient'] = None
			else:
				self.data['pk_patient'] = self._PRW_patient.person.ID

		if self._PRW_due.is_valid_timestamp():
			self.data['due_date'] = self._PRW_due.date

		if self._PRW_expiry.is_valid_timestamp():
			self.data['expiry_date'] = self._PRW_expiry.date

		if self._RBTN_normal.GetValue() is True:
			self.data['importance'] = 0
		elif self._RBTN_high.GetValue() is True:
			self.data['importance'] = 1
		else:
			self.data['importance'] = -1

		self.data.save()
		return True
Exemple #9
0
	def _on_delete_focussed_msg(self, evt):
		if self.__focussed_msg['is_virtual']:
			gmDispatcher.send(signal = 'statustext', msg = _('You must deal with the reason for this message to remove it from your inbox.'), beep = True)
			return False

		# if not "to" current provider, then don't delete
		if self.__focussed_msg['pk_staff'] != gmStaff.gmCurrentProvider()['pk_staff']:
			gmDispatcher.send(signal = 'statustext', msg = _('This message can only be deleted by [%s].') % self.__focussed_msg['provider'], beep = True)
			return False

		pk_patient = self.__focussed_msg['pk_patient']
		if pk_patient is not None:
			#emr = gmClinicalRecord.cClinicalRecord(aPKey = pk_patient, allow_user_interaction = False)
			from Gnumed.wxpython import gmChartPullingWidgets
			emr = gmChartPullingWidgets.pull_chart(gmPerson.cPerson(pk_patient))
			if emr is None:
				return False
			epi = emr.add_episode(episode_name = 'administrative', is_open = False)
			soap_cat = gmTools.bool2subst (
				(self.__focussed_msg['category'] == u'clinical'),
				u'U',
				None
			)
			narr = _('Deleted inbox message:\n%s') % self.__focussed_msg.format(with_patient = False)
			emr.add_clin_narrative(note = narr, soap_cat = soap_cat, episode = epi)
			gmDispatcher.send(signal = 'statustext', msg = _('Recorded deletion of inbox message in EMR.'), beep = False)

		if not self.provider.inbox.delete_message(self.__focussed_msg['pk_inbox_message']):
			gmDispatcher.send(signal='statustext', msg=_('Problem removing message from Inbox.'))
			return False

		return True
Exemple #10
0
	def _on_send_to_me_checked(self, event):
		if self._CHBOX_send_to_me.IsChecked():
			self._PRW_receiver.Enable(False)
			self._PRW_receiver.SetData(data = gmStaff.gmCurrentProvider()['pk_staff'])
		else:
			self._PRW_receiver.Enable(True)
			self._PRW_receiver.SetText(value = u'', data = None)
Exemple #11
0
def create_dynamic_hint(link_obj=None, query=None, title=None, hint=None, source=None):
	args = {
		'query': query,
		'title': title,
		'hint': hint,
		'source': source,
		'usr': gmStaff.gmCurrentProvider()['db_user']
	}
	cmd = """
		INSERT INTO ref.auto_hint (
			query,
			title,
			hint,
			source,
			lang
		) VALUES (
			gm.nullify_empty_string(%(query)s),
			gm.nullify_empty_string(%(title)s),
			gm.nullify_empty_string(%(hint)s),
			gm.nullify_empty_string(%(source)s),
			i18n.get_curr_lang(%(usr)s)
		)
		RETURNING pk
	"""
	rows, idx = gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = True)
	return cDynamicHint(aPK_obj = rows[0]['pk'], link_obj = link_obj)
    def _refresh_as_new(self):
        self._TCTRL_subject.SetValue(u'')
        self._PRW_type.SetText(value=u'', data=None)
        self._CHBOX_send_to_me.SetValue(True)
        self._PRW_receiver.Enable(False)
        self._PRW_receiver.SetData(
            data=gmStaff.gmCurrentProvider()['pk_staff'])
        self._TCTRL_message.SetValue(u'')
        self._PRW_due.SetText(data=None)
        self._PRW_expiry.SetText(data=None)
        self._RBTN_normal.SetValue(True)
        self._RBTN_high.SetValue(False)
        self._RBTN_low.SetValue(False)

        self._PRW_patient.person = None

        if gmPerson.gmCurrentPatient().connected:
            self._CHBOX_active_patient.Enable(True)
            self._CHBOX_active_patient.SetValue(True)
            self._PRW_patient.Enable(False)
        else:
            self._CHBOX_active_patient.Enable(False)
            self._CHBOX_active_patient.SetValue(False)
            self._PRW_patient.Enable(True)

        self._TCTRL_subject.SetFocus()
	def _on_delete_focussed_msg(self, evt):
		if self.__focussed_msg['is_virtual']:
			gmDispatcher.send(signal = 'statustext', msg = _('You must deal with the reason for this message to remove it from your inbox.'), beep = True)
			return False

		# message to a certain provider ?
		if self.__focussed_msg['pk_staff'] is not None:
			# do not delete messages to *other* providers
			if self.__focussed_msg['pk_staff'] != gmStaff.gmCurrentProvider()['pk_staff']:
				gmDispatcher.send(signal = 'statustext', msg = _('This message can only be deleted by [%s].') % self.__focussed_msg['provider'], beep = True)
				return False

		pk_patient = self.__focussed_msg['pk_patient']
		if pk_patient is not None:
			emr = gmClinicalRecord.cClinicalRecord(aPKey = pk_patient)
			epi = emr.add_episode(episode_name = 'administrative', is_open = False)
			soap_cat = gmTools.bool2subst (
				(self.__focussed_msg['category'] == 'clinical'),
				'u',
				None
			)
			narr = _('Deleted inbox message:\n%s') % self.__focussed_msg.format(with_patient = False)
			emr.add_clin_narrative(note = narr, soap_cat = soap_cat, episode = epi)
			gmDispatcher.send(signal = 'statustext', msg = _('Recorded deletion of inbox message in EMR.'), beep = False)

		if not self.provider.inbox.delete_message(self.__focussed_msg['pk_inbox_message']):
			gmDispatcher.send(signal='statustext', msg=_('Problem removing message from Inbox.'))
			return False

		return True
Exemple #14
0
 def GetWidget(self, parent):
     # get current workplace name
     workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace
     currUser = gmStaff.gmCurrentProvider()['db_user']
     _log.info("ConfigReg: %s@%s" % (currUser, workplace))
     self._widget = gmConfigEditorPanel(parent, currUser, workplace)
     return self._widget
Exemple #15
0
	def import_fd2gm_file_as_prescription(self, filename=None):

		if filename is None:
			filename = self.__fd2gm_filename

		_log.debug('importing FreeDiams prescription information from [%s]', filename)

		fd2gm_xml = etree.ElementTree()
		fd2gm_xml.parse(filename)

		pdfs = fd2gm_xml.findall('ExtraDatas/Printed')
		if len(pdfs) == 0:
			_log.debug('no PDF prescription files listed')
			return

		fd_filenames = []
		for pdf in pdfs:
			fd_filenames.append(pdf.attrib['file'])

		_log.debug('listed PDF prescription files: %s', fd_filenames)

		docs = self.patient.get_document_folder()
		emr = self.patient.emr

		prescription = docs.add_prescription (
			encounter = emr.active_encounter['pk_encounter'],
			episode = emr.add_episode (
				episode_name = gmMedication.DEFAULT_MEDICATION_HISTORY_EPISODE,
				is_open = False
			)['pk_episode']
		)
		prescription['ext_ref'] = 'FreeDiams'
		prescription.save()
		fd_filenames.append(filename)
		success, msg, parts = prescription.add_parts_from_files(files = fd_filenames)
		if not success:
			_log.error(msg)
			return

		for part in parts:
			part['obj_comment'] = _('copy of printed prescription')
			part.save()

		xml_part = parts[-1]
		xml_part['filename'] = 'freediams-prescription.xml'
		xml_part['obj_comment'] = _('prescription data')
		xml_part.save()

		# are we the intended reviewer ?
		from Gnumed.business.gmStaff import gmCurrentProvider
		me = gmCurrentProvider()
		# if so: auto-sign the prescription
		if xml_part['pk_intended_reviewer'] == me['pk_staff']:
			prescription.set_reviewed(technically_abnormal = False, clinically_relevant = False)
Exemple #16
0
	def import_fd2gm_file_as_prescription(self, filename=None):

		if filename is None:
			filename = self.__fd2gm_filename

		_log.debug('importing FreeDiams prescription information from [%s]', filename)

		fd2gm_xml = etree.ElementTree()
		fd2gm_xml.parse(filename)

		pdfs = fd2gm_xml.findall('ExtraDatas/Printed')
		if len(pdfs) == 0:
			_log.debug('no PDF prescription files listed')
			return

		fd_filenames = []
		for pdf in pdfs:
			fd_filenames.append(pdf.attrib['file'])

		_log.debug('listed PDF prescription files: %s', fd_filenames)

		docs = self.patient.get_document_folder()
		emr = self.patient.emr

		prescription = docs.add_prescription (
			encounter = emr.active_encounter['pk_encounter'],
			episode = emr.add_episode (
				episode_name = DEFAULT_MEDICATION_HISTORY_EPISODE,
				is_open = False
			)['pk_episode']
		)
		prescription['ext_ref'] = 'FreeDiams'
		prescription.save()
		fd_filenames.append(filename)
		success, msg, parts = prescription.add_parts_from_files(files = fd_filenames)
		if not success:
			_log.error(msg)
			return

		for part in parts:
			part['obj_comment'] = _('copy of printed prescription')
			part.save()

		xml_part = parts[-1]
		xml_part['filename'] = 'freediams-prescription.xml'
		xml_part['obj_comment'] = _('prescription data')
		xml_part.save()

		# are we the intended reviewer ?
		from Gnumed.business.gmStaff import gmCurrentProvider
		me = gmCurrentProvider()
		# if so: auto-sign the prescription
		if xml_part['pk_intended_reviewer'] == me['pk_staff']:
			prescription.set_reviewed(technically_abnormal = False, clinically_relevant = False)
Exemple #17
0
 def refresh(lctrl):
     notes = emr.get_clin_narrative(
         encounters=encounters,
         episodes=episodes,
         providers=[gmStaff.gmCurrentProvider()['short_alias']])
     lctrl.set_string_items(items=[[
         narr['date'].strftime('%x %H:%M'), gmSoapDefs.soap_cat2l10n[
             narr['soap_cat']], narr['narrative'].replace(
                 '\n', '/').replace('\r', '/')
     ] for narr in notes])
     lctrl.set_data(data=notes)
Exemple #18
0
	def refresh(lctrl):
		notes = emr.get_clin_narrative (
			encounters = encounters,
			episodes = episodes,
			providers = [ gmStaff.gmCurrentProvider()['short_alias'] ]
		)
		lctrl.set_string_items(items = [
			[	narr['date'].strftime('%x %H:%M'),
				gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
				narr['narrative'].replace('\n', '/').replace('\r', '/')
			] for narr in notes
		])
		lctrl.set_data(data = notes)
Exemple #19
0
	def __init__(self, *args, **kwds):

		wxgProviderInboxPnl.wxgProviderInboxPnl.__init__(self, *args, **kwds)
		gmRegetMixin.cRegetOnPaintMixin.__init__(self)

		self.provider = gmStaff.gmCurrentProvider()
		self.__init_ui()

		cProviderInboxPnl._item_handlers['clinical.review docs'] = self._goto_doc_review
		cProviderInboxPnl._item_handlers['clinical.review results'] = self._goto_measurements_review
		cProviderInboxPnl._item_handlers['clinical.review lab'] = self._goto_measurements_review
		cProviderInboxPnl._item_handlers['clinical.review vaccs'] = self._goto_vaccination_review

		self.__register_interests()
Exemple #20
0
	def __init__(self, *args, **kwds):

		wxgProviderInboxPnl.wxgProviderInboxPnl.__init__(self, *args, **kwds)
		gmRegetMixin.cRegetOnPaintMixin.__init__(self)

		self.provider = gmStaff.gmCurrentProvider()
		self.__init_ui()

		cProviderInboxPnl._item_handlers['clinical.review docs'] = self._goto_doc_review
		cProviderInboxPnl._item_handlers['clinical.review results'] = self._goto_measurements_review
		cProviderInboxPnl._item_handlers['clinical.review lab'] = self._goto_measurements_review
		cProviderInboxPnl._item_handlers['clinical.review vaccs'] = self._goto_vaccination_review

		self.__register_interests()
Exemple #21
0
def _check_for_provider_chart_access(person):

	curr_prov = gmStaff.gmCurrentProvider()

	# can view my own chart
	if person.ID == curr_prov['pk_identity']:
		return True

	# primary provider can view patient
	if person['pk_primary_provider'] == curr_prov['pk_staff']:
		return True

	# is the patient a provider ?
	if person.ID not in [ s['pk_identity'] for s in gmStaff.get_staff_list() ]:
		return True

	prov = u'%s (%s%s %s)' % (
		curr_prov['short_alias'],
		gmTools.coalesce(curr_prov['title'], u'', u'%s '),
		curr_prov['firstnames'],
		curr_prov['lastnames']
	)
	pat = u'%s%s %s' % (
		gmTools.coalesce(person['title'], u'', u'%s '),
		person['firstnames'],
		person['lastnames']
	)
	# notify the staff member
	gmProviderInbox.create_inbox_message (
		staff = person.staff_id,
		message_type = _('Privacy notice'),
		message_category = u'administrative',
		subject = _('%s: Your chart has been accessed by %s (without user interaction, probably by a script).') % (pat, prov),
		patient = person.ID
	)
	# notify /me about the staff member notification
	gmProviderInbox.create_inbox_message (
		staff = curr_prov['pk_staff'],
		message_type = _('Privacy notice'),
		message_category = u'administrative',
		subject = _('%s: Staff member %s has been notified of your chart access.') % (prov, pat)
	)

	return True
Exemple #22
0
	def _save_as_new(self):

		pat_id = None
		if self._CHBOX_active_patient.GetValue() is True:
			pat_id = gmPerson.gmCurrentPatient().ID
		else:
			if self._PRW_patient.person is not None:
				pat_id = self._PRW_patient.person.ID

		receiver = None
		if self._CHBOX_send_to_me.IsChecked():
			receiver = gmStaff.gmCurrentProvider()['pk_staff']
		else:
			if self._PRW_receiver.GetData() is not None:
				receiver = self._PRW_receiver.GetData()

		msg = gmProviderInbox.create_inbox_message (
			patient = pat_id,
			staff = receiver,
			message_type = self._PRW_type.GetData(can_create = True),
			subject = self._TCTRL_subject.GetValue().strip()
		)

		msg['data'] = self._TCTRL_message.GetValue().strip()

		if self._PRW_due.is_valid_timestamp():
			msg['due_date'] = self._PRW_due.date

		if self._PRW_expiry.is_valid_timestamp():
			msg['expiry_date'] = self._PRW_expiry.date

		if self._RBTN_normal.GetValue() is True:
			msg['importance'] = 0
		elif self._RBTN_high.GetValue() is True:
			msg['importance'] = 1
		else:
			msg['importance'] = -1

		msg.save()
		self.data = msg
		return True
Exemple #23
0
	def _save_as_new(self):

		pat_id = None
		if self._CHBOX_active_patient.GetValue() is True:
			pat_id = gmPerson.gmCurrentPatient().ID
		else:
			if self._PRW_patient.person is not None:
				pat_id = self._PRW_patient.person.ID

		receiver = None
		if self._CHBOX_send_to_me.IsChecked():
			receiver = gmStaff.gmCurrentProvider()['pk_staff']
		else:
			if self._PRW_receiver.GetData() is not None:
				receiver = self._PRW_receiver.GetData()

		msg = gmProviderInbox.create_inbox_message (
			patient = pat_id,
			staff = receiver,
			message_type = self._PRW_type.GetData(can_create = True),
			subject = self._TCTRL_subject.GetValue().strip()
		)

		msg['data'] = self._TCTRL_message.GetValue().strip()

		if self._PRW_due.is_valid_timestamp():
			msg['due_date'] = self._PRW_due.date

		if self._PRW_expiry.is_valid_timestamp():
			msg['expiry_date'] = self._PRW_expiry.date

		if self._RBTN_normal.GetValue() is True:
			msg['importance'] = 0
		elif self._RBTN_high.GetValue() is True:
			msg['importance'] = 1
		else:
			msg['importance'] = -1

		msg.save()
		self.data = msg
		return True
	def __init_ui(self):
		self._PRW_lastname.final_regex = '.+'
		self._PRW_firstnames.final_regex = '.+'
		self._PRW_address_searcher.selection_only = False

		# only if we would support None on selection_only's:
#		self._PRW_external_id_type.selection_only = True

		if self.default_country is not None:
			match = self._PRW_country._data2match(data = self.default_country)
			if match is not None:
				self._PRW_country.SetText(value = match['field_label'], data = match['data'])

		if self.default_region is not None:
			self._PRW_region.SetText(value = self.default_region)

		self._PRW_type.SetText(value = 'home')
		# FIXME: only use this if member of gm-doctors,
		# FIXME: other than that check fallback_primary_provider
		self._PRW_primary_provider.SetData(data = gmStaff.gmCurrentProvider()['pk_staff'])

		self._PRW_lastname.SetFocus()
Exemple #25
0
    def _on_mark_reviewed(self, event):
        reviewed_results = []
        for row in range(self.__grid_unreviewed_results.GetNumberRows()):
            if self.__grid_unreviewed_results.GetCellValue(row, 0) == '1':
                # look up associated request
                result = self.dict_unreviewed_results[row]
                reviewed_results.append(result)
                # update "relevant" status
                relevant = self.__grid_unreviewed_results.GetCellValue(row, 1)
                if relevant == '1':
                    result['relevant'] = 'true'
                else:
                    result['relevant'] = 'false'

        if len(reviewed_results) == 0:
            gmGuiHelpers.beep_status_text(_('No results marked as reviewed.'))
            event.Skip()
            return None

        for result in reviewed_results:
            result['reviewed'] = 'true'
            result['pk_reviewer'] = gmStaff.gmCurrentProvider()['pk_staff']
            if not result['abnormal']:
                result['abnormal'] = ''
            successfull, error = result.save_payload()
            # repopulate
            if successfull:
                self.__populate_notebook()
            else:
                _log.Log(gmLog.lErr,
                         'setting result status to reviewed failed %s' % error)
                gmGuiHelpers.gm_show_error(
                    aMessage=_('Cannot mark results as "reviewed":\n%s') %
                    error,
                    aTitle=_('update result status'))
                return None

        event.Skip()
Exemple #26
0
	def _on_mark_reviewed(self, event):
		reviewed_results = []
		for row in range(self.__grid_unreviewed_results.GetNumberRows()):
			if self.__grid_unreviewed_results.GetCellValue(row, 0) == '1':
				# look up associated request
				result = self.dict_unreviewed_results[row]
				reviewed_results.append(result)
				# update "relevant" status
				relevant = self.__grid_unreviewed_results.GetCellValue(row, 1)
				if relevant == '1':
					result['relevant'] = 'true'
				else:
					result['relevant'] = 'false'

		if len(reviewed_results) == 0:
			gmGuiHelpers.beep_status_text(_('No results marked as reviewed.'))
			event.Skip()
			return None

		for result in reviewed_results:
			result['reviewed'] = 'true'
			result['pk_reviewer'] = gmStaff.gmCurrentProvider()['pk_staff']
			if not result['abnormal']:
				result['abnormal'] = ''
			successfull, error = result.save_payload()
			# repopulate
			if successfull:
				self.__populate_notebook()
			else:
				_log.Log(gmLog.lErr, 'setting result status to reviewed failed %s' % error)
				gmGuiHelpers.gm_show_error (
					aMessage = _('Cannot mark results as "reviewed":\n%s') % error,
					aTitle = _('update result status')
				)
				return None

		event.Skip()
    def __init_ui(self):
        self._PRW_lastname.final_regex = '.+'
        self._PRW_firstnames.final_regex = '.+'
        self._PRW_address_searcher.selection_only = False

        # only if we would support None on selection_only's:
        #		self._PRW_external_id_type.selection_only = True

        if self.default_country is not None:
            match = self._PRW_country._data2match(data=self.default_country)
            if match is not None:
                self._PRW_country.SetText(value=match['field_label'],
                                          data=match['data'])

        if self.default_region is not None:
            self._PRW_region.SetText(value=self.default_region)

        self._PRW_type.SetText(value='home')
        # FIXME: only use this if member of gm-doctors,
        # FIXME: other than that check fallback_primary_provider
        self._PRW_primary_provider.SetData(
            data=gmStaff.gmCurrentProvider()['pk_staff'])

        self._PRW_lastname.SetFocus()
Exemple #28
0
    def Setup(parent):
        """Wrapper to load this module from an environment that wants a panel
		"""
        currUser = gmStaff.gmCurrentProvider()['db_user']
        workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace
        return gmConfigEditorPanel(parent, currUser, workplace)
Exemple #29
0
def print_generic_document(parent=None, jobtype:str=None, episode=None):
	"""Call LibreOffice Writer with a generated (fake) ODT file.

	Once Writer is closed, the ODT is imported if different from its initial content.

	Note:
		The file passed to LO _must_ reside in a directory the parents of
		which are all R-X by the user or else LO will throw up its arms
		in despair and fall back to the user's home dir upon saving.

		So,

			/tmp/user/$UID/some-file.odt

		will *not* work (because .../user/... is "drwx--x--x root.root") while

			/home/$USER/some/dir/some-file.odt

		does.
	"""
	sandbox = os.path.join(gmTools.gmPaths().user_tmp_dir, 'libreoffice')
	gmTools.mkdir(sandbox)
	fpath = gmTools.get_unique_filename(suffix = '.txt', tmp_dir = sandbox)
	doc_file = open(fpath, mode = 'wt')
	doc_file.write(__ODT_FILE_PREAMBLE)
	doc_file.write(_('Today: %s') % gmDateTime.pydt_now_here().strftime('%c'))
	doc_file.write('\n\n')
	prax = gmPraxis.gmCurrentPraxisBranch()
	doc_file.write('Praxis:\n')
	doc_file.write(prax.format())
	doc_file.write('\n')
	doc_file.write('Praxis branch:\n')
	doc_file.write('\n'.join(prax.org_unit.format (
		with_address = True,
		with_org = True,
		with_comms = True
	)))
	doc_file.write('\n\n')
	pat = gmPerson.gmCurrentPatient(gmPerson.cPatient(12))
	if pat.connected:
		doc_file.write('Patient:\n')
		doc_file.write(pat.get_description_gender())
		doc_file.write('\n\n')
		for adr in pat.get_addresses():
			doc_file.write(adr.format(single_line = False, verbose = True, show_type = True))
		doc_file.write('\n\n')
		for chan in pat.get_comm_channels():
			doc_file.werite(chan.format())
		doc_file.write('\n\n')
	doc_file.write('Provider:\n')
	doc_file.write('\n'.join(gmStaff.gmCurrentProvider().get_staff().format()))
	doc_file.write('\n\n-----------------------------------------------------------------------------\n\n')
	doc_file.close()

	# convert txt -> odt
	success, ret_code, stdout = gmShellAPI.run_process (
		cmd_line = [
			'lowriter',
			'--convert-to', 'odt',
			'--outdir', os.path.split(fpath)[0],
			fpath
		],
		verbose = True
	)
	if success:
		fpath = gmTools.fname_stem_with_path(fpath) + '.odt'
	else:
		_log.warning('cannot convert .txt to .odt')
	md5_before = gmTools.file2md5(fpath)
	gmShellAPI.run_process(cmd_line = ['lowriter', fpath], verbose = True)
	md5_after = gmTools.file2md5(fpath)
	if md5_before == md5_after:
		gmDispatcher.send(signal = 'statustext', msg = _('Document not modified. Discarding.'), beep = False)
		return

	if not pat.connected:
		shutil.move(fpath, gmTools.gmPaths().user_work_dir)
		gmDispatcher.send(signal = 'statustext', msg = _('No patient. Moved file into %s') % gmTools.gmPaths().user_work_dir, beep = False)
		return

	pat.export_area.add_file (
		filename = fpath,
		hint = _('Generic letter, written at %s') % gmDateTime.pydt_now_here().strftime('%Y %b %d  %H:%M')
	)
	gmDispatcher.send(signal = 'display_widget', name = 'gmExportAreaPlugin')
Exemple #30
0
def __import_single_PID_hl7_file(filename, emr=None):
	"""Assumes single-PID/single-MSH HL7 file."""

	_log.debug('importing single-PID single-MSH HL7 data from [%s]', filename)

	# read the file
	MSH_file = io.open(filename, mode = 'rt', encoding = 'utf8')
	HL7 = pyhl7.parse(MSH_file.read(1024 * 1024 * 5))	# 5 MB max
	MSH_file.close()

	# sanity checks
	if len(HL7.segments('MSH')) != 1:
		_log.error('more than one MSH segment')
		return False
	if len(HL7.segments('PID')) != 1:
		_log.error('more than one PID segment')
		return False

	# ensure lab is in database
	hl7_lab = HL7.extract_field('MSH', field_num = MSH_field__sending_lab)
	gm_lab = __find_or_create_lab(hl7_lab)

	# ensure test types exist
	conn = gmPG2.get_connection(readonly = False)
	__ensure_hl7_test_types_exist_in_gnumed(link_obj = conn, hl7_data = HL7, pk_test_org = gm_lab['pk_test_org'])

	# find patient
	if emr is None:
		#PID = HL7.segment('PID')
		pats = __PID2dto(HL7 = HL7)
		if len(pats) == 0:
			conn.rollback()
			return False
		if len(pats) > 1:
			conn.rollback()
			return False
		emr = pats[0].emr

	# import values: loop over segments
	when_list = {}
	current_result = None
	previous_segment = None
	had_errors = False
	msh_seen = False
	pid_seen = False
	last_obr = None
	obr = {}
	for seg_idx in range(len(HL7)):
		seg = HL7[seg_idx]
		seg_type = seg[0][0]

		_log.debug('processing line #%s = segment of type <%s>', seg_idx, seg_type)

		if seg_type == u'MSH':
			msh_seen = True

		if seg_type == u'PID':
			if not msh_seen:
				conn.rollback()
				_log.error('PID segment before MSH segment')
				return False
			pid_seen = True

		if seg_type in [u'MSH', u'PID']:
			_log.info('segment already handled')
			previous_segment = seg_type
			obr = {}
			current_result = None
			continue

		if seg_type in [u'ORC']:
			_log.info('currently ignoring %s segments', seg_type)
			previous_segment = seg_type
			obr = {}
			current_result = None
			continue

		if seg_type == u'OBR':
			previous_segment = seg_type
			last_obr = seg
			current_result = None
			obr['abbrev'] = (u'%s' % seg[OBR_field__service_name][0]).strip()
			try:
				obr['name'] = (u'%s' % seg[OBR_field__service_name][1]).strip()
			except IndexError:
				obr['name'] = obr['abbrev']
			for field_name in [OBR_field__ts_ended, OBR_field__ts_started, OBR_field__ts_specimen_received, OBR_field__ts_requested]:
				obr['clin_when'] = seg[field_name][0].strip()
				if obr['clin_when'] != u'':
					break
			continue

		if seg_type == u'OBX':
			current_result = None
			# determine value
			val_alpha = seg[OBX_field__value][0].strip()
			is_num, val_num = gmTools.input2decimal(initial = val_alpha)
			if is_num:
				val_alpha = None
			else:
				val_num = None
				val_alpha = val_alpha.replace('\.br\\', u'\n')
			# determine test type
			unit = seg[OBX_field__unit][0].strip()
			if unit == u'':
				if is_num:
					unit = u'1/1'
				else:
					unit = None
			test_type = __find_or_create_test_type (
				loinc = u'%s' % seg[OBX_field__type][0][OBX_component__loinc-1],
				name = u'%s' % seg[OBX_field__type][0][OBX_component__name-1],
				pk_lab = gm_lab['pk_test_org'],
				unit = unit
			)
			# eventually, episode should be read from lab_request
			epi = emr.add_episode (
				link_obj = conn,
				episode_name = u'administrative',
				is_open = False,
				allow_dupes = False
			)
			current_result = emr.add_test_result (
				link_obj = conn,
				episode = epi['pk_episode'],
				type = test_type['pk_test_type'],
				intended_reviewer = gmStaff.gmCurrentProvider()['pk_staff'],
				val_num = val_num,
				val_alpha = val_alpha,
				unit = unit
			)
			# handle range information et al
			ref_range = seg[OBX_field__range][0].strip()
			if ref_range != u'':
				current_result.reference_range = ref_range
			flag = seg[OBX_field__abnormal_flag][0].strip()
			if flag != u'':
				current_result['abnormality_indicator'] = flag
			current_result['status'] = seg[OBX_field__status][0].strip()
			current_result['val_grouping'] = seg[OBX_field__subid][0].strip()
			current_result['source_data'] = u''
			if last_obr is not None:
				current_result['source_data'] += unicode(last_obr)
				current_result['source_data'] += u'\n'
			current_result['source_data'] += unicode(seg)
			clin_when = seg[OBX_field__timestamp][0].strip()
			if clin_when == u'':
				_log.warning('no <Observation timestamp> in OBX, trying OBR timestamp')
				clin_when = obr['clin_when']
			try:
				clin_when = __hl7dt2pydt(clin_when)
			except ValueError:
				_log.exception('clin_when from OBX or OBR not useable, assuming <today>')
			if clin_when is not None:
				current_result['clin_when'] = clin_when
			current_result.save(conn = conn)
			when_list[gmDateTime.pydt_strftime(current_result['clin_when'], '%Y %b %d')] = 1
			previous_segment = seg_type
			continue

		if seg_type == u'NTE':
			note = seg[NET_field__note][0].strip().replace('\.br\\', u'\n')
			if note == u'':
				_log.debug('empty NTE segment')
				previous_segment = seg_type			# maybe not ? (HL7 providers happen to use empty NTE segments to "structure" raw HL7 |-)
				continue

			# if this is an NTE following an OBR (IOW an order-related
			# comment): make this a test result all of its own :-)
			if previous_segment == u'OBR':
				_log.debug('NTE following OBR: general note, using OBR timestamp [%s]', obr['clin_when'])
				current_result = None
				name = obr['name']
				if name == u'':
					name = _('Comment')
				# FIXME: please suggest a LOINC for "order comment"
				test_type = __find_or_create_test_type(name = name, pk_lab = gm_lab['pk_test_org'], abbrev = obr['abbrev'])
				# eventually, episode should be read from lab_request
				epi = emr.add_episode (
					link_obj = conn,
					episode_name = u'administrative',
					is_open = False,
					allow_dupes = False
				)
				nte_result = emr.add_test_result (
					link_obj = conn,
					episode = epi['pk_episode'],
					type = test_type['pk_test_type'],
					intended_reviewer = gmStaff.gmCurrentProvider()['pk_staff'],
					val_alpha = note
				)
				#nte_result['val_grouping'] = seg[OBX_field__subid][0].strip()
				nte_result['source_data'] = unicode(seg)
				try:
					nte_result['clin_when'] = __hl7dt2pydt(obr['clin_when'])
				except ValueError:
					_log.exception('no .clin_when from OBR for NTE pseudo-OBX available')
				nte_result.save(conn = conn)
				continue

			if (previous_segment == u'OBX') and (current_result is not None):
				current_result['source_data'] += u'\n'
				current_result['source_data'] += unicode(seg)
				current_result['note_test_org'] = gmTools.coalesce (
					current_result['note_test_org'],
					note,
					u'%%s\n%s' % note
				)
				current_result.save(conn = conn)
				previous_segment = seg_type
				continue

			_log.error(u'unexpected NTE segment')
			had_errors = True
			break

		_log.error('unknown segment, aborting')
		_log.debug('line: %s', seg)
		had_errors = True
		break

	if had_errors:
		conn.rollback()
		return False

	conn.commit()

	# record import in chart
	try:
		no_results = len(HL7.segments('OBX'))
	except KeyError:
		no_results = u'?'
	soap = _(
		'Imported HL7 file [%s]:\n'
		' lab "%s" (%s@%s), %s results (%s)'
	) % (
		filename,
		hl7_lab,
		gm_lab['unit'],
		gm_lab['organization'],
		no_results,
		u' / '.join(when_list.keys())
	)
	epi = emr.add_episode (
		episode_name = u'administrative',
		is_open = False,
		allow_dupes = False
	)
	emr.add_clin_narrative (
		note = soap,
		soap_cat = None,
		episode = epi
	)

	# keep copy of HL7 data in document archive
	folder = gmPerson.cPatient(emr.pk_patient).document_folder
	hl7_docs = folder.get_documents (
		doc_type = u'HL7 data',
		episodes = [epi['pk_episode']],
		order_by = u'ORDER BY clin_when DESC'
	)
	if len(hl7_docs) > 0:
		# there should only ever be one unless the user manually creates more,
		# also, it should always be the latest since "ORDER BY clin_when DESC"
		hl7_doc = hl7_docs[0]
	else:
		hl7_doc = folder.add_document (
			document_type = u'HL7 data',
			encounter = emr.active_encounter['pk_encounter'],
			episode = epi['pk_episode']
		)
		hl7_doc['comment'] = _('list of imported HL7 data files')
	hl7_doc['clin_when'] = gmDateTime.pydt_now_here()
	hl7_doc.save()
	part = hl7_doc.add_part(file = filename)
	part['obj_comment'] = _('Result dates: %s') % u' / '.join(when_list.keys())
	part.save()
	hl7_doc.set_reviewed(technically_abnormal = False, clinically_relevant = False)

	return True
Exemple #31
0
def sanity_check_encounter_of_active_patient(parent=None, msg=None):

	# FIXME: should consult a centralized security provider
	# secretaries cannot edit encounters
	if gmStaff.gmCurrentProvider()['role'] == u'secretary':
		return True

	pat = gmPerson.gmCurrentPatient()
	if not pat.connected:
		return True

	dbcfg = gmCfg.cCfgSQL()
	check_enc = bool(dbcfg.get2 (
		option = 'encounter.show_editor_before_patient_change',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'user',
		default = True					# True: if needed, not always unconditionally
	))

	if not check_enc:
		return True

	emr = pat.get_emr()
	enc = emr.active_encounter

	# did we add anything to the EMR ?
	has_narr = enc.has_narrative()
	has_docs = enc.has_documents()

	if (not has_narr) and (not has_docs):
		return True

	empty_aoe = (gmTools.coalesce(enc['assessment_of_encounter'], '').strip() == u'')
	zero_duration = (enc['last_affirmed'] == enc['started'])

	# all is well anyway
	if (not empty_aoe) and (not zero_duration):
		return True

	if zero_duration:
		enc['last_affirmed'] = pydt.datetime.now(tz = gmDateTime.gmCurrentLocalTimezone)

	# no narrative, presumably only import of docs and done
	if not has_narr:
		if empty_aoe:
			enc['assessment_of_encounter'] = _('only documents added')
		enc['pk_type'] = gmEMRStructItems.get_encounter_type(description = 'chart review')[0]['pk']
		# "last_affirmed" should be latest modified_at of relevant docs but that's a lot more involved
		enc.save_payload()
		return True

	# does have narrative
	if empty_aoe:
		# - work out suitable default
		epis = emr.get_episodes_by_encounter()
		if len(epis) > 0:
			enc_summary = ''
			for epi in epis:
				enc_summary += '%s; ' % epi['description']
			enc['assessment_of_encounter'] = enc_summary

	if msg is None:
		msg = _('Edit the encounter details of the active patient before moving on:')
	if parent is None:
		parent = wx.GetApp().GetTopWindow()
	edit_encounter(parent = parent, encounter = enc, msg = msg)

	return True
Exemple #32
0
def sanity_check_encounter_of_active_patient(parent=None, msg=None):

    # FIXME: should consult a centralized security provider
    # secretaries cannot edit encounters
    if gmStaff.gmCurrentProvider()['role'] == 'secretary':
        return True

    pat = gmPerson.gmCurrentPatient()
    if not pat.connected:
        return True

    check_enc = gmCfgDB.get4user(
        option='encounter.show_editor_before_patient_change',
        workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
        default=True  # True: if needed, not always unconditionally
    )

    if not check_enc:
        return True

    emr = pat.emr
    enc = emr.active_encounter
    # did we add anything to the EMR ?
    has_narr = enc.has_narrative()
    has_docs = enc.has_documents()
    if (not has_narr) and (not has_docs):
        return True

    empty_aoe = (gmTools.coalesce(enc['assessment_of_encounter'],
                                  '').strip() == '')
    zero_duration = (enc['last_affirmed'] == enc['started'])
    # all is well anyway
    if (not empty_aoe) and (not zero_duration):
        return True

    if zero_duration:
        enc['last_affirmed'] = pydt.datetime.now(
            tz=gmDateTime.gmCurrentLocalTimezone)
    # no narrative, presumably only import of docs and done
    if not has_narr:
        if empty_aoe:
            enc['assessment_of_encounter'] = _('only documents added')
        enc['pk_type'] = gmEMRStructItems.get_encounter_type(
            description='chart review')[0]['pk']
        # "last_affirmed" should be latest modified_at of relevant docs but that's a lot more involved
        enc.save_payload()
        return True

    # does have narrative
    if empty_aoe:
        # - work out suitable default
        epis = emr.get_episodes_by_encounter()
        if len(epis) > 0:
            enc['assessment_of_encounter'] = '; '.join(
                [e['description'] for e in epis])
    enc.save_payload()
    if msg is None:
        msg = _(
            'Edit the encounter details of the active patient before moving on:'
        )
    if parent is None:
        parent = wx.GetApp().GetTopWindow()
    _log.debug('sanity-check editing encounter [%s] for patient [%s]',
               enc['pk_encounter'], enc['pk_patient'])
    edit_encounter(parent=parent, encounter=enc, msg=msg)
    return True
Exemple #33
0
def __import_single_PID_hl7_file(filename, emr=None):
	"""Assumes single-PID/single-MSH HL7 file."""

	_log.debug('importing single-PID single-MSH HL7 data from [%s]', filename)

	# read the file
	MSH_file = io.open(filename, mode = 'rt', encoding = 'utf8', newline = '')
	HL7 = pyhl7.parse(MSH_file.read(1024 * 1024 * 5))	# 5 MB max
	MSH_file.close()

	# sanity checks
	if len(HL7.segments('MSH')) != 1:
		_log.error('more than one MSH segment')
		return False
	if len(HL7.segments('PID')) != 1:
		_log.error('more than one PID segment')
		return False

	# ensure lab is in database
	hl7_lab = HL7.extract_field('MSH', field_num = MSH_field__sending_lab)
	gm_lab = __find_or_create_lab(hl7_lab)

	# ensure test types exist
	conn = gmPG2.get_connection(readonly = False)
	__ensure_hl7_test_types_exist_in_gnumed(link_obj = conn, hl7_data = HL7, pk_test_org = gm_lab['pk_test_org'])

	# find patient
	if emr is None:
		#PID = HL7.segment('PID')
		pats = __PID2dto(HL7 = HL7)
		if len(pats) == 0:
			conn.rollback()
			return False
		if len(pats) > 1:
			conn.rollback()
			return False
		emr = pats[0].emr

	# import values: loop over segments
	when_list = {}
	current_result = None
	previous_segment = None
	had_errors = False
	msh_seen = False
	pid_seen = False
	last_obr = None
	obr = {}
	for seg_idx in range(len(HL7)):
		seg = HL7[seg_idx]
		seg_type = seg[0][0]

		_log.debug('processing line #%s = segment of type <%s>', seg_idx, seg_type)

		if seg_type == 'MSH':
			msh_seen = True

		if seg_type == 'PID':
			if not msh_seen:
				conn.rollback()
				_log.error('PID segment before MSH segment')
				return False
			pid_seen = True

		if seg_type in ['MSH', 'PID']:
			_log.info('segment already handled')
			previous_segment = seg_type
			obr = {}
			current_result = None
			continue

		if seg_type in ['ORC']:
			_log.info('currently ignoring %s segments', seg_type)
			previous_segment = seg_type
			obr = {}
			current_result = None
			continue

		if seg_type == 'OBR':
			previous_segment = seg_type
			last_obr = seg
			current_result = None
			obr['abbrev'] = ('%s' % seg[OBR_field__service_name][0]).strip()
			try:
				obr['name'] = ('%s' % seg[OBR_field__service_name][1]).strip()
			except IndexError:
				obr['name'] = obr['abbrev']
			for field_name in [OBR_field__ts_ended, OBR_field__ts_started, OBR_field__ts_specimen_received, OBR_field__ts_requested]:
				obr['clin_when'] = seg[field_name][0].strip()
				if obr['clin_when'] != '':
					break
			continue

		if seg_type == 'OBX':
			current_result = None
			# determine value
			val_alpha = seg[OBX_field__value][0].strip()
			is_num, val_num = gmTools.input2decimal(initial = val_alpha)
			if is_num:
				val_alpha = None
			else:
				val_num = None
				val_alpha = val_alpha.replace('\.br\\', '\n')
			# determine test type
			unit = seg[OBX_field__unit][0].strip()
			if unit == '':
				if is_num:
					unit = '1/1'
				else:
					unit = None
			test_type = __find_or_create_test_type (
				loinc = '%s' % seg[OBX_field__type][0][OBX_component__loinc-1],
				name = '%s' % seg[OBX_field__type][0][OBX_component__name-1],
				pk_lab = gm_lab['pk_test_org'],
				unit = unit,
				link_obj = conn
			)
			# eventually, episode should be read from lab_request
			epi = emr.add_episode (
				link_obj = conn,
				episode_name = 'administrative',
				is_open = False,
				allow_dupes = False
			)
			current_result = emr.add_test_result (
				link_obj = conn,
				episode = epi['pk_episode'],
				type = test_type['pk_test_type'],
				intended_reviewer = gmStaff.gmCurrentProvider()['pk_staff'],
				val_num = val_num,
				val_alpha = val_alpha,
				unit = unit
			)
			# handle range information et al
			ref_range = seg[OBX_field__range][0].strip()
			if ref_range != '':
				current_result.reference_range = ref_range
			flag = seg[OBX_field__abnormal_flag][0].strip()
			if flag != '':
				current_result['abnormality_indicator'] = flag
			current_result['status'] = seg[OBX_field__status][0].strip()
			current_result['val_grouping'] = seg[OBX_field__subid][0].strip()
			current_result['source_data'] = ''
			if last_obr is not None:
				current_result['source_data'] += str(last_obr)
				current_result['source_data'] += '\n'
			current_result['source_data'] += str(seg)
			clin_when = seg[OBX_field__timestamp][0].strip()
			if clin_when == '':
				_log.warning('no <Observation timestamp> in OBX, trying OBR timestamp')
				clin_when = obr['clin_when']
			try:
				clin_when = __hl7dt2pydt(clin_when)
			except ValueError:
				_log.exception('clin_when from OBX or OBR not useable, assuming <today>')
			if clin_when is not None:
				current_result['clin_when'] = clin_when
			current_result.save(conn = conn)
			when_list[gmDateTime.pydt_strftime(current_result['clin_when'], '%Y %b %d')] = 1
			previous_segment = seg_type
			continue

		if seg_type == 'NTE':
			note = seg[NET_field__note][0].strip().replace('\.br\\', '\n')
			if note == '':
				_log.debug('empty NTE segment')
				previous_segment = seg_type			# maybe not ? (HL7 providers happen to use empty NTE segments to "structure" raw HL7 |-)
				continue

			# if this is an NTE following an OBR (IOW an order-related
			# comment): make this a test result all of its own :-)
			if previous_segment == 'OBR':
				_log.debug('NTE following OBR: general note, using OBR timestamp [%s]', obr['clin_when'])
				current_result = None
				name = obr['name']
				if name == '':
					name = _('Comment')
				# FIXME: please suggest a LOINC for "order comment"
				test_type = __find_or_create_test_type(name = name, pk_lab = gm_lab['pk_test_org'], abbrev = obr['abbrev'], link_obj = conn)
				# eventually, episode should be read from lab_request
				epi = emr.add_episode (
					link_obj = conn,
					episode_name = 'administrative',
					is_open = False,
					allow_dupes = False
				)
				nte_result = emr.add_test_result (
					link_obj = conn,
					episode = epi['pk_episode'],
					type = test_type['pk_test_type'],
					intended_reviewer = gmStaff.gmCurrentProvider()['pk_staff'],
					val_alpha = note
				)
				#nte_result['val_grouping'] = seg[OBX_field__subid][0].strip()
				nte_result['source_data'] = str(seg)
				try:
					nte_result['clin_when'] = __hl7dt2pydt(obr['clin_when'])
				except ValueError:
					_log.exception('no .clin_when from OBR for NTE pseudo-OBX available')
				nte_result.save(conn = conn)
				continue

			if (previous_segment == 'OBX') and (current_result is not None):
				current_result['source_data'] += '\n'
				current_result['source_data'] += str(seg)
				current_result['note_test_org'] = gmTools.coalesce (
					current_result['note_test_org'],
					note,
					'%%s\n%s' % note
				)
				current_result.save(conn = conn)
				previous_segment = seg_type
				continue

			_log.error('unexpected NTE segment')
			had_errors = True
			break

		_log.error('unknown segment, aborting')
		_log.debug('line: %s', seg)
		had_errors = True
		break

	if had_errors:
		conn.rollback()
		return False

	conn.commit()

	# record import in chart
	try:
		no_results = len(HL7.segments('OBX'))
	except KeyError:
		no_results = '?'
	soap = _(
		'Imported HL7 file [%s]:\n'
		' lab "%s" (%s@%s), %s results (%s)'
	) % (
		filename,
		hl7_lab,
		gm_lab['unit'],
		gm_lab['organization'],
		no_results,
		' / '.join(list(when_list))
	)
	epi = emr.add_episode (
		episode_name = 'administrative',
		is_open = False,
		allow_dupes = False
	)
	emr.add_clin_narrative (
		note = soap,
		soap_cat = None,
		episode = epi
	)

	# keep copy of HL7 data in document archive
	folder = gmPerson.cPatient(emr.pk_patient).document_folder
	hl7_docs = folder.get_documents (
		doc_type = 'HL7 data',
		pk_episodes = [epi['pk_episode']],
		order_by = 'ORDER BY clin_when DESC'
	)
	if len(hl7_docs) > 0:
		# there should only ever be one unless the user manually creates more,
		# also, it should always be the latest since "ORDER BY clin_when DESC"
		hl7_doc = hl7_docs[0]
	else:
		hl7_doc = folder.add_document (
			document_type = 'HL7 data',
			encounter = emr.active_encounter['pk_encounter'],
			episode = epi['pk_episode']
		)
		hl7_doc['comment'] = _('list of imported HL7 data files')
		hl7_doc['pk_org_unit'] = gmPraxis.gmCurrentPraxisBranch()['pk_org_unit']
	hl7_doc['clin_when'] = gmDateTime.pydt_now_here()
	hl7_doc.save()
	part = hl7_doc.add_part(file = filename)
	part['obj_comment'] = _('Result dates: %s') % ' / '.join(list(when_list))
	part.save()
	hl7_doc.set_reviewed(technically_abnormal = False, clinically_relevant = False)

	return True
from Gnumed.business import gmStaff

from Gnumed.wxpython import gmGuiHelpers

_log = logging.getLogger('gm.perms')

#=========================================================================
_known_roles = [
    'public access',
    'non-clinical access',
    'limited clinical access',  # currently not in use
    'full clinical access',
    'admin'  # currently not in use
]

_curr_staff = gmStaff.gmCurrentProvider()


#-------------------------------------------------------------------------
def verify_minimum_required_role(minimum_role,
                                 activity=None,
                                 return_value_on_failure=None,
                                 fail_silently=False):

    if activity is None:
        activity = _('generic activity')

    #---------
    def _inner_verify_minimum_required_role(original_function):

        #---------
Exemple #35
0
 def get_provider_inbox_data(self):
     self.provider = gmStaff.gmCurrentProvider(provider=gmStaff.cStaff())
     inbox = gmProviderInbox.cProviderInbox()
     self.__msgs = inbox.messages
     return jsonclasshintify(inbox.messages)
Exemple #36
0
 def __init__(self, provider_id=None):
     if provider_id is None:
         self.__provider_id = gmStaff.gmCurrentProvider()['pk_staff']
     else:
         self.__provider_id = provider_id
Exemple #37
0
 def test_inbox():
     gmStaff.gmCurrentProvider(provider=gmStaff.cStaff())
     inbox = cProviderInbox()
     for msg in inbox.messages:
         print msg
Exemple #38
0
def edit_narrative(parent=None, narrative=None, single_entry=False):
	assert isinstance(narrative, gmClinNarrative.cNarrative), '<narrative> must be of type <cNarrative>'

	title = _('Editing progress note')
	if narrative['modified_by_raw'] == gmStaff.gmCurrentProvider()['db_user']:
		msg = _('Your original progress note:')
	else:
		msg = _('Original progress note by %s [%s]\n(will be notified of changes):') % (
			narrative['modified_by'],
			narrative['modified_by_raw']
		)
	if parent is None:
		parent = wx.GetApp().GetTopWindow()
	dlg = gmGuiHelpers.cMultilineTextEntryDlg (
		parent,
		-1,
		title = title,
		msg = msg,
		data = narrative.format(left_margin = ' ', fancy = True),
		text = narrative['narrative'].strip()
	)
	decision = dlg.ShowModal()
	val = dlg.value.strip()
	dlg.DestroyLater()
	if decision != wx.ID_SAVE:
		return False

	if val == '':
		return False

	if val == narrative['narrative'].strip():
		return False

	if narrative['modified_by_raw'] == gmStaff.gmCurrentProvider()['db_user']:
		narrative['narrative'] = val
		narrative.save_payload()
		return True

	q = _(
		'Original progress note written by someone else:\n'
		'\n'
		' %s (%s)\n'
		'\n'
		'Upon saving changes that person will be notified.\n'
		'\n'
		'Consider saving as a new progress note instead.'
	) % (
		narrative['modified_by_raw'],
		narrative['modified_by']
	)
	buttons = [
		{'label': _('Save changes'), 'default': True},
		{'label': _('Save new note')},
		{'label': _('Discard')}
	]
	dlg = gmGuiHelpers.c3ButtonQuestionDlg(parent = parent, caption = title, question = q, button_defs = buttons)
	decision = dlg.ShowModal()
	dlg.DestroyLater()
	if decision not in [wx.ID_YES, wx.ID_NO]:
		return False

	if decision == wx.ID_NO:
		# create new progress note within the same context as the original one
		gmClinNarrative.create_narrative_item (
			narrative = val,
			soap_cat = narrative['soap_cat'],
			episode_id = narrative['pk_episode'],
			encounter_id = narrative['pk_encounter']
		)
		return True

	# notify original provider
	msg = gmProviderInbox.create_inbox_message (
		staff = narrative.staff_id,
		message_type = _('Change notification'),
		message_category = 'administrative',
		subject = _('A progress note of yours has been edited.'),
		patient = narrative['pk_patient']
	)
	msg['data'] = _(
		'Original (by [%s]):\n'
		'%s\n'
		'\n'
		'Edited (by [%s]):\n'
		'%s'
	) % (
		narrative['modified_by'],
		narrative['narrative'].strip(),
		gmStaff.gmCurrentProvider()['short_alias'],
		val
	)
	msg.save()
	# notify /me about the staff member notification
	#gmProviderInbox.create_inbox_message (
	#	staff = curr_prov['pk_staff'],
	#	message_type = _('Privacy notice'),
	#	message_category = 'administrative',
	#	subject = _('%s: Staff member %s has been notified of your chart access.') % (prov, pat)
	#)
	# save narrative change
	narrative['narrative'] = val
	narrative.save()
	return True
def _verify_staff_chart_access(patient=None):

	if patient is None:
		return True

	# staff ?
	if patient.ID not in [ s['pk_identity'] for s in gmStaff.get_staff_list() ]:
		return True

	curr_prov = gmStaff.gmCurrentProvider()

	# can view my own chart
	if patient.ID == curr_prov['pk_identity']:
		return True

	# primary provider can view patient
	if patient['pk_primary_provider'] == curr_prov['pk_staff']:
		return True

	proceed = gmGuiHelpers.gm_show_question (
		aTitle = _('Privacy check'),
		aMessage = _(
			'You have selected the chart of a member of staff,\n'
			'for whom privacy is especially important:\n'
			'\n'
			'  %s, %s\n'
			'\n'
			'This may be OK depending on circumstances.\n'
			'\n'
			'Please be aware that accessing patient charts is\n'
			'logged and that %s%s will be\n'
			'notified of the access if you choose to proceed.\n'
			'\n'
			'Are you sure you want to draw this chart ?'
		) % (
			patient.get_description_gender(),
			patient.get_formatted_dob(),
			gmTools.coalesce(patient['title'], '', '%s '),
			patient['lastnames']
		)
	)

	if proceed:
		prov = '%s (%s%s %s)' % (
			curr_prov['short_alias'],
			gmTools.coalesce(curr_prov['title'], '', '%s '),
			curr_prov['firstnames'],
			curr_prov['lastnames']
		)
		pat = '%s%s %s' % (
			gmTools.coalesce(patient['title'], '', '%s '),
			patient['firstnames'],
			patient['lastnames']
		)
		# notify the staff member
		gmProviderInbox.create_inbox_message (
			staff = patient.staff_id,
			message_type = _('Privacy notice'),
			message_category = 'administrative',
			subject = _('%s: Your chart has been accessed by %s.') % (pat, prov),
			patient = patient.ID
		)
		# notify /me about the staff member notification
		gmProviderInbox.create_inbox_message (
			staff = curr_prov['pk_staff'],
			message_type = _('Privacy notice'),
			message_category = 'administrative',
			subject = _('%s: Staff member %s has been notified of your chart access.') % (prov, pat)
		)

	return proceed
Exemple #40
0
 def get_provider_inbox_data(self):
     self.provider = gmStaff.gmCurrentProvider(provider=gmStaff.cStaff())
     inbox = gmProviderInbox.cProviderInbox()
     self.__msgs = inbox.messages
     return jsonclasshintify(inbox.messages)
Exemple #41
0
def manage_progress_notes(parent=None,
                          encounters=None,
                          episodes=None,
                          patient=None):

    # sanity checks
    if patient is None:
        patient = gmPerson.gmCurrentPatient()

    if not patient.connected:
        gmDispatcher.send(
            signal='statustext',
            msg=_('Cannot edit progress notes. No active patient.'))
        return False

    if parent is None:
        parent = wx.GetApp().GetTopWindow()

    emr = patient.emr

    #--------------------------
    def delete(item):
        if item is None:
            return False
        dlg = gmGuiHelpers.c2ButtonQuestionDlg(
            parent,
            -1,
            caption=_('Deleting progress note'),
            question=_(
                'Are you positively sure you want to delete this\n'
                'progress note from the medical record ?\n'
                '\n'
                'Note that even if you chose to delete the entry it will\n'
                'still be (invisibly) kept in the audit trail to protect\n'
                'you from litigation because physical deletion is known\n'
                'to be unlawful in some jurisdictions.\n'),
            button_defs=({
                'label': _('Delete'),
                'tooltip': _('Yes, delete the progress note.'),
                'default': False
            }, {
                'label': _('Cancel'),
                'tooltip': _('No, do NOT delete the progress note.'),
                'default': True
            }))
        decision = dlg.ShowModal()

        if decision != wx.ID_YES:
            return False

        gmClinNarrative.delete_clin_narrative(narrative=item['pk_narrative'])
        return True

    #--------------------------
    def edit(item):
        if item is None:
            return False

        dlg = gmGuiHelpers.cMultilineTextEntryDlg(
            parent,
            -1,
            title=_('Editing progress note'),
            msg=_('This is the original progress note:'),
            data=item.format(left_margin=' ', fancy=True),
            text=item['narrative'])
        decision = dlg.ShowModal()

        if decision != wx.ID_SAVE:
            return False

        val = dlg.value
        dlg.Destroy()
        if val.strip() == '':
            return False

        item['narrative'] = val
        item.save_payload()

        return True

    #--------------------------
    def refresh(lctrl):
        notes = emr.get_clin_narrative(
            encounters=encounters,
            episodes=episodes,
            providers=[gmStaff.gmCurrentProvider()['short_alias']])
        lctrl.set_string_items(items=[[
            narr['date'].strftime('%x %H:%M'), gmSoapDefs.soap_cat2l10n[
                narr['soap_cat']], narr['narrative'].replace(
                    '\n', '/').replace('\r', '/')
        ] for narr in notes])
        lctrl.set_data(data=notes)

    #--------------------------

    gmListWidgets.get_choices_from_list(
        parent=parent,
        caption=_('Managing progress notes'),
        msg=_('\n'
              ' This list shows the progress notes by %s.\n'
              '\n') % gmStaff.gmCurrentProvider()['short_alias'],
        columns=[_('when'), _('type'), _('entry')],
        single_selection=True,
        can_return_empty=False,
        edit_callback=edit,
        delete_callback=delete,
        refresh_callback=refresh)
Exemple #42
0
	def __init__(self, provider_id=None):
		if provider_id is None:
			self.__provider_id = gmStaff.gmCurrentProvider()['pk_staff']
		else:
			self.__provider_id = provider_id
Exemple #43
0
def manage_progress_notes(parent=None, encounters=None, episodes=None, patient=None):

	# sanity checks
	if patient is None:
		patient = gmPerson.gmCurrentPatient()

	if not patient.connected:
		gmDispatcher.send(signal = 'statustext', msg = _('Cannot edit progress notes. No active patient.'))
		return False

	if parent is None:
		parent = wx.GetApp().GetTopWindow()

	emr = patient.emr
	#--------------------------
	def delete(item):
		if item is None:
			return False
		dlg = gmGuiHelpers.c2ButtonQuestionDlg (
			parent,
			-1,
			caption = _('Deleting progress note'),
			question = _(
				'Are you positively sure you want to delete this\n'
				'progress note from the medical record ?\n'
				'\n'
				'Note that even if you chose to delete the entry it will\n'
				'still be (invisibly) kept in the audit trail to protect\n'
				'you from litigation because physical deletion is known\n'
				'to be unlawful in some jurisdictions.\n'
			),
			button_defs = (
				{'label': _('Delete'), 'tooltip': _('Yes, delete the progress note.'), 'default': False},
				{'label': _('Cancel'), 'tooltip': _('No, do NOT delete the progress note.'), 'default': True}
			)
		)
		decision = dlg.ShowModal()

		if decision != wx.ID_YES:
			return False

		gmClinNarrative.delete_clin_narrative(narrative = item['pk_narrative'])
		return True
	#--------------------------
	def edit(item):
		if item is None:
			return False

		dlg = gmGuiHelpers.cMultilineTextEntryDlg (
			parent,
			-1,
			title = _('Editing progress note'),
			msg = _('This is the original progress note:'),
			data = item.format(left_margin = ' ', fancy = True),
			text = item['narrative']
		)
		decision = dlg.ShowModal()

		if decision != wx.ID_SAVE:
			return False

		val = dlg.value
		dlg.DestroyLater()
		if val.strip() == '':
			return False

		item['narrative'] = val
		item.save_payload()

		return True
	#--------------------------
	def refresh(lctrl):
		notes = emr.get_clin_narrative (
			encounters = encounters,
			episodes = episodes,
			providers = [ gmStaff.gmCurrentProvider()['short_alias'] ]
		)
		lctrl.set_string_items(items = [
			[	narr['date'].strftime('%x %H:%M'),
				gmSoapDefs.soap_cat2l10n[narr['soap_cat']],
				narr['narrative'].replace('\n', '/').replace('\r', '/')
			] for narr in notes
		])
		lctrl.set_data(data = notes)
	#--------------------------

	gmListWidgets.get_choices_from_list (
		parent = parent,
		caption = _('Managing progress notes'),
		msg = _(
			'\n'
			' This list shows the progress notes by %s.\n'
			'\n'
		) % gmStaff.gmCurrentProvider()['short_alias'],
		columns = [_('when'), _('type'), _('entry')],
		single_selection = True,
		can_return_empty = False,
		edit_callback = edit,
		delete_callback = delete,
		refresh_callback = refresh
	)
Exemple #44
0
	def save(self):
		"""Save data into backend."""

		# fill progress_note for import
		progress_note = []
		aoe = ''
		rfe = ''
		has_rfe = False
		soap_lines_contents = self.GetValue()
		for line_content in soap_lines_contents.values():
			if line_content.text.strip() == '':
				continue
			progress_note.append ({
				gmSOAPimporter.soap_bundle_SOAP_CAT_KEY: line_content.data.soap_cat,
				gmSOAPimporter.soap_bundle_TYPES_KEY: [],		# these types need to come from the editor
				gmSOAPimporter.soap_bundle_TEXT_KEY: line_content.text.rstrip()
			})
			if line_content.data.is_rfe:
				has_rfe = True
				rfe += line_content.text.rstrip()
			if line_content.data.soap_cat == 'a':
				aoe += line_content.text.rstrip()

		emr = self.__pat.emr

		# - new episode, must get name from narrative (or user)
		if (self.__problem is None) or (self.__problem['type'] == 'issue'):
			# work out episode name
			epi_name = ''
			if len(aoe) != 0:
				epi_name = aoe
			else:
				epi_name = rfe

			dlg = wx.TextEntryDialog (
				self,
				_('Enter a descriptive name for this new problem:'),
				caption = _('Creating a problem (episode) to save the notelet under ...'),
				value = epi_name.replace('\r', '//').replace('\n', '//'),
				style = wx.OK | wx.CANCEL | wx.CENTRE
			)
			decision = dlg.ShowModal()
			if decision != wx.ID_OK:
				return False

			epi_name = dlg.GetValue().strip()
			if epi_name == '':
				gmGuiHelpers.gm_show_error(_('Cannot save a new problem without a name.'), _('saving progress note'))
				return False

			# new unassociated episode
			new_episode = emr.add_episode(episode_name = epi_name[:45], pk_health_issue = None, is_open = True)

			if self.__problem is not None:
				issue = emr.problem2issue(self.__problem)
				if not gmEMRStructWidgets.move_episode_to_issue(episode = new_episode, target_issue = issue, save_to_backend = True):
					print("error moving episode to issue")

			epi_id = new_episode['pk_episode']
		else:
			epi_id = self.__problem['pk_episode']

		# set up clinical context in progress note
		encounter = emr.active_encounter
		staff_id = gmStaff.gmCurrentProvider()['pk_staff']
		clin_ctx = {
			gmSOAPimporter.soap_bundle_EPISODE_ID_KEY: epi_id,
			gmSOAPimporter.soap_bundle_ENCOUNTER_ID_KEY: encounter['pk_encounter'],
			gmSOAPimporter.soap_bundle_STAFF_ID_KEY: staff_id
		}
		for line in progress_note:
			line[gmSOAPimporter.soap_bundle_CLIN_CTX_KEY] = clin_ctx

		# dump progress note to backend
		importer = gmSOAPimporter.cSOAPImporter()
		if not importer.import_soap(progress_note):
			gmGuiHelpers.gm_show_error(_('Error saving progress note.'), _('saving progress note'))
			return False

		# dump embedded data to backend
		if not self.__embedded_data_holder.save():
			gmGuiHelpers.gm_show_error (
				_('Error saving embedded data.'),
				_('saving progress note')
			)
			return False
		self.__embedded_data_holder.clear()

		return True
from Gnumed.wxpython import gmGuiHelpers


_log = logging.getLogger('gm.perms')

#=========================================================================
_known_roles = [
	'public access',
	'non-clinical access',
	'limited clinical access',		# currently not in use
	'full clinical access',
	'admin'						# currently not in use
]

_curr_staff = gmStaff.gmCurrentProvider()

#-------------------------------------------------------------------------
def verify_minimum_required_role(minimum_role, activity=None, return_value_on_failure=None, fail_silently=False):

	if activity is None:
		activity = _('generic activity')

	#---------
	def _inner_verify_minimum_required_role(original_function):

		#---------
		#@functools.wraps(original_function)
		def _func_decorated_with_required_role_checking(*args, **kwargs):
			if _known_roles.index(minimum_role) > _known_roles.index(_curr_staff['role']):
				_log.info('access denied: %s', activity)
Exemple #46
0
    def save(self):
        """Save data into backend."""

        # fill progress_note for import
        progress_note = []
        aoe = ''
        rfe = ''
        has_rfe = False
        soap_lines_contents = self.GetValue()
        for line_content in soap_lines_contents.values():
            if line_content.text.strip() == '':
                continue
            progress_note.append({
                gmSOAPimporter.soap_bundle_SOAP_CAT_KEY:
                line_content.data.soap_cat,
                gmSOAPimporter.soap_bundle_TYPES_KEY:
                [],  # these types need to come from the editor
                gmSOAPimporter.soap_bundle_TEXT_KEY:
                line_content.text.rstrip()
            })
            if line_content.data.is_rfe:
                has_rfe = True
                rfe += line_content.text.rstrip()
            if line_content.data.soap_cat == 'a':
                aoe += line_content.text.rstrip()

        emr = self.__pat.emr

        # - new episode, must get name from narrative (or user)
        if (self.__problem is None) or (self.__problem['type'] == 'issue'):
            # work out episode name
            epi_name = ''
            if len(aoe) != 0:
                epi_name = aoe
            else:
                epi_name = rfe

            dlg = wx.TextEntryDialog(
                parent=self,
                message=_('Enter a descriptive name for this new problem:'),
                caption=_(
                    'Creating a problem (episode) to save the notelet under ...'
                ),
                defaultValue=epi_name.replace('\r', '//').replace('\n', '//'),
                style=wx.OK | wx.CANCEL | wx.CENTRE)
            decision = dlg.ShowModal()
            if decision != wx.ID_OK:
                return False

            epi_name = dlg.GetValue().strip()
            if epi_name == '':
                gmGuiHelpers.gm_show_error(
                    _('Cannot save a new problem without a name.'),
                    _('saving progress note'))
                return False

            # new unassociated episode
            new_episode = emr.add_episode(episode_name=epi_name[:45],
                                          pk_health_issue=None,
                                          is_open=True)

            if self.__problem is not None:
                issue = emr.problem2issue(self.__problem)
                if not gmEMRStructWidgets.move_episode_to_issue(
                        episode=new_episode,
                        target_issue=issue,
                        save_to_backend=True):
                    print("error moving episode to issue")

            epi_id = new_episode['pk_episode']
        else:
            epi_id = self.__problem['pk_episode']

        # set up clinical context in progress note
        encounter = emr.active_encounter
        staff_id = gmStaff.gmCurrentProvider()['pk_staff']
        clin_ctx = {
            gmSOAPimporter.soap_bundle_EPISODE_ID_KEY: epi_id,
            gmSOAPimporter.soap_bundle_ENCOUNTER_ID_KEY:
            encounter['pk_encounter'],
            gmSOAPimporter.soap_bundle_STAFF_ID_KEY: staff_id
        }
        for line in progress_note:
            line[gmSOAPimporter.soap_bundle_CLIN_CTX_KEY] = clin_ctx

        # dump progress note to backend
        importer = gmSOAPimporter.cSOAPImporter()
        if not importer.import_soap(progress_note):
            gmGuiHelpers.gm_show_error(_('Error saving progress note.'),
                                       _('saving progress note'))
            return False

        # dump embedded data to backend
        if not self.__embedded_data_holder.save():
            gmGuiHelpers.gm_show_error(_('Error saving embedded data.'),
                                       _('saving progress note'))
            return False
        self.__embedded_data_holder.clear()

        return True
Exemple #47
0
	def test_inbox():
		gmStaff.gmCurrentProvider(provider = gmStaff.cStaff())
		inbox = cProviderInbox()
		for msg in inbox.messages:
			print(msg)
Exemple #48
0
def _verify_staff_chart_access(patient=None):

	if patient is None:
		return True

	# staff ?
	if patient.ID not in [ s['pk_identity'] for s in gmStaff.get_staff_list() ]:
		return True

	curr_prov = gmStaff.gmCurrentProvider()

	# can view my own chart
	if patient.ID == curr_prov['pk_identity']:
		return True

	# primary provider can view patient
	if patient['pk_primary_provider'] == curr_prov['pk_staff']:
		return True

	proceed = gmGuiHelpers.gm_show_question (
		aTitle = _('Privacy check'),
		aMessage = _(
			'You have selected the chart of a member of staff,\n'
			'for whom privacy is especially important:\n'
			'\n'
			'  %s, %s\n'
			'\n'
			'This may be OK depending on circumstances.\n'
			'\n'
			'Please be aware that accessing patient charts is\n'
			'logged and that %s%s will be\n'
			'notified of the access if you choose to proceed.\n'
			'\n'
			'Are you sure you want to draw this chart ?'
		) % (
			patient.get_description_gender(),
			patient.get_formatted_dob(),
			gmTools.coalesce(patient['title'], '', '%s '),
			patient['lastnames']
		)
	)

	if proceed:
		prov = '%s (%s%s %s)' % (
			curr_prov['short_alias'],
			gmTools.coalesce(curr_prov['title'], '', '%s '),
			curr_prov['firstnames'],
			curr_prov['lastnames']
		)
		pat = '%s%s %s' % (
			gmTools.coalesce(patient['title'], '', '%s '),
			patient['firstnames'],
			patient['lastnames']
		)
		# notify the staff member
		gmProviderInbox.create_inbox_message (
			staff = patient.staff_id,
			message_type = _('Privacy notice'),
			message_category = 'administrative',
			subject = _('%s: Your chart has been accessed by %s.') % (pat, prov),
			patient = patient.ID
		)
		# notify /me about the staff member notification
		gmProviderInbox.create_inbox_message (
			staff = curr_prov['pk_staff'],
			message_type = _('Privacy notice'),
			message_category = 'administrative',
			subject = _('%s: Staff member %s has been notified of your chart access.') % (prov, pat)
		)

	return proceed