Esempio n. 1
0
	def _on_waiting_list_button_pressed(self, event):
		event.Skip()

		pat_pk_key = self._LCTRL_result.patient_pk_data_key
		if pat_pk_key is None:
			gmGuiHelpers.gm_show_info (
				info = _('These report results do not seem to contain per-patient data.'),
				title = _('Using report results')
			)
			return

		zone = wx.GetTextFromUser (
			_('Enter a waiting zone to put patients in:'),
			caption = _('Using report results'),
			default_value = _('search results')
		)
		if zone.strip() == '':
			return

		data = self._LCTRL_result.get_selected_item_data(only_one = False)
		if data is None:
			use_all = gmGuiHelpers.gm_show_question (
				title = _('Using report results'),
				question = _('No results selected.\n\nTransfer ALL patients from results to waiting list ?'),
				cancel_button = True
			)
			if not use_all:
				return
			data = self._LCTRL_result.data

		comment = self._PRW_report_name.GetValue().strip()
		for item in data:
			pat = gmPerson.cPerson(aPK_obj = item[pat_pk_key])
			pat.put_on_waiting_list (comment = comment, zone = zone)
Esempio n. 2
0
    def _on_waiting_list_button_pressed(self, event):
        event.Skip()

        pat_pk_key = self._LCTRL_result.patient_pk_data_key
        if pat_pk_key is None:
            gmGuiHelpers.gm_show_info(info=_(
                'These report results do not seem to contain per-patient data.'
            ),
                                      title=_('Using report results'))
            return

        zone = wx.GetTextFromUser(
            _('Enter a waiting zone to put patients in:'),
            caption=_('Using report results'),
            default_value=_('search results'))
        if zone.strip() == '':
            return

        data = self._LCTRL_result.get_selected_item_data(only_one=False)
        if data is None:
            use_all = gmGuiHelpers.gm_show_question(
                title=_('Using report results'),
                question=
                _('No results selected.\n\nTransfer ALL patients from results to waiting list ?'
                  ),
                cancel_button=True)
            if not use_all:
                return
            data = self._LCTRL_result.data

        comment = self._PRW_report_name.GetValue().strip()
        for item in data:
            pat = gmPerson.cPerson(aPK_obj=item[pat_pk_key])
            pat.put_on_waiting_list(comment=comment, zone=zone)
Esempio n. 3
0
def check_for_updates():

	dbcfg = gmCfg.cCfgSQL()

	url = dbcfg.get2 (
		option = u'horstspace.update.url',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'workplace',
		default = u'http://www.gnumed.de/downloads/gnumed-versions.txt'
	)

	consider_latest_branch = bool(dbcfg.get2 (
		option = u'horstspace.update.consider_latest_branch',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'workplace',
		default = True
	))

	_cfg = gmCfg2.gmCfgData()

	found, msg = gmNetworkTools.check_for_update (
		url = url,
		current_branch = _cfg.get(option = 'client_branch'),
		current_version = _cfg.get(option = 'client_version'),
		consider_latest_branch = consider_latest_branch
	)

	if found is False:
		gmDispatcher.send(signal = 'statustext', msg = _('Your client (%s) is up to date.') % _cfg.get(option = 'client_version'))
		return

	gmGuiHelpers.gm_show_info (
		msg,
		_('Checking for client updates')
	)
Esempio n. 4
0
def load_person_from_vcard_file():

	wildcards = '|'.join ([
		'%s (*.vcf)|*.vcf' % _('vcf files'),
		'%s (*.VCF)|*.VCF' % _('VCF files'),
		'%s (*)|*' % _('all files'),
		'%s (*.*)|*.*' % _('all files (Windows)')
	])

	dlg = wx.FileDialog (
		parent = wx.GetApp().GetTopWindow(),
		message = _('Choose a vCard file:'),
		defaultDir = os.path.join(gmTools.gmPaths().home_dir, 'gnumed'),
		wildcard = wildcards,
		style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
	)
	result = dlg.ShowModal()
	fname = dlg.GetPath()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return

	from Gnumed.business import gmVCard
	dto = gmVCard.parse_vcard2dto(filename = fname)
	if dto is None:
		gmDispatcher.send(signal='statustext', msg=_('[%s] does not seem to contain a vCard.') % fname)
		return

	idents = dto.get_candidate_identities(can_create = True)
	if len(idents) == 1:
		ident = idents[0]
		if not set_active_patient(patient = ident):
			gmGuiHelpers.gm_show_info (_(
				'Cannot activate patient:\n\n'
				'%s %s (%s)\n'
				'%s'
				) % (
					dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
				),
				_('Activating external patient')
			)
		return

	dlg = cSelectPersonFromListDlg(wx.GetApp().GetTopWindow(), -1)
	dlg.set_persons(persons = idents)
	result = dlg.ShowModal()
	ident = dlg.get_selected_person()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return
	if not set_active_patient(patient = ident):
		gmGuiHelpers.gm_show_info (_(
			'Cannot activate patient:\n\n'
			'%s %s (%s)\n'
			'%s'
			) % (
				dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
			),
			_('Activating external patient')
		)
Esempio n. 5
0
def load_person_from_vcard_file():

	wildcards = '|'.join ([
		'%s (*.vcf)|*.vcf' % _('vcf files'),
		'%s (*.VCF)|*.VCF' % _('VCF files'),
		'%s (*)|*' % _('all files'),
		'%s (*.*)|*.*' % _('all files (Windows)')
	])

	dlg = wx.FileDialog (
		parent = wx.GetApp().GetTopWindow(),
		message = _('Choose a vCard file:'),
		defaultDir = os.path.join(gmTools.gmPaths().home_dir, 'gnumed'),
		wildcard = wildcards,
		style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
	)
	result = dlg.ShowModal()
	fname = dlg.GetPath()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return

	from Gnumed.business import gmVCard
	dto = gmVCard.parse_vcard2dto(filename = fname)
	if dto is None:
		gmDispatcher.send(signal='statustext', msg=_('[%s] does not seem to contain a vCard.') % fname)
		return

	idents = dto.get_candidate_identities(can_create = True)
	if len(idents) == 1:
		ident = idents[0]
		if not set_active_patient(patient = ident):
			gmGuiHelpers.gm_show_info (_(
				'Cannot activate patient:\n\n'
				'%s %s (%s)\n'
				'%s'
				) % (
					dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
				),
				_('Activating external patient')
			)
		return

	dlg = cSelectPersonFromListDlg(wx.GetApp().GetTopWindow(), -1)
	dlg.set_persons(persons = idents)
	result = dlg.ShowModal()
	ident = dlg.get_selected_person()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return
	if not set_active_patient(patient = ident):
		gmGuiHelpers.gm_show_info (_(
			'Cannot activate patient:\n\n'
			'%s %s (%s)\n'
			'%s'
			) % (
				dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
			),
			_('Activating external patient')
		)
Esempio n. 6
0
	def _save_as_update(self):

		if len(self.__indications) == 0:
			gmGuiHelpers.gm_show_info (
				aTitle = _('Saving vaccine'),
				aMessage = _('You must select at least one indication.')
			)
			return False

		drug = self.data.brand
		drug['brand'] = self._PRW_brand.GetValue().strip()
		drug['is_fake_brand'] = self._CHBOX_fake.GetValue()
		val = self._PRW_atc.GetData()
		if val is not None:
			if val != u'J07':
				drug['atc'] = val.strip()
		drug.save()

		# the validator already asked for changes so just do it
		self.data.set_indications(pk_indications = [ i['id'] for i in self.__indications ])

#		self.data['is_live'] = self._CHBOX_live.GetValue()
		val = self._PRW_age_min.GetValue().strip()
		if val != u'':
			self.data['min_age'] = gmDateTime.str2interval(val)
		if val != u'':
			self.data['max_age'] = gmDateTime.str2interval(val)
		val = self._TCTRL_comment.GetValue().strip()
		if val != u'':
			self.data['comment'] = val

		self.data.save()
		return True
Esempio n. 7
0
def start_new_encounter(emr=None):
	emr.start_new_encounter()
	gmDispatcher.send(signal = 'statustext', msg = _('Started a new encounter for the active patient.'), beep = True)
	time.sleep(0.5)
	gmGuiHelpers.gm_show_info (
		_('\nA new encounter was started for the active patient.\n'),
		_('Start of new encounter')
	)
Esempio n. 8
0
def start_new_encounter(emr=None):
	emr.start_new_encounter()
	gmDispatcher.send(signal = 'statustext', msg = _('Started a new encounter for the active patient.'), beep = True)
	time.sleep(0.5)
	gmGuiHelpers.gm_show_info (
		_('\nA new encounter was started for the active patient.\n'),
		_('Start of new encounter')
	)
Esempio n. 9
0
def _signal_update_status(status):

	update_found, msg = status
	if update_found is False:
		_cfg = gmCfg2.gmCfgData()
		gmDispatcher.send(signal = 'statustext', msg = _('Your client (%s) is up to date.') % _cfg.get(option = 'client_version'))
		return

	gmGuiHelpers.gm_show_info(msg, _('Checking for client updates'))
Esempio n. 10
0
 def create_widget_on_test_kwd2(*args, **kwargs):
     msg = (
         "test keyword must have been typed...\n"
         "actually this would have to return a suitable wx.Window subclass instance\n"
     )
     for arg in args:
         msg = msg + "\narg ==> %s" % arg
     for key in kwargs.keys():
         msg = msg + "\n%s ==> %s" % (key, kwargs[key])
     gmGuiHelpers.gm_show_info(
         aMessage=msg, aTitle='msg box on create_widget from test_keyword')
Esempio n. 11
0
def __create_branch_for_praxis(pk_org_unit: int):
    branch = gmPraxis.create_praxis_branch(pk_org_unit=pk_org_unit)
    _log.debug(
        'auto-created praxis branch because only one organization without any unit existed: %s',
        branch)
    gmGuiHelpers.gm_show_info(title=_('Praxis configuration ...'),
                              info=_('GNUmed has auto-created the following\n'
                                     'praxis branch for you (which you can\n'
                                     'later configure as needed):\n'
                                     '\n'
                                     '%s') % branch.format())
    return branch
Esempio n. 12
0
def _signal_update_status(status):

	update_found, msg = status
	if update_found is False:
		_cfg = gmCfg2.gmCfgData()
		gmDispatcher.send(signal = 'statustext', msg = _('Your client (%s) is up to date.') % _cfg.get(option = 'client_version'))
		return

	gmGuiHelpers.gm_show_info (
		msg,
		_('Checking for client updates')
	)
Esempio n. 13
0
def search_narrative_across_emrs(parent=None):

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

	search_term_dlg = wx.TextEntryDialog (
		parent,
		_('Enter (regex) term to search for across all EMRs:'),
		caption = _('Text search across all EMRs'),
		style = wx.OK | wx.CANCEL | wx.CENTRE
	)
	result = search_term_dlg.ShowModal()

	if result != wx.ID_OK:
		return

	wx.BeginBusyCursor()
	search_term = search_term_dlg.GetValue()
	search_term_dlg.DestroyLater()
	results = gmClinNarrative.search_text_across_emrs(search_term = search_term)
	wx.EndBusyCursor()

	if len(results) == 0:
		gmGuiHelpers.gm_show_info (
			_(
			'Nothing found for search term:\n'
			' "%s"'
			) % search_term,
			_('Search results')
		)
		return

	items = [ [
		gmPerson.cPerson(aPK_obj = r['pk_patient'])['description_gender'],
		r['narrative'],
		r['src_table']
	] for r in results ]

	selected_patient = gmListWidgets.get_choices_from_list (
		parent = parent,
		caption = _('Search results for [%s]') % search_term,
		choices = items,
		columns = [_('Patient'), _('Match'), _('Match location')],
		data = [ r['pk_patient'] for r in results ],
		single_selection = True,
		can_return_empty = False
	)

	if selected_patient is None:
		return

	wx.CallAfter(set_active_patient, patient = gmPerson.cPerson(aPK_obj = selected_patient))
Esempio n. 14
0
def search_narrative_across_emrs(parent=None):

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

	search_term_dlg = wx.TextEntryDialog (
		parent,
		_('Enter (regex) term to search for across all EMRs:'),
		caption = _('Text search across all EMRs'),
		style = wx.OK | wx.CANCEL | wx.CENTRE
	)
	result = search_term_dlg.ShowModal()

	if result != wx.ID_OK:
		return

	wx.BeginBusyCursor()
	search_term = search_term_dlg.GetValue()
	search_term_dlg.DestroyLater()
	results = gmClinNarrative.search_text_across_emrs(search_term = search_term)
	wx.EndBusyCursor()

	if len(results) == 0:
		gmGuiHelpers.gm_show_info (
			_(
			'Nothing found for search term:\n'
			' "%s"'
			) % search_term,
			_('Search results')
		)
		return

	items = [ [
		gmPerson.cPerson(aPK_obj = r['pk_patient']).description_gender,
		r['narrative'],
		r['src_table']
	] for r in results ]

	selected_patient = gmListWidgets.get_choices_from_list (
		parent = parent,
		caption = _('Search results for [%s]') % search_term,
		choices = items,
		columns = [_('Patient'), _('Match'), _('Match location')],
		data = [ r['pk_patient'] for r in results ],
		single_selection = True,
		can_return_empty = False
	)

	if selected_patient is None:
		return

	wx.CallAfter(set_active_patient, patient = gmPerson.cPerson(aPK_obj = selected_patient))
Esempio n. 15
0
	def create_widget_on_test_kwd2(*args, **kwargs):
		msg = (
			"test keyword must have been typed...\n"
			"actually this would have to return a suitable wx.Window subclass instance\n"
		)
		for arg in args:
			msg = msg + "\narg ==> %s" % arg
		for key in kwargs.keys():
			msg = msg + "\n%s ==> %s" % (key, kwargs[key])
		gmGuiHelpers.gm_show_info (
			aMessage = msg,
			aTitle = 'msg box on create_widget from test_keyword'
		)
Esempio n. 16
0
    def _on_visualize_button_pressed(self, evt):

        try:
            # better fail early
            import Gnuplot
        except ImportError:
            gmGuiHelpers.gm_show_info(
                aMessage=_('Cannot import "Gnuplot" python module.'),
                aTitle=_('Query result visualizer'))
            return

        x_col = gmListWidgets.get_choices_from_list(
            parent=self,
            msg=_('Choose a column to be used as the X-Axis:'),
            caption=_('Choose column from query results ...'),
            choices=self.query_results[0].keys(),
            columns=[_('Column name')],
            single_selection=True)
        if x_col is None:
            return

        y_col = gmListWidgets.get_choices_from_list(
            parent=self,
            msg=_('Choose a column to be used as the Y-Axis:'),
            caption=_('Choose column from query results ...'),
            choices=self.query_results[0].keys(),
            columns=[_('Column name')],
            single_selection=True)
        if y_col is None:
            return

        # FIXME: support debugging (debug=1) depending on --debug
        gp = Gnuplot.Gnuplot(persist=1)
        if self._PRW_report_name.GetValue().strip() != '':
            gp.title(
                _('GNUmed report: %s') %
                self._PRW_report_name.GetValue().strip()[:40])
        else:
            gp.title(_('GNUmed report results'))
        gp.xlabel(x_col)
        gp.ylabel(y_col)
        try:
            gp.plot([[r[x_col], r[y_col]] for r in self.query_results])
        except Exception:
            _log.exception('unable to plot results from [%s:%s]' %
                           (x_col, y_col))
            gmDispatcher.send(signal='statustext',
                              msg=_('Error plotting data.'),
                              beep=True)
Esempio n. 17
0
def __create_praxis_and_branch():
    pk_cat = gmOrganization.create_org_category(category='Praxis')
    org = gmOrganization.create_org(_('Your praxis'), pk_cat)
    unit = org.add_unit(_('Your branch'))
    branch = gmPraxis.create_praxis_branch(pk_org_unit=unit['pk_org_unit'])
    _log.debug(
        'auto-created praxis and branch because no organizations existed: %s',
        branch)
    gmGuiHelpers.gm_show_info(title=_('Praxis configuration ...'),
                              info=_('GNUmed has auto-created the following\n'
                                     'praxis branch for you (which you can\n'
                                     'later configure as needed):\n'
                                     '\n'
                                     '%s') % branch.format())
    return branch
Esempio n. 18
0
	def _on_visualize_button_pressed(self, evt):

		try:
			# better fail early
			import Gnuplot
		except ImportError:
			gmGuiHelpers.gm_show_info (
				aMessage = _('Cannot import "Gnuplot" python module.'),
				aTitle = _('Query result visualizer')
			)
			return

		x_col = gmListWidgets.get_choices_from_list (
			parent = self,
			msg = _('Choose a column to be used as the X-Axis:'),
			caption = _('Choose column from query results ...'),
			choices = self.query_results[0].keys(),
			columns = [_('Column name')],
			single_selection = True
		)
		if x_col is None:
			return

		y_col = gmListWidgets.get_choices_from_list (
			parent = self,
			msg = _('Choose a column to be used as the Y-Axis:'),
			caption = _('Choose column from query results ...'),
			choices = self.query_results[0].keys(),
			columns = [_('Column name')],
			single_selection = True
		)
		if y_col is None:
			return

		# FIXME: support debugging (debug=1) depending on --debug
		gp = Gnuplot.Gnuplot(persist=1)
		if self._PRW_report_name.GetValue().strip() != '':
			gp.title(_('GNUmed report: %s') % self._PRW_report_name.GetValue().strip()[:40])
		else:
			gp.title(_('GNUmed report results'))
		gp.xlabel(x_col)
		gp.ylabel(y_col)
		try:
			gp.plot([ [r[x_col], r[y_col]] for r in self.query_results ])
		except Exception:
			_log.exception('unable to plot results from [%s:%s]' % (x_col, y_col))
			gmDispatcher.send(signal = 'statustext', msg = _('Error plotting data.'), beep = True)
Esempio n. 19
0
def __database_is_acceptable_for_use(require_version: bool = True,
                                     expected_version: int = None,
                                     login=None) -> bool:
    if not gmPG2.schema_exists(schema='gm'):
        _log.error('schema [gm] does not exist - database not bootstrapped ?')
        gmGuiHelpers.gm_show_error(msg_not_bootstrapped,
                                   _('Verifying database'))
        return False

    if not gmPG2.database_schema_compatible(version=expected_version):
        client_version = _cfg.get(option='client_version')
        connected_db_version = gmPG2.get_schema_version()
        msg = msg_generic % (client_version, connected_db_version,
                             expected_version,
                             gmTools.coalesce(login.host, '<localhost>'),
                             login.database, login.user)
        if require_version:
            gmGuiHelpers.gm_show_error(msg + '\n\n' + msg_fail,
                                       _('Verifying database version'))
            return False

        gmGuiHelpers.gm_show_info(msg + '\n\n' + msg_override,
                                  _('Verifying database version'))

    max_skew = 10 if _cfg.get(option='debug') else 1  # in minutes
    if not gmPG2.sanity_check_time_skew(tolerance=(max_skew * 60)):
        if not _cfg.get(option='debug'):
            gmGuiHelpers.gm_show_error(msg_time_skew_fail % max_skew,
                                       _('Verifying database settings'))
            return False

        gmGuiHelpers.gm_show_warning(msg_time_skew_warn % max_skew,
                                     _('Verifying database settings'))

    sanity_level, message = gmPG2.sanity_check_database_settings()
    if sanity_level != 0:
        gmGuiHelpers.gm_show_error((msg_insanity % message),
                                   _('Verifying database settings'))
        if sanity_level == 2:
            return False

    gmLog2.log_multiline(logging.DEBUG,
                         message='DB seems suitable to use, fingerprint:',
                         text=gmPG2.get_db_fingerprint(eol='\n'))

    return True
Esempio n. 20
0
	def _on_activate_button_pressed(self, evt):
		self.__id_most_recently_activated_patient = None
		item = self._LCTRL_patients.get_selected_item_data(only_one=True)
		if item is None:
			return
		try:
			pat = gmPerson.cPerson(aPK_obj = item['pk_identity'])
		except gmExceptions.ConstructorError:
			gmGuiHelpers.gm_show_info (
				aTitle = _('Waiting list'),
				aMessage = _('Cannot activate patient.\n\nIt has probably been disabled.')
			)
			return
		curr_pat = gmPerson.gmCurrentPatient()
		if curr_pat.connected:
			if curr_pat.ID == item['pk_identity']:
				return
		wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
Esempio n. 21
0
	def _on_activate_button_pressed(self, evt):
		self.__id_most_recently_activated_patient = None
		item = self._LCTRL_patients.get_selected_item_data(only_one=True)
		if item is None:
			return
		try:
			pat = gmPerson.cPerson(aPK_obj = item['pk_identity'])
		except gmExceptions.ConstructorError:
			gmGuiHelpers.gm_show_info (
				aTitle = _('Waiting list'),
				aMessage = _('Cannot activate patient.\n\nIt has probably been disabled.')
			)
			return
		curr_pat = gmPerson.gmCurrentPatient()
		if curr_pat.connected:
			if curr_pat.ID == item['pk_identity']:
				return
		wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
Esempio n. 22
0
	def _save_as_new(self):

		if len(self.__indications) == 0:
			gmGuiHelpers.gm_show_info (
				aTitle = _('Saving vaccine'),
				aMessage = _('You must select at least one indication.')
			)
			return False

		# save the data as a new instance
		data = gmVaccination.create_vaccine (
			pk_brand = self._PRW_brand.GetData(),
			brand_name = self._PRW_brand.GetValue(),
			pk_indications = [ i['id'] for i in self.__indications ]
		)

#		data['is_live'] = self._CHBOX_live.GetValue()
		val = self._PRW_age_min.GetValue().strip()
		if val != u'':
			data['min_age'] = gmDateTime.str2interval(val)
		val = self._PRW_age_max.GetValue().strip()
		if val != u'':
			data['max_age'] = gmDateTime.str2interval(val)
		val = self._TCTRL_comment.GetValue().strip()
		if val != u'':
			data['comment'] = val

		data.save()

		drug = data.brand
		drug['is_fake_brand'] = self._CHBOX_fake.GetValue()
		val = self._PRW_atc.GetData()
		if val is not None:
			if val != u'J07':
				drug['atc'] = val.strip()
		drug.save()

		# must be done very late or else the property access
		# will refresh the display such that later field
		# access will return empty values
		self.data = data

		return True
Esempio n. 23
0
	def __save_new_from_indications(self):

		if len(self.__indications) == 0:
			gmGuiHelpers.gm_show_info (
				aTitle = _('Saving vaccination'),
				aMessage = _('You must select at least one indication.')
			)
			return False

		vaccine = gmVaccination.map_indications2generic_vaccine(indications = [ i['description'] for i in self.__indications ])

		if vaccine is None:
			for ind in self.__indications:
				vaccine = gmVaccination.map_indications2generic_vaccine(indications = [ind['description']])
				data = self.__save_new_from_vaccine(vaccine = vaccine['pk_vaccine'])
		else:
			data = self.__save_new_from_vaccine(vaccine = vaccine['pk_vaccine'])

		return data
Esempio n. 24
0
	def _on_activateplus_button_pressed(self, evt):
		item = self._LCTRL_patients.get_selected_item_data(only_one=True)
		if item is None:
			return
		try:
			pat = gmPerson.cPerson(aPK_obj = item['pk_identity'])
		except gmExceptions.ConstructorError:
			gmGuiHelpers.gm_show_info (
				aTitle = _('Waiting list'),
				aMessage = _('Cannot activate patient.\n\nIt has probably been disabled.')
			)
			return
		self.__id_most_recently_activated_patient = item['pk_identity']
		self.__comment_most_recently_activated_patient = gmTools.coalesce(item['comment'], '').strip()
		gmPraxis.gmCurrentPraxisBranch().remove_from_waiting_list(pk = item['pk_waiting_list'])
		curr_pat = gmPerson.gmCurrentPatient()
		if curr_pat.connected:
			if curr_pat.ID == item['pk_identity']:
				return
		wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
Esempio n. 25
0
	def _on_activateplus_button_pressed(self, evt):
		item = self._LCTRL_patients.get_selected_item_data(only_one=True)
		if item is None:
			return
		try:
			pat = gmPerson.cPerson(aPK_obj = item['pk_identity'])
		except gmExceptions.ConstructorError:
			gmGuiHelpers.gm_show_info (
				aTitle = _('Waiting list'),
				aMessage = _('Cannot activate patient.\n\nIt has probably been disabled.')
			)
			return
		self.__id_most_recently_activated_patient = item['pk_identity']
		self.__comment_most_recently_activated_patient = gmTools.coalesce(item['comment'], '').strip()
		gmPraxis.gmCurrentPraxisBranch().remove_from_waiting_list(pk = item['pk_waiting_list'])
		curr_pat = gmPerson.gmCurrentPatient()
		if curr_pat.connected:
			if curr_pat.ID == item['pk_identity']:
				return
		wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
Esempio n. 26
0
	def delete(vaccine=None):
		deleted = gmVaccination.delete_vaccine(vaccine = vaccine['pk_vaccine'])
		if deleted:
			return True

		gmGuiHelpers.gm_show_info (
			_(
				'Cannot delete vaccine\n'
				'\n'
				' %s - %s (#%s)\n'
				'\n'
				'It is probably documented in a vaccination.'
			) % (
				vaccine['vaccine'],
				vaccine['preparation'],
				vaccine['pk_vaccine']
			),
			_('Deleting vaccine')
		)

		return False
Esempio n. 27
0
def load_person_from_xml_linuxmednews_via_clipboard():

	fname = gmGuiHelpers.clipboard2file()
	if fname in [None, False]:
		gmGuiHelpers.gm_show_info (
			info = _('No patient in clipboard.'),
			title = _('Activating external patient')
		)
		return

	from Gnumed.business import gmLinuxMedNewsXML
	dto = gmLinuxMedNewsXML.parse_xml_linuxmednews(filename = fname)
	if dto is None:
		gmDispatcher.send(signal='statustext', msg=_('Clipboard does not seem to contain LinuxMedNews XML.'))
		return

	idents = dto.get_candidate_identities(can_create = True)
	if len(idents) == 1:
		ident = idents[0]
		if not set_active_patient(patient = ident):
			gmGuiHelpers.gm_show_info (_(
				'Cannot activate patient:\n\n'
				'%s %s (%s)\n'
				'%s'
				) % (
					dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
				),
				_('Activating external patient')
			)
		return

	dlg = cSelectPersonFromListDlg(wx.GetApp().GetTopWindow(), -1)
	dlg.set_persons(persons = idents)
	result = dlg.ShowModal()
	ident = dlg.get_selected_person()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return None
	if not set_active_patient(patient = ident):
		gmGuiHelpers.gm_show_info (_(
			'Cannot activate patient:\n\n'
			'%s %s (%s)\n'
			'%s'
			) % (
				dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
			),
			_('Activating external patient')
		)
Esempio n. 28
0
def load_person_from_xml_linuxmednews_via_clipboard():

	fname = gmGuiHelpers.clipboard2file()
	if fname in [None, False]:
		gmGuiHelpers.gm_show_info (
			info = _('No patient in clipboard.'),
			title = _('Activating external patient')
		)
		return

	from Gnumed.business import gmLinuxMedNewsXML
	dto = gmLinuxMedNewsXML.parse_xml_linuxmednews(filename = fname)
	if dto is None:
		gmDispatcher.send(signal='statustext', msg=_('Clipboard does not seem to contain LinuxMedNews XML.'))
		return

	idents = dto.get_candidate_identities(can_create = True)
	if len(idents) == 1:
		ident = idents[0]
		if not set_active_patient(patient = ident):
			gmGuiHelpers.gm_show_info (_(
				'Cannot activate patient:\n\n'
				'%s %s (%s)\n'
				'%s'
				) % (
					dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
				),
				_('Activating external patient')
			)
		return

	dlg = cSelectPersonFromListDlg(wx.GetApp().GetTopWindow(), -1)
	dlg.set_persons(persons = idents)
	result = dlg.ShowModal()
	ident = dlg.get_selected_person()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return None
	if not set_active_patient(patient = ident):
		gmGuiHelpers.gm_show_info (_(
			'Cannot activate patient:\n\n'
			'%s %s (%s)\n'
			'%s'
			) % (
				dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
			),
			_('Activating external patient')
		)
Esempio n. 29
0
	def _on_merge_button_pressed(self, event):

		if self._TCTRL_patient1.person is None:
			gmDispatcher.send(signal = 'statustext', msg = _('No patient selected on the left.'), beep = True)
			return

		if self._TCTRL_patient2.person is None:
			gmDispatcher.send(signal = 'statustext', msg = _('No patient selected on the right.'), beep = True)
			return

		if self._RBTN_patient1.GetValue():
			patient2keep = self._TCTRL_patient1.person
			patient2merge = self._TCTRL_patient2.person
		else:
			patient2keep = self._TCTRL_patient2.person
			patient2merge = self._TCTRL_patient1.person

		if patient2merge['lastnames'] == 'Kirk':
			if _cfg.get(option = 'debug'):
				gmNetworkTools.open_url_in_browser(url = 'http://en.wikipedia.org/wiki/File:Picard_as_Locutus.jpg')
				gmGuiHelpers.gm_show_info(_('\n\nYou will be assimilated.\n\n'), _('The Borg'))
				return
			else:
				gmDispatcher.send(signal = 'statustext', msg = _('Cannot merge Kirk into another patient.'), beep = True)
				return

		doit = gmGuiHelpers.gm_show_question (
			aMessage = _(
				'Are you positively sure you want to merge patient\n\n'
				' #%s: %s (%s, %s)\n\n'
				'into patient\n\n'
				' #%s: %s (%s, %s) ?\n\n'
				'Note that this action can ONLY be reversed by a laborious\n'
				'manual process requiring in-depth knowledge about databases\n'
				'and the patients in question !\n'
			) % (
				patient2merge.ID,
				patient2merge['description_gender'],
				patient2merge['gender'],
				patient2merge.get_formatted_dob(format = '%Y %b %d'),
				patient2keep.ID,
				patient2keep['description_gender'],
				patient2keep['gender'],
				patient2keep.get_formatted_dob(format = '%Y %b %d')
			),
			aTitle = _('Merging patients: confirmation'),
			cancel_button = False
		)
		if not doit:
			return

		conn = gmAuthWidgets.get_dbowner_connection(procedure = _('Merging patients'))
		if conn is None:
			gmDispatcher.send(signal = 'statustext', msg = _('Cannot merge patients without admin access.'), beep = True)
			return

		success, msg = patient2keep.assimilate_identity(other_identity = patient2merge, link_obj = conn)
		conn.close()
		if not success:
			gmDispatcher.send(signal = 'statustext', msg = msg, beep = True)
			return

		msg = _(
			'The patient\n'
			'\n'
			' #%s: %s (%s, %s)\n'
			'\n'
			'has successfully been merged into\n'
			'\n'
			' #%s: %s (%s, %s)'
		) % (
			patient2merge.ID,
			patient2merge['description_gender'],
			patient2merge['gender'],
			patient2merge.get_formatted_dob(format = '%Y %b %d'),
			patient2keep.ID,
			patient2keep['description_gender'],
			patient2keep['gender'],
			patient2keep.get_formatted_dob(format = '%Y %b %d')
		)
		title = _('Merging patients: success')

		curr_pat = gmPerson.gmCurrentPatient()
		# announce success
		if (curr_pat.connected) and (patient2keep.ID == curr_pat.ID):
			gmGuiHelpers.gm_show_info(aMessage = msg, aTitle = title)
		# and offer to activate kept patient if not active
		else:
			msg = msg + (
			'\n\n\n'
			'Do you want to activate that patient\n'
			'now for further modifications ?\n'
			)
			doit = gmGuiHelpers.gm_show_question (
				aMessage = msg,
				aTitle = title,
				cancel_button = False
			)
			if doit:
				wx.CallAfter(set_active_patient, patient = patient2keep)

		if self.IsModal():
			self.EndModal(wx.ID_OK)
		else:
			self.Close()
Esempio n. 30
0
def get_person_from_external_sources(parent=None, search_immediately=False, activate_immediately=False):
	"""Load patient from external source.

	- scan external sources for candidates
	- let user select source
	  - if > 1 available: always
	  - if only 1 available: depending on search_immediately
	- search for patients matching info from external source
	- if more than one match:
	  - let user select patient
	- if no match:
	  - create patient
	- activate patient
	"""
	# get DTOs from interfaces
	dtos = []
	dtos.extend(load_persons_from_xdt())
	dtos.extend(load_persons_from_pracsoft_au())
	dtos.extend(load_persons_from_kvks())
	dtos.extend(load_persons_from_ca_msva())

	# no external persons
	if len(dtos) == 0:
		gmDispatcher.send(signal='statustext', msg=_('No patients found in external sources.'))
		return None

	# one external patient with DOB - already active ?
	if (len(dtos) == 1) and (dtos[0]['dto'].dob is not None):
		dto = dtos[0]['dto']
		# is it already the current patient ?
		curr_pat = gmPerson.gmCurrentPatient()
		if curr_pat.connected:
			key_dto = dto.firstnames + dto.lastnames + dto.dob.strftime('%Y-%m-%d') + dto.gender
			names = curr_pat.get_active_name()
			key_pat = names['firstnames'] + names['lastnames'] + curr_pat.get_formatted_dob(format = '%Y-%m-%d') + curr_pat['gender']
			_log.debug('current patient: %s' % key_pat)
			_log.debug('dto patient    : %s' % key_dto)
			if key_dto == key_pat:
				gmDispatcher.send(signal='statustext', msg=_('The only external patient is already active in GNUmed.'), beep=False)
				return None

	# one external person - look for internal match immediately ?
	if (len(dtos) == 1) and search_immediately:
		dto = dtos[0]['dto']

	# several external persons
	else:
		if parent is None:
			parent = wx.GetApp().GetTopWindow()
		dlg = cSelectPersonDTOFromListDlg(parent=parent, id=-1)
		dlg.set_dtos(dtos=dtos)
		result = dlg.ShowModal()
		if result == wx.ID_CANCEL:
			return None
		dto = dlg.get_selected_dto()['dto']
		dlg.DestroyLater()

	# search
	idents = dto.get_candidate_identities(can_create=True)
	if idents is None:
		gmGuiHelpers.gm_show_info (_(
			'Cannot create new patient:\n\n'
			' [%s %s (%s), %s]'
			) % (
				dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
			),
			_('Activating external patient')
		)
		return None

	if len(idents) == 1:
		ident = idents[0]

	if len(idents) > 1:
		if parent is None:
			parent = wx.GetApp().GetTopWindow()
		dlg = cSelectPersonFromListDlg(parent=parent, id=-1)
		dlg.set_persons(persons=idents)
		result = dlg.ShowModal()
		ident = dlg.get_selected_person()
		dlg.DestroyLater()
		if result == wx.ID_CANCEL:
			return None

	if activate_immediately:
		if not set_active_patient(patient = ident):
			gmGuiHelpers.gm_show_info (_(
				'Cannot activate patient:\n\n'
				'%s %s (%s)\n'
				'%s'
				) % (
					dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
				),
				_('Activating external patient')
			)
			return None

	dto.import_extra_data(identity = ident)
	dto.delete_from_source()

	return ident
Esempio n. 31
0
	def _on_merge_button_pressed(self, event):

		if self._TCTRL_patient1.person is None:
			gmDispatcher.send(signal = 'statustext', msg = _('No patient selected on the left.'), beep = True)
			return

		if self._TCTRL_patient2.person is None:
			gmDispatcher.send(signal = 'statustext', msg = _('No patient selected on the right.'), beep = True)
			return

		if self._RBTN_patient1.GetValue():
			patient2keep = self._TCTRL_patient1.person
			patient2merge = self._TCTRL_patient2.person
		else:
			patient2keep = self._TCTRL_patient2.person
			patient2merge = self._TCTRL_patient1.person

		if patient2merge['lastnames'] == 'Kirk':
			if _cfg.get(option = 'debug'):
				gmNetworkTools.open_url_in_browser(url = 'http://en.wikipedia.org/wiki/File:Picard_as_Locutus.jpg')
				gmGuiHelpers.gm_show_info(_('\n\nYou will be assimilated.\n\n'), _('The Borg'))
				return
			else:
				gmDispatcher.send(signal = 'statustext', msg = _('Cannot merge Kirk into another patient.'), beep = True)
				return

		doit = gmGuiHelpers.gm_show_question (
			aMessage = _(
				'Are you positively sure you want to merge patient\n\n'
				' #%s: %s (%s, %s)\n\n'
				'into patient\n\n'
				' #%s: %s (%s, %s) ?\n\n'
				'Note that this action can ONLY be reversed by a laborious\n'
				'manual process requiring in-depth knowledge about databases\n'
				'and the patients in question !\n'
			) % (
				patient2merge.ID,
				patient2merge['description_gender'],
				patient2merge['gender'],
				patient2merge.get_formatted_dob(format = '%Y %b %d'),
				patient2keep.ID,
				patient2keep['description_gender'],
				patient2keep['gender'],
				patient2keep.get_formatted_dob(format = '%Y %b %d')
			),
			aTitle = _('Merging patients: confirmation'),
			cancel_button = False
		)
		if not doit:
			return

		conn = gmAuthWidgets.get_dbowner_connection(procedure = _('Merging patients'))
		if conn is None:
			gmDispatcher.send(signal = 'statustext', msg = _('Cannot merge patients without admin access.'), beep = True)
			return

		success, msg = patient2keep.assimilate_identity(other_identity = patient2merge, link_obj = conn)
		conn.close()
		if not success:
			gmDispatcher.send(signal = 'statustext', msg = msg, beep = True)
			return

		msg = _(
			'The patient\n'
			'\n'
			' #%s: %s (%s, %s)\n'
			'\n'
			'has successfully been merged into\n'
			'\n'
			' #%s: %s (%s, %s)'
		) % (
			patient2merge.ID,
			patient2merge['description_gender'],
			patient2merge['gender'],
			patient2merge.get_formatted_dob(format = '%Y %b %d'),
			patient2keep.ID,
			patient2keep['description_gender'],
			patient2keep['gender'],
			patient2keep.get_formatted_dob(format = '%Y %b %d')
		)
		title = _('Merging patients: success')

		curr_pat = gmPerson.gmCurrentPatient()
		# announce success
		if (curr_pat.connected) and (patient2keep.ID == curr_pat.ID):
			gmGuiHelpers.gm_show_info(aMessage = msg, aTitle = title)
		# and offer to activate kept patient if not active
		else:
			msg = msg + (
			'\n\n\n'
			'Do you want to activate that patient\n'
			'now for further modifications ?\n'
			)
			doit = gmGuiHelpers.gm_show_question (
				aMessage = msg,
				aTitle = title,
				cancel_button = False
			)
			if doit:
				wx.CallAfter(set_active_patient, patient = patient2keep)

		if self.IsModal():
			self.EndModal(wx.ID_OK)
		else:
			self.Close()
Esempio n. 32
0
def load_persons_from_xdt():

	bdt_files = []

	# some can be auto-detected
	# MCS/Isynet: $DRIVE:\Winacs\TEMP\BDTxx.tmp where xx is the workplace
	candidates = []
	drives = 'cdefghijklmnopqrstuvwxyz'
	for drive in drives:
		candidate = drive + ':\Winacs\TEMP\BDT*.tmp'
		candidates.extend(glob.glob(candidate))
	for candidate in candidates:
		path, filename = os.path.split(candidate)
		# FIXME: add encoding !
		bdt_files.append({'file': candidate, 'source': 'MCS/Isynet %s' % filename[-6:-4]})

	# some need to be configured
	# aggregate sources
	src_order = [
		('explicit', 'return'),
		('workbase', 'append'),
		('local', 'append'),
		('user', 'append'),
		('system', 'append')
	]
	xdt_profiles = _cfg.get (
		group = 'workplace',
		option = 'XDT profiles',
		source_order = src_order
	)
	if xdt_profiles is None:
		return []

	# first come first serve
	src_order = [
		('explicit', 'return'),
		('workbase', 'return'),
		('local', 'return'),
		('user', 'return'),
		('system', 'return')
	]
	for profile in xdt_profiles:
		name = _cfg.get (
			group = 'XDT profile %s' % profile,
			option = 'filename',
			source_order = src_order
		)
		if name is None:
			_log.error('XDT profile [%s] does not define a <filename>' % profile)
			continue
		encoding = _cfg.get (
			group = 'XDT profile %s' % profile,
			option = 'encoding',
			source_order = src_order
		)
		if encoding is None:
			_log.warning('xDT source profile [%s] does not specify an <encoding> for BDT file [%s]' % (profile, name))
		source = _cfg.get (
			group = 'XDT profile %s' % profile,
			option = 'source',
			source_order = src_order
		)
		dob_format = _cfg.get (
			group = 'XDT profile %s' % profile,
			option = 'DOB format',
			source_order = src_order
		)
		if dob_format is None:
			_log.warning('XDT profile [%s] does not define a date of birth format in <DOB format>' % profile)
		bdt_files.append({'file': name, 'source': source, 'encoding': encoding, 'dob_format': dob_format})

	dtos = []
	for bdt_file in bdt_files:
		try:
			# FIXME: potentially return several persons per file
			dto = gmPerson.get_person_from_xdt (
				filename = bdt_file['file'],
				encoding = bdt_file['encoding'],
				dob_format = bdt_file['dob_format']
			)

		except IOError:
			gmGuiHelpers.gm_show_info (
				_(
				'Cannot access BDT file\n\n'
				' [%s]\n\n'
				'to import patient.\n\n'
				'Please check your configuration.'
				) % bdt_file,
				_('Activating xDT patient')
			)
			_log.exception('cannot access xDT file [%s]' % bdt_file['file'])
			continue
		except Exception:
			gmGuiHelpers.gm_show_error (
				_(
				'Cannot load patient from BDT file\n\n'
				' [%s]'
				) % bdt_file,
				_('Activating xDT patient')
			)
			_log.exception('cannot read patient from xDT file [%s]' % bdt_file['file'])
			continue

		dtos.append({'dto': dto, 'source': gmTools.coalesce(bdt_file['source'], dto.source)})

	return dtos
Esempio n. 33
0
def search_narrative_in_emr(parent=None, patient=None):

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

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

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

	search_term_dlg = wx.TextEntryDialog (
		parent,
		_('Enter search term:'),
		caption = _('Text search of entire EMR of active patient'),
		style = wx.OK | wx.CANCEL | wx.CENTRE
	)
	result = search_term_dlg.ShowModal()

	if result != wx.ID_OK:
		search_term_dlg.DestroyLater()
		return False

	wx.BeginBusyCursor()
	val = search_term_dlg.GetValue()
	search_term_dlg.DestroyLater()
	emr = patient.emr
	rows = emr.search_narrative_simple(val)
	wx.EndBusyCursor()

	if len(rows) == 0:
		gmGuiHelpers.gm_show_info (
			_(
			'Nothing found for search term:\n'
			' "%s"'
			) % val,
			_('Search results')
		)
		return True

	txt = ''
	for row in rows:
		txt += '%s: %s\n' % (
			row['soap_cat'],
			row['narrative']
		)

		txt += ' %s: %s - %s %s\n' % (
			_('Encounter'),
			row['encounter_started'].strftime('%x %H:%M'),
			row['encounter_ended'].strftime('%H:%M'),
			row['encounter_type']
		)
		txt += ' %s: %s\n' % (
			_('Episode'),
			row['episode']
		)
		txt += ' %s: %s\n\n' % (
			_('Health issue'),
			row['health_issue']
		)

	msg = _(
		'Search term was: "%s"\n'
		'\n'
		'Search results:\n\n'
		'%s\n'
	) % (val, txt)

	dlg = wx.MessageDialog (
		parent = parent,
		message = msg,
		caption = _('Search results for [%s]') % val,
		style = wx.OK | wx.STAY_ON_TOP
	)
	dlg.ShowModal()
	dlg.DestroyLater()

	return True
Esempio n. 34
0
def _ask_for_encounter_continuation(new_encounter=None,
                                    fairly_recent_encounter=None):
    """This is used as the callback when the EMR detects that the
	   patient was here rather recently and wants to ask the
	   provider whether to continue the recent encounter.
	"""
    # better safe than sorry
    if new_encounter['pk_patient'] != fairly_recent_encounter['pk_patient']:
        raise ValueError(
            'pk_patient values on new (enc=%s pat=%s) and fairly-recent (enc=%s pat=%s) encounter do not match'
            % (new_encounter['pk_encounter'], new_encounter['pk_patient'],
               fairly_recent_encounter['pk_encounter'],
               fairly_recent_encounter['pk_patient']))

    # only pester user if current patient is concerned
    curr_pat = gmPerson.gmCurrentPatient()
    if new_encounter['pk_patient'] != curr_pat.ID:
        return

    # ask user
    msg = _('%s, %s  [#%s]\n'
            '\n'
            "This patient's chart was worked on only recently:\n"
            '\n'
            ' %s'
            '\n'
            'Do you want to continue that consultation ?\n'
            ' (If not a new one will be used.)\n') % (
                curr_pat.get_description_gender(with_nickname=False),
                gmDateTime.pydt_strftime(curr_pat['dob'],
                                         '%Y %b %d'), curr_pat.ID,
                fairly_recent_encounter.format(episodes=None,
                                               with_soap=False,
                                               left_margin=1,
                                               patient=None,
                                               issues=None,
                                               with_docs=False,
                                               with_tests=False,
                                               fancy_header=False,
                                               with_vaccinations=False,
                                               with_rfe_aoe=True,
                                               with_family_history=False,
                                               with_co_encountlet_hints=False,
                                               by_episode=False))
    dlg = gmGuiHelpers.c2ButtonQuestionDlg(
        parent=None,
        id=-1,
        caption=_('Pulling chart'),
        question=msg,
        button_defs=[{
            'label': _('Continue recent'),
            'tooltip': _('Continue the existing recent encounter.'),
            'default': False
        }, {
            'label':
            _('Start new'),
            'tooltip':
            _('Start a new encounter. The existing one will be closed.'),
            'default':
            True
        }],
        show_checkbox=False)
    result = dlg.ShowModal()
    dlg.DestroyLater()

    # switch encounters
    if result == wx.ID_YES:
        _log.info('user wants to continue fairly-recent encounter')
        curr_pat.emr.active_encounter = fairly_recent_encounter
        if new_encounter.transfer_all_data_to_another_encounter(
                pk_target_encounter=fairly_recent_encounter['pk_encounter']):
            if not gmEMRStructItems.delete_encounter(
                    pk_encounter=new_encounter['pk_encounter']):
                gmGuiHelpers.gm_show_info(
                    _('Properly switched to fairly recent encounter but unable to delete newly-created encounter.'
                      ), _('Pulling chart'))
        else:
            gmGuiHelpers.gm_show_info(
                _('Unable to transfer the data from newly-created to fairly recent encounter.'
                  ), _('Pulling chart'))
        return

    _log.debug('stayed with newly created encounter')
Esempio n. 35
0
def import_amts_bmp(parent=None,
                    bmp_filename: str = None) -> typing.Union[bool, None]:
    if bmp_filename is None:
        dlg = wx.FileDialog(parent=parent,
                            message=_('Choose an AMTS BMP medication plan.'),
                            defaultDir=os.path.expanduser(
                                os.path.join('~', 'gnumed')),
                            defaultFile='',
                            wildcard="%s (*.xml)|*.xml|%s (*)|*" %
                            (_('BMP files'), _('all files')),
                            style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        result = dlg.ShowModal()
        if result == wx.ID_CANCEL:
            return None
        bmp_filename = dlg.GetPath()
        dlg.DestroyLater()

    dlg_title = _('Importing AMTS BMP Medikationsplan')
    bmp = gmAMTS_BMP.cAmtsBmpFile(bmp_filename)
    if not bmp.valid():
        gmGuiHelpers.gm_show_error(
            title=dlg_title,
            error=_('The file\n'
                    '\n'
                    ' [%s]\n'
                    '\n'
                    'does not seem to be a Medikationsplan.') % bmp_filename)
        return False

    dto = bmp.patient_as_dto
    person = dto.unambiguous_identity
    if person is None:
        candidates = dto.candidate_identities
        if len(candidates) == 0:
            # no match found -> ask for creation or ask whether to import for the current patient
            curr_pat = gmPerson.gmCurrentPatient()
            if curr_pat.is_connected:
                gmGuiHelpers.c3ButtonQuestionDlg(
                    parent=parent,
                    caption=dlg_title,
                    question=_('No matching patient found in GNUmed.\n'
                               '\n'
                               'The patient in the Medikationsplan is:\n'
                               '\n'
                               ' %s\n'
                               '\n'
                               'Do you want to create that patient ?') %
                    dto.format(),
                    button_defs=[])
            else:
                gmGuiHelpers.gm_show_question(
                    title=dlg_title,
                    question=_('No matching patient found in GNUmed.\n'
                               '\n'
                               'The patient in the Medikationsplan is:\n'
                               '\n'
                               ' %s\n'
                               '\n'
                               'Do you want to create that patient ?') %
                    dto.format())

        elif len(candidates) == 1:
            # one match found -> ask whether to import
            pass
        else:
            # several found -> ask which to use
            pass

#		msg = _('None or several matching patients found.')
#		gmGuiHelpers.gm_show_info (
#			title = _('Importing AMTS BMP Medikationsplan'),
#			info = msg + '\n\n' + bmp.format(eol = '\n')
#		)
    else:
        gmGuiHelpers.gm_show_info(
            title=_('Importing AMTS BMP Medikationsplan'),
            info=bmp.format(eol='\n'))
    return True
Esempio n. 36
0
    def _on_save_items_button_pressed(self, event):
        event.Skip()

        items = self._LCTRL_items.get_selected_item_data(only_one=False)
        if len(items) == 0:
            items = self._LCTRL_items.get_item_data()

        dlg = wx.DirDialog(
            self,
            message=_(
                'Select the directory into which to export the documents.'),
            defaultPath=os.path.join(gmTools.gmPaths().home_dir, 'gnumed'))
        choice = dlg.ShowModal()
        path = dlg.GetPath()
        if choice != wx.ID_OK:
            return True

        if not gmTools.dir_is_empty(path):
            reuse_nonempty_dir = gmGuiHelpers.gm_show_question(
                title=_(u'Saving export area documents'),
                question=_(
                    u'The chosen export directory\n'
                    u'\n'
                    u' [%s]\n'
                    u'\n'
                    u'already contains files. Do you still want to save the\n'
                    u'selected export area documents into that directory ?\n'
                    u'\n'
                    u'(this is useful for including the external documents\n'
                    u' already stored in or below this directory)\n'
                    u'\n'
                    u'[NO] will create a subdirectory for you and use that.') %
                path,
                cancel_button=True)
            if reuse_nonempty_dir is None:
                return True
            if reuse_nonempty_dir is False:
                path = gmTools.mk_sandbox_dir(
                    prefix=u'export-%s-' % gmPerson.gmCurrentPatient().dirname,
                    base_dir=path)

        include_metadata = gmGuiHelpers.gm_show_question(
            title=_(u'Saving export area documents'),
            question=_(u'Create descriptive metadata files\n'
                       u'and save them alongside the\n'
                       u'selected export area documents ?'),
            cancel_button=True)
        if include_metadata is None:
            return True

        export_dir = gmPerson.gmCurrentPatient().export_area.export(
            base_dir=path, items=items, with_metadata=include_metadata)

        self.save_soap_note(
            soap=_('Saved to [%s]:\n - %s') %
            (export_dir, u'\n - '.join([i['description'] for i in items])))

        title = _('Saving export area documents')
        msg = _('Saved documents into directory:\n\n %s') % export_dir
        if include_metadata:
            browse_index = gmGuiHelpers.gm_show_question(
                title=title,
                question=msg + u'\n\n' + _('Browse patient data pack ?'),
                cancel_button=False)
            if browse_index:
                gmNetworkTools.open_url_in_browser(
                    url=u'file://%s' % os.path.join(export_dir, u'index.html'))
        else:
            gmGuiHelpers.gm_show_info(title=title, info=msg)

        return True
Esempio n. 37
0
	def _on_run_button_pressed(self, evt):

		self._BTN_visualize.Enable(False)
		self._BTN_waiting_list.Enable(False)
		self._BTN_save_results.Enable(False)

		user_query = self._TCTRL_query.GetValue().strip().strip(';')
		if user_query == '':
			return True

		limit = 1001
		pat = None
		curr_pat = gmPerson.gmCurrentPatient()
		if curr_pat.connected:
			pat = curr_pat.ID
		success, hint, cols, rows = gmDataMining.run_report_query (
			query = user_query,
			limit = limit,
			pk_identity = pat
		)

		self._LCTRL_result.set_columns()

		if len(rows) == 0:
			self._LCTRL_result.set_columns([_('Results')])
			self._LCTRL_result.set_string_items([[_('Report returned no data.')]])
			self._LCTRL_result.set_column_widths()
			gmDispatcher.send('statustext', msg = _('No data returned for this report.'), beep = True)
			return True

		gmDispatcher.send(signal = 'statustext', msg = _('Found %s results.') % len(rows))

		if len(rows) == 1001:
			gmGuiHelpers.gm_show_info (
				aMessage = _(
					'This query returned at least %s results.\n'
					'\n'
					'GNUmed will only show the first %s rows.\n'
					'\n'
					'You may want to narrow down the WHERE conditions\n'
					'or use LIMIT and OFFSET to batchwise go through\n'
					'all the matching rows.'
				) % (limit, limit-1),
				aTitle = _('Report Generator')
			)
			rows = rows[:-1]		# make it true :-)

		self._LCTRL_result.set_columns(cols)
		for row in rows:
			try:
				label = str(gmTools.coalesce(row[0], '')).replace('\n', '<LF>').replace('\r', '<CR>')
			except UnicodeDecodeError:
				label = _('not str()able')
			if len(label) > 150:
				label = label[:150] + gmTools.u_ellipsis
			row_num = self._LCTRL_result.InsertItem(sys.maxsize, label = label)
			for col_idx in range(1, len(row)):
				try:
					label = str(gmTools.coalesce(row[col_idx], '')).replace('\n', '<LF>').replace('\r', '<CR>')[:250]
				except UnicodeDecodeError:
					label = _('not str()able')
				if len(label) > 150:
					label = label[:150] + gmTools.u_ellipsis
				self._LCTRL_result.SetItem (
					index = row_num,
					column = col_idx,
					label = label
				)
		# must be called explicitely, because string items are set above without calling set_string_items
		self._LCTRL_result._invalidate_sorting_metadata()
		self._LCTRL_result.set_column_widths()
		self._LCTRL_result.set_data(data = rows)

		self.query_results = rows
		self._BTN_visualize.Enable(True)
		self._BTN_waiting_list.Enable(True)
		self._BTN_save_results.Enable(True)

		return success
Esempio n. 38
0
def set_active_praxis_branch(parent=None, no_parent=False):

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

	branches = gmPraxis.get_praxis_branches()

	if len(branches) == 1:
		_log.debug('only one praxis branch configured')
		gmPraxis.gmCurrentPraxisBranch(branches[0])
		return True

	if len(branches) == 0:
		orgs = gmOrganization.get_orgs()
		if len(orgs) == 0:
			pk_cat = gmOrganization.create_org_category(category = u'Praxis')
			org = gmOrganization.create_org(_('Your praxis'), pk_cat)
			unit = org.add_unit(_('Your branch'))
			branch = gmPraxis.create_praxis_branch(pk_org_unit = unit['pk_org_unit'])
			_log.debug('auto-created praxis branch because no organizations existed: %s', branch)
			gmPraxis.gmCurrentPraxisBranch(branch)
			gmGuiHelpers.gm_show_info (
				title = _('Praxis configuration ...'),
				info = _(
					'GNUmed has auto-created the following\n'
					'praxis branch for you (which you can\n'
					'later configure as needed):\n'
					'\n'
					'%s'
				) % branch.format()
			)
			return True

		if len(orgs) == 1:
			units = orgs[0].units
			if len(units) == 1:
				branch = gmPraxis.create_praxis_branch(pk_org_unit = units[0]['pk_org_unit'])
				_log.debug('auto-selected praxis branch because only one organization with only one unit existed: %s', branch)
				gmPraxis.gmCurrentPraxisBranch(branch)
				gmGuiHelpers.gm_show_info (
					title = _('Praxis configuration ...'),
					info = _(
						'GNUmed has auto-selected the following\n'
						'praxis branch for you (which you can\n'
						'later configure as needed):\n'
						'\n'
						'%s'
					) % branch.format()
				)
				return True

		_log.debug('no praxis branches configured, selecting from organization units')
		msg = _(
				'No praxis branches configured currently.\n'
				'\n'
				'You MUST select one unit of an organization to be the initial\n'
				'branch (site, office) which you are logging in from.'
		)
		unit = gmOrganizationWidgets.select_org_unit(msg = msg, no_parent = True)
		if unit is None:
			_log.warning('no organization unit selected, aborting')
			return False
		_log.debug('org unit selected as praxis branch: %s', unit)
		branch = gmPraxis.create_praxis_branch(pk_org_unit = unit['pk_org_unit'])
		_log.debug('created praxis branch: %s', branch)
		gmPraxis.gmCurrentPraxisBranch(branch)
		return True

	#--------------------
	def refresh(lctrl):
		branches = gmPraxis.get_praxis_branches()
		items = [
			[	b['branch'],
				gmTools.coalesce(b['l10n_unit_category'], u'')
			] for b in branches
		]
		lctrl.set_string_items(items = items)
		lctrl.set_data(data = branches)
	#--------------------
	branch = gmListWidgets.get_choices_from_list (
		parent = parent,
		msg = _("Select branch (of praxis [%s]) which you are logging in from.\n") % branches[0]['praxis'],
		caption = _('Praxis branch selection ...'),
		columns = [_('Branch'), _('Branch type')],
		can_return_empty = False,
		single_selection = True,
		refresh_callback = refresh
	)
	if branch is None:
		_log.warning('no praxis branch selected, aborting')
		return False
	gmPraxis.gmCurrentPraxisBranch(branch)
	return True
Esempio n. 39
0
def load_persons_from_xdt():

	bdt_files = []

	# some can be auto-detected
	# MCS/Isynet: $DRIVE:\Winacs\TEMP\BDTxx.tmp where xx is the workplace
	candidates = []
	drives = 'cdefghijklmnopqrstuvwxyz'
	for drive in drives:
		candidate = drive + ':\Winacs\TEMP\BDT*.tmp'
		candidates.extend(glob.glob(candidate))
	for candidate in candidates:
		path, filename = os.path.split(candidate)
		# FIXME: add encoding !
		bdt_files.append({'file': candidate, 'source': 'MCS/Isynet %s' % filename[-6:-4]})

	# some need to be configured
	# aggregate sources
	src_order = [
		('explicit', 'return'),
		('workbase', 'append'),
		('local', 'append'),
		('user', 'append'),
		('system', 'append')
	]
	xdt_profiles = _cfg.get (
		group = 'workplace',
		option = 'XDT profiles',
		source_order = src_order
	)
	if xdt_profiles is None:
		return []

	# first come first serve
	src_order = [
		('explicit', 'return'),
		('workbase', 'return'),
		('local', 'return'),
		('user', 'return'),
		('system', 'return')
	]
	for profile in xdt_profiles:
		name = _cfg.get (
			group = 'XDT profile %s' % profile,
			option = 'filename',
			source_order = src_order
		)
		if name is None:
			_log.error('XDT profile [%s] does not define a <filename>' % profile)
			continue
		encoding = _cfg.get (
			group = 'XDT profile %s' % profile,
			option = 'encoding',
			source_order = src_order
		)
		if encoding is None:
			_log.warning('xDT source profile [%s] does not specify an <encoding> for BDT file [%s]' % (profile, name))
		source = _cfg.get (
			group = 'XDT profile %s' % profile,
			option = 'source',
			source_order = src_order
		)
		dob_format = _cfg.get (
			group = 'XDT profile %s' % profile,
			option = 'DOB format',
			source_order = src_order
		)
		if dob_format is None:
			_log.warning('XDT profile [%s] does not define a date of birth format in <DOB format>' % profile)
		bdt_files.append({'file': name, 'source': source, 'encoding': encoding, 'dob_format': dob_format})

	dtos = []
	for bdt_file in bdt_files:
		try:
			# FIXME: potentially return several persons per file
			dto = gmPerson.get_person_from_xdt (
				filename = bdt_file['file'],
				encoding = bdt_file['encoding'],
				dob_format = bdt_file['dob_format']
			)

		except IOError:
			gmGuiHelpers.gm_show_info (
				_(
				'Cannot access BDT file\n\n'
				' [%s]\n\n'
				'to import patient.\n\n'
				'Please check your configuration.'
				) % bdt_file,
				_('Activating xDT patient')
			)
			_log.exception('cannot access xDT file [%s]' % bdt_file['file'])
			continue
		except:
			gmGuiHelpers.gm_show_error (
				_(
				'Cannot load patient from BDT file\n\n'
				' [%s]'
				) % bdt_file,
				_('Activating xDT patient')
			)
			_log.exception('cannot read patient from xDT file [%s]' % bdt_file['file'])
			continue

		dtos.append({'dto': dto, 'source': gmTools.coalesce(bdt_file['source'], dto.source)})

	return dtos
Esempio n. 40
0
def connect_to_database(max_attempts=3, expected_version=None, require_version=True):
	"""Display the login dialog and try to log into the backend.

	- up to max_attempts times
	- returns True/False
	"""
	# force programmer to set a valid expected_version
	expected_hash = gmPG2.known_schema_hashes[expected_version]
	client_version = _cfg.get(option = 'client_version')
	global current_db_name
	current_db_name = 'gnumed_v%s' % expected_version

	attempt = 0

	dlg = cLoginDialog(None, -1, client_version = client_version)
	dlg.Centre(wx.BOTH)

	while attempt < max_attempts:

		_log.debug('login attempt %s of %s', (attempt+1), max_attempts)

		connected = False

		dlg.ShowModal()
		login = dlg.panel.GetLoginInfo()
		if login is None:
			_log.info("user cancelled login dialog")
			break

		gmLog2.add_word2hide(login.password)

		# try getting a connection to verify the DSN works
		dsn = gmPG2.make_psycopg2_dsn (
			database = login.database,
			host = login.host,
			port = login.port,
			user = login.user,
			password = login.password
		)
		try:
			conn = gmPG2.get_raw_connection(dsn = dsn, verbose = True, readonly = True)
			connected = True

		except gmPG2.cAuthenticationError as e:
			attempt += 1
			_log.error("login attempt failed: %s", e)
			if attempt < max_attempts:
				if ('host=127.0.0.1' in ('%s' % e)) or ('host=' not in ('%s' % e)):
					msg = _(
						'Unable to connect to database:\n\n'
						'%s\n\n'
						"Are you sure you have got a local database installed ?\n"
						'\n'
						"Please retry with proper credentials or cancel.\n"
						'\n'
						' (for the public and any new GNUmed data-\n'
						'  bases the default user name and password\n'
						'  are {any-doc, any-doc})\n'
						'\n'
						'You may also need to check the PostgreSQL client\n'
						'authentication configuration in pg_hba.conf. For\n'
						'details see:\n'
						'\n'
						'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL'
					)
				else:
					msg = _(
						"Unable to connect to database:\n\n"
						"%s\n\n"
						"Please retry with proper credentials or cancel.\n"
						"\n"
						"For the public and any new GNUmed databases the\n"
						"default user name and password are {any-doc, any-doc}.\n"
						"\n"
						'You may also need to check the PostgreSQL client\n'
						'authentication configuration in pg_hba.conf. For\n'
						'details see:\n'
						'\n'
						'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL'
					)
				msg = msg % e
				msg = regex.sub(r'password=[^\s]+', 'password=%s' % gmTools.u_replacement_character, msg)
				gmGuiHelpers.gm_show_error (
					msg,
					_('Connecting to backend')
				)
			del e
			continue

		except gmPG2.dbapi.OperationalError as exc:
			_log.exception('login attempt failed')
			gmPG2.log_pg_exception_details(exc)
			msg = _(
				"Unable to connect to database:\n\n"
				"%s\n\n"
				"Please retry another backend / user / password combination !\n"
				"\n"
				" (for the public and any new GNUmed databases\n"
				"  the default user name and password are\n"
				"  {any-doc, any-doc})\n"
				"\n"
			) % exc
			msg = regex.sub(r'password=[^\s]+', 'password=%s' % gmTools.u_replacement_character, msg)
			gmGuiHelpers.gm_show_error(msg, _('Connecting to backend'))
			del exc
			continue

		conn.close()

		# connect was successful
		gmPG2.set_default_login(login = login)
		gmPG2.set_default_client_encoding(encoding = dlg.panel.backend_profile.encoding)

		seems_bootstrapped = gmPG2.schema_exists(schema = 'gm')
		if not seems_bootstrapped:
			_log.error('schema [gm] does not exist - database not bootstrapped ?')
			msg = _(
				'The database you connected to does not seem\n'
				'to have been boostrapped properly.\n'
				'\n'
				'Make sure you have run the GNUmed database\n'
				'bootstrapper tool to create a new database.\n'
				'\n'
				'Further help can be found on the website at\n'
				'\n'
				'  http://wiki.gnumed.de\n'
				'\n'
				'or on the GNUmed mailing list.'
			)
			gmGuiHelpers.gm_show_error(msg, _('Verifying database'))
			connected = False
			break

		compatible = gmPG2.database_schema_compatible(version = expected_version)
		if compatible or not require_version:
			dlg.panel.save_state()

		if not compatible:
			connected_db_version = gmPG2.get_schema_version()
			msg = msg_generic % (
				client_version,
				connected_db_version,
				expected_version,
				gmTools.coalesce(login.host, '<localhost>'),
				login.database,
				login.user
			)
			if require_version:
				gmGuiHelpers.gm_show_error(msg + msg_fail, _('Verifying database version'))
				connected = False
				continue
			gmGuiHelpers.gm_show_info(msg + msg_override, _('Verifying database version'))

		# FIXME: make configurable
		max_skew = 1		# minutes
		if _cfg.get(option = 'debug'):
			max_skew = 10
		if not gmPG2.sanity_check_time_skew(tolerance = (max_skew * 60)):
			if _cfg.get(option = 'debug'):
				gmGuiHelpers.gm_show_warning(msg_time_skew_warn % max_skew, _('Verifying database settings'))
			else:
				gmGuiHelpers.gm_show_error(msg_time_skew_fail % max_skew, _('Verifying database settings'))
				connected = False
				continue

		sanity_level, message = gmPG2.sanity_check_database_settings()
		if sanity_level != 0:
			gmGuiHelpers.gm_show_error((msg_insanity % message), _('Verifying database settings'))
			if sanity_level == 2:
				connected = False
				continue

		gmExceptionHandlingWidgets.set_is_public_database(login.public_db)
		gmExceptionHandlingWidgets.set_helpdesk(login.helpdesk)

		conn = gmPG2.get_connection(verbose = True, connection_name = 'GNUmed-[DbListenerThread]', pooled = False)
		listener = gmBackendListener.gmBackendListener(conn = conn)
		break

	dlg.DestroyLater()

	return connected
Esempio n. 41
0
    def _on_run_button_pressed(self, evt):

        self._BTN_visualize.Enable(False)
        self._BTN_waiting_list.Enable(False)
        self._BTN_save_results.Enable(False)

        user_query = self._TCTRL_query.GetValue().strip().strip(';')
        if user_query == '':
            return True

        limit = 1001
        pat = None
        curr_pat = gmPerson.gmCurrentPatient()
        if curr_pat.connected:
            pat = curr_pat.ID
        success, hint, cols, rows = gmDataMining.run_report_query(
            query=user_query, limit=limit, pk_identity=pat)

        self._LCTRL_result.set_columns()

        if len(rows) == 0:
            self._LCTRL_result.set_columns([_('Results')])
            self._LCTRL_result.set_string_items(
                [[_('Report returned no data.')]])
            self._LCTRL_result.set_column_widths()
            gmDispatcher.send('statustext',
                              msg=_('No data returned for this report.'),
                              beep=True)
            return True

        gmDispatcher.send(signal='statustext',
                          msg=_('Found %s results.') % len(rows))

        if len(rows) == 1001:
            gmGuiHelpers.gm_show_info(
                aMessage=_('This query returned at least %s results.\n'
                           '\n'
                           'GNUmed will only show the first %s rows.\n'
                           '\n'
                           'You may want to narrow down the WHERE conditions\n'
                           'or use LIMIT and OFFSET to batchwise go through\n'
                           'all the matching rows.') % (limit, limit - 1),
                aTitle=_('Report Generator'))
            rows = rows[:-1]  # make it true :-)

        self._LCTRL_result.set_columns(cols)
        for row in rows:
            try:
                label = str(gmTools.coalesce(row[0], '')).replace(
                    '\n', '<LF>').replace('\r', '<CR>')
            except UnicodeDecodeError:
                label = _('not str()able')
            if len(label) > 150:
                label = label[:150] + gmTools.u_ellipsis
            row_num = self._LCTRL_result.InsertItem(sys.maxsize, label=label)
            for col_idx in range(1, len(row)):
                try:
                    label = str(gmTools.coalesce(row[col_idx], '')).replace(
                        '\n', '<LF>').replace('\r', '<CR>')[:250]
                except UnicodeDecodeError:
                    label = _('not str()able')
                if len(label) > 150:
                    label = label[:150] + gmTools.u_ellipsis
                self._LCTRL_result.SetItem(index=row_num,
                                           column=col_idx,
                                           label=label)
        # must be called explicitely, because string items are set above without calling set_string_items
        self._LCTRL_result._invalidate_sorting_metadata()
        self._LCTRL_result.set_column_widths()
        self._LCTRL_result.set_data(data=rows)

        self.query_results = rows
        self._BTN_visualize.Enable(True)
        self._BTN_waiting_list.Enable(True)
        self._BTN_save_results.Enable(True)

        return success
Esempio n. 42
0
def get_person_from_external_sources(parent=None, search_immediately=False, activate_immediately=False):
	"""Load patient from external source.

	- scan external sources for candidates
	- let user select source
	  - if > 1 available: always
	  - if only 1 available: depending on search_immediately
	- search for patients matching info from external source
	- if more than one match:
	  - let user select patient
	- if no match:
	  - create patient
	- activate patient
	"""
	# get DTOs from interfaces
	dtos = []
	dtos.extend(load_persons_from_xdt())
	dtos.extend(load_persons_from_pracsoft_au())
	dtos.extend(load_persons_from_kvks())
	dtos.extend(load_persons_from_ca_msva())

	# no external persons
	if len(dtos) == 0:
		gmDispatcher.send(signal='statustext', msg=_('No patients found in external sources.'))
		return None

	# one external patient with DOB - already active ?
	if (len(dtos) == 1) and (dtos[0]['dto'].dob is not None):
		dto = dtos[0]['dto']
		# is it already the current patient ?
		curr_pat = gmPerson.gmCurrentPatient()
		if curr_pat.connected:
			key_dto = dto.firstnames + dto.lastnames + dto.dob.strftime('%Y-%m-%d') + dto.gender
			names = curr_pat.get_active_name()
			key_pat = names['firstnames'] + names['lastnames'] + curr_pat.get_formatted_dob(format = '%Y-%m-%d') + curr_pat['gender']
			_log.debug('current patient: %s' % key_pat)
			_log.debug('dto patient    : %s' % key_dto)
			if key_dto == key_pat:
				gmDispatcher.send(signal='statustext', msg=_('The only external patient is already active in GNUmed.'), beep=False)
				return None

	# one external person - look for internal match immediately ?
	if (len(dtos) == 1) and search_immediately:
		dto = dtos[0]['dto']

	# several external persons
	else:
		if parent is None:
			parent = wx.GetApp().GetTopWindow()
		dlg = cSelectPersonDTOFromListDlg(parent=parent, id=-1)
		dlg.set_dtos(dtos=dtos)
		result = dlg.ShowModal()
		if result == wx.ID_CANCEL:
			return None
		dto = dlg.get_selected_dto()['dto']
		dlg.DestroyLater()

	# search
	idents = dto.get_candidate_identities(can_create=True)
	if idents is None:
		gmGuiHelpers.gm_show_info (_(
			'Cannot create new patient:\n\n'
			' [%s %s (%s), %s]'
			) % (
				dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
			),
			_('Activating external patient')
		)
		return None

	if len(idents) == 1:
		ident = idents[0]

	if len(idents) > 1:
		if parent is None:
			parent = wx.GetApp().GetTopWindow()
		dlg = cSelectPersonFromListDlg(parent=parent, id=-1)
		dlg.set_persons(persons=idents)
		result = dlg.ShowModal()
		ident = dlg.get_selected_person()
		dlg.DestroyLater()
		if result == wx.ID_CANCEL:
			return None

	if activate_immediately:
		if not set_active_patient(patient = ident):
			gmGuiHelpers.gm_show_info (_(
				'Cannot activate patient:\n\n'
				'%s %s (%s)\n'
				'%s'
				) % (
					dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
				),
				_('Activating external patient')
			)
			return None

	dto.import_extra_data(identity = ident)
	dto.delete_from_source()

	return ident
Esempio n. 43
0
def search_narrative_in_emr(parent=None, patient=None):

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

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

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

    search_term_dlg = wx.TextEntryDialog(
        parent=parent,
        message=_('Enter search term:'),
        caption=_('Text search of entire EMR of active patient'),
        style=wx.OK | wx.CANCEL | wx.CENTRE)
    result = search_term_dlg.ShowModal()

    if result != wx.ID_OK:
        search_term_dlg.Destroy()
        return False

    wx.BeginBusyCursor()
    val = search_term_dlg.GetValue()
    search_term_dlg.Destroy()
    emr = patient.emr
    rows = emr.search_narrative_simple(val)
    wx.EndBusyCursor()

    if len(rows) == 0:
        gmGuiHelpers.gm_show_info(
            _('Nothing found for search term:\n'
              ' "%s"') % val, _('Search results'))
        return True

    txt = ''
    for row in rows:
        txt += '%s: %s\n' % (row['soap_cat'], row['narrative'])

        txt += ' %s: %s - %s %s\n' % (
            _('Encounter'), row['encounter_started'].strftime('%x %H:%M'),
            row['encounter_ended'].strftime('%H:%M'), row['encounter_type'])
        txt += ' %s: %s\n' % (_('Episode'), row['episode'])
        txt += ' %s: %s\n\n' % (_('Health issue'), row['health_issue'])

    msg = _('Search term was: "%s"\n'
            '\n'
            'Search results:\n\n'
            '%s\n') % (val, txt)

    dlg = wx.MessageDialog(parent=parent,
                           message=msg,
                           caption=_('Search results for [%s]') % val,
                           style=wx.OK | wx.STAY_ON_TOP)
    dlg.ShowModal()
    dlg.Destroy()

    return True
Esempio n. 44
0
	def _on_enter(self, search_term=None):
		"""This can be overridden in child classes."""

		wx.BeginBusyCursor()

		# get list of matching ids
		idents = self.__person_searcher.get_identities(search_term)

		if idents is None:
			wx.EndBusyCursor()
			gmGuiHelpers.gm_show_info (
				_('Error searching for matching persons.\n\n'
				  'Search term: "%s"'
				) % search_term,
				_('selecting person')
			)
			return None

		_log.info("%s matching person(s) found", len(idents))

		if len(idents) == 0:
			wx.EndBusyCursor()

			dlg = gmGuiHelpers.c2ButtonQuestionDlg (
				wx.GetTopLevelParent(self),
				-1,
				caption = _('Selecting patient'),
				question = _(
					'Cannot find any matching patients for the search term\n\n'
					' "%s"\n\n'
					'You may want to try a shorter search term.\n'
				) % search_term,
				button_defs = [
					{'label': _('Go back'), 'tooltip': _('Go back and search again.'), 'default': True},
					{'label': _('Create new'), 'tooltip': _('Create new patient.')}
				]
			)
			if dlg.ShowModal() != wx.ID_NO:
				return

			success = create_new_person(activate = True)
			if success:
				self.person = gmPerson.gmCurrentPatient()
			else:
				self.person = None
			return None

		# only one matching identity
		if len(idents) == 1:
			self.person = idents[0]
			wx.EndBusyCursor()
			return None

		# more than one matching identity: let user select from pick list
		dlg = cSelectPersonFromListDlg(parent=wx.GetTopLevelParent(self), id=-1)
		dlg.set_persons(persons=idents)
		wx.EndBusyCursor()
		result = dlg.ShowModal()
		if result == wx.ID_CANCEL:
			dlg.DestroyLater()
			return None

		wx.BeginBusyCursor()
		self.person = dlg.get_selected_person()
		dlg.DestroyLater()
		wx.EndBusyCursor()

		return None
Esempio n. 45
0
def install_data_pack(data_pack=None):

	if data_pack is None:
		return False

	_log.info('attempting installation of data pack: %s', data_pack['name'])

	msg = _(
		'Note that GNUmed data packs are provided\n'
		'\n'
		'WITHOUT ANY GUARANTEE WHATSOEVER\n'
		'\n'
		'regarding their content.\n'
		'\n'
		'Despite data packs having been prepared with the\n'
		'utmost care you must still vigilantly apply caution,\n'
		'common sense, and due diligence to make sure you\n'
		'render appropriate care to your patients.\n'
		'\n'
		'Press [Yes] to declare agreement with this precaution.\n'
		'\n'
		'Press [No] to abort installation of the data pack.\n'
	)
	go_ahead = gmGuiHelpers.gm_show_question(msg, _('Terms of Data Pack Use'))
	if not go_ahead:
		_log.info('user did not agree to terms of data pack use')
		return True

	gm_dbo_conn = gmAuthWidgets.get_dbowner_connection(procedure = _('installing data pack'))
	if gm_dbo_conn is None:
		msg = _('Lacking permissions to install data pack.')
		gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
		return False

	wx.BeginBusyCursor()
	verified, data = gmNetworkTools.download_data_pack (
		data_pack['pack_url'],
		md5_url = data_pack['md5_url']
	)
	wx.EndBusyCursor()
	if not verified:
		_log.error('cannot download and verify data pack: %s', data_pack['name'])
		md5_expected, md5_calculated = data
		msg = _(
			'Cannot validate data pack.\n'
			'\n'
			'  name: %s\n'
			'  URL: %s\n'
			'\n'
			'  MD5\n'
			'   calculated: %s\n'
			'   expected: %s\n'
			'   source: %s\n'
			'\n'
			'You may want to try downloading again or you\n'
			'may need to contact your administrator.'
		) % (
			data_pack['name'],
			data_pack['pack_url'],
			md5_calculated,
			md5_expected,
			data_pack['md5_url']
		)
		gmGuiHelpers.gm_show_error(msg, _('Verifying data pack'))
		return False

	data_pack['local_archive'] = data

	wx.BeginBusyCursor()
	unzip_dir = gmNetworkTools.unzip_data_pack(filename = data)
	wx.EndBusyCursor()
	if unzip_dir is None:
		msg = _(
			'Cannot unpack data pack.\n'
			'\n'
			'  name: %s\n'
			'  URL: %s\n'
			'  local: %s\n'
			'\n'
			'You may want to try downloading again or you\n'
			'may need to contact your administrator.'
		) % (
			data_pack['name'],
			data_pack['pack_url'],
			data_pack['local_archive']
		)
		gmGuiHelpers.gm_show_error(msg, _('Unpacking data pack'))
		return False

	data_pack['unzip_dir'] = unzip_dir

	wx.BeginBusyCursor()
	try:
		installed = gmNetworkTools.install_data_pack(data_pack, gm_dbo_conn)
	finally:
		wx.EndBusyCursor()

	# check schema hash
	db_version = gmPG2.map_client_branch2required_db_version[_cfg.get(option = 'client_branch')]
	if not gmPG2.database_schema_compatible(version = db_version):
		if db_version != 0:
			msg = _(
				'Installation of data pack failed because\n'
				'it attempted to modify the database layout.\n'
				'\n'
				'  name: %s\n'
				'  URL: %s\n'
				'  local: %s\n'
				'\n'
				'You will need to contact your administrator.'
			) % (
				data_pack['name'],
				data_pack['pack_url'],
				data_pack['local_archive']
			)
			gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
			return False

	if not installed:
		msg = _(
			'Installation of data pack failed.\n'
			'\n'
			'  name: %s\n'
			'  URL: %s\n'
			'  local: %s\n'
			'\n'
			'You may want to try downloading again or you\n'
			'may need to contact your administrator.'
		) % (
			data_pack['name'],
			data_pack['pack_url'],
			data_pack['local_archive']
		)
		gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
		return False

	msg = _(
		'Successfully installed data pack.\n'
		'\n'
		'  name: %s\n'
		'  URL: %s\n'
	) % (
		data_pack['name'],
		data_pack['pack_url']
	)
	gmGuiHelpers.gm_show_info(msg, _('Installing data pack'))

	return True
Esempio n. 46
0
def install_data_pack(data_pack=None):

    if data_pack is None:
        return False

    _log.info('attempting installation of data pack: %s', data_pack['name'])

    msg = _('Note that GNUmed data packs are provided\n'
            '\n'
            'WITHOUT ANY GUARANTEE WHATSOEVER\n'
            '\n'
            'regarding their content.\n'
            '\n'
            'Despite data packs having been prepared with the\n'
            'utmost care you must still vigilantly apply caution,\n'
            'common sense, and due diligence to make sure you\n'
            'render appropriate care to your patients.\n'
            '\n'
            'Press [Yes] to declare agreement with this precaution.\n'
            '\n'
            'Press [No] to abort installation of the data pack.\n')
    go_ahead = gmGuiHelpers.gm_show_question(msg, _('Terms of Data Pack Use'))
    if not go_ahead:
        _log.info('user did not agree to terms of data pack use')
        return True

    gm_dbo_conn = gmAuthWidgets.get_dbowner_connection(
        procedure=_('installing data pack'))
    if gm_dbo_conn is None:
        msg = _('Lacking permissions to install data pack.')
        gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
        return False

    wx.BeginBusyCursor()
    verified, data = gmNetworkTools.download_data_pack(
        data_pack['pack_url'], md5_url=data_pack['md5_url'])
    wx.EndBusyCursor()
    if not verified:
        _log.error('cannot download and verify data pack: %s',
                   data_pack['name'])
        md5_expected, md5_calculated = data
        msg = _('Cannot validate data pack.\n'
                '\n'
                '  name: %s\n'
                '  URL: %s\n'
                '\n'
                '  MD5\n'
                '   calculated: %s\n'
                '   expected: %s\n'
                '   source: %s\n'
                '\n'
                'You may want to try downloading again or you\n'
                'may need to contact your administrator.') % (
                    data_pack['name'], data_pack['pack_url'], md5_calculated,
                    md5_expected, data_pack['md5_url'])
        gmGuiHelpers.gm_show_error(msg, _('Verifying data pack'))
        return False

    data_pack['local_archive'] = data

    wx.BeginBusyCursor()
    unzip_dir = gmNetworkTools.unzip_data_pack(filename=data)
    wx.EndBusyCursor()
    if unzip_dir is None:
        msg = _('Cannot unpack data pack.\n'
                '\n'
                '  name: %s\n'
                '  URL: %s\n'
                '  local: %s\n'
                '\n'
                'You may want to try downloading again or you\n'
                'may need to contact your administrator.') % (
                    data_pack['name'], data_pack['pack_url'],
                    data_pack['local_archive'])
        gmGuiHelpers.gm_show_error(msg, _('Unpacking data pack'))
        return False

    data_pack['unzip_dir'] = unzip_dir

    wx.BeginBusyCursor()
    try:
        installed = gmNetworkTools.install_data_pack(data_pack, gm_dbo_conn)
    finally:
        wx.EndBusyCursor()

    # check schema hash
    db_version = gmPG2.map_client_branch2required_db_version[_cfg.get(
        option='client_branch')]
    if not gmPG2.database_schema_compatible(version=db_version):
        if db_version != 0:
            msg = _('Installation of data pack failed because\n'
                    'it attempted to modify the database layout.\n'
                    '\n'
                    '  name: %s\n'
                    '  URL: %s\n'
                    '  local: %s\n'
                    '\n'
                    'You will need to contact your administrator.') % (
                        data_pack['name'], data_pack['pack_url'],
                        data_pack['local_archive'])
            gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
            return False

    if not installed:
        msg = _('Installation of data pack failed.\n'
                '\n'
                '  name: %s\n'
                '  URL: %s\n'
                '  local: %s\n'
                '\n'
                'You may want to try downloading again or you\n'
                'may need to contact your administrator.') % (
                    data_pack['name'], data_pack['pack_url'],
                    data_pack['local_archive'])
        gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
        return False

    msg = _('Successfully installed data pack.\n'
            '\n'
            '  name: %s\n'
            '  URL: %s\n') % (data_pack['name'], data_pack['pack_url'])
    gmGuiHelpers.gm_show_info(msg, _('Installing data pack'))

    return True
Esempio n. 47
0
        if not compatible:
            connected_db_version = gmPG2.get_schema_version()
            msg = msg_generic % (
                client_version,
                connected_db_version,
                expected_version,
                gmTools.coalesce(login.host, "<localhost>"),
                login.database,
                login.user,
            )
            if require_version:
                gmGuiHelpers.gm_show_error(msg + msg_fail, _("Verifying database version"))
                connected = False
                continue
            gmGuiHelpers.gm_show_info(msg + msg_override, _("Verifying database version"))

            # FIXME: make configurable
        max_skew = 1  # minutes
        if _cfg.get(option="debug"):
            max_skew = 10
        if not gmPG2.sanity_check_time_skew(tolerance=(max_skew * 60)):
            if _cfg.get(option="debug"):
                gmGuiHelpers.gm_show_warning(msg_time_skew_warn % max_skew, _("Verifying database settings"))
            else:
                gmGuiHelpers.gm_show_error(msg_time_skew_fail % max_skew, _("Verifying database settings"))
                connected = False
                continue

        sanity_level, message = gmPG2.sanity_check_database_settings()
        if sanity_level != 0:
Esempio n. 48
0
def connect_to_database(max_attempts=3,
                        expected_version=None,
                        require_version=True):
    """Display the login dialog and try to log into the backend.

	- up to max_attempts times
	- returns True/False
	"""
    # force programmer to set a valid expected_version
    expected_hash = gmPG2.known_schema_hashes[expected_version]
    client_version = _cfg.get(option='client_version')
    global current_db_name
    current_db_name = 'gnumed_v%s' % expected_version

    attempt = 0

    dlg = cLoginDialog(None, -1, client_version=client_version)
    dlg.Centre(wx.BOTH)

    while attempt < max_attempts:

        _log.debug('login attempt %s of %s', (attempt + 1), max_attempts)

        connected = False

        dlg.ShowModal()
        login = dlg.panel.GetLoginInfo()
        if login is None:
            _log.info("user cancelled login dialog")
            break

        gmLog2.add_word2hide(login.password)

        # try getting a connection to verify the DSN works
        dsn = gmPG2.make_psycopg2_dsn(database=login.database,
                                      host=login.host,
                                      port=login.port,
                                      user=login.user,
                                      password=login.password)
        try:
            conn = gmPG2.get_raw_connection(dsn=dsn,
                                            verbose=True,
                                            readonly=True)
            connected = True

        except gmPG2.cAuthenticationError as e:
            attempt += 1
            _log.error("login attempt failed: %s", e)
            if attempt < max_attempts:
                if ('host=127.0.0.1' in ('%s' % e)) or ('host='
                                                        not in ('%s' % e)):
                    msg = _(
                        'Unable to connect to database:\n\n'
                        '%s\n\n'
                        "Are you sure you have got a local database installed ?\n"
                        '\n'
                        "Please retry with proper credentials or cancel.\n"
                        '\n'
                        ' (for the public and any new GNUmed data-\n'
                        '  bases the default user name and password\n'
                        '  are {any-doc, any-doc})\n'
                        '\n'
                        'You may also need to check the PostgreSQL client\n'
                        'authentication configuration in pg_hba.conf. For\n'
                        'details see:\n'
                        '\n'
                        'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL')
                else:
                    msg = _(
                        "Unable to connect to database:\n\n"
                        "%s\n\n"
                        "Please retry with proper credentials or cancel.\n"
                        "\n"
                        "For the public and any new GNUmed databases the\n"
                        "default user name and password are {any-doc, any-doc}.\n"
                        "\n"
                        'You may also need to check the PostgreSQL client\n'
                        'authentication configuration in pg_hba.conf. For\n'
                        'details see:\n'
                        '\n'
                        'wiki.gnumed.de/bin/view/Gnumed/ConfigurePostgreSQL')
                msg = msg % e
                msg = regex.sub(
                    r'password=[^\s]+',
                    'password=%s' % gmTools.u_replacement_character, msg)
                gmGuiHelpers.gm_show_error(msg, _('Connecting to backend'))
            del e
            continue

        except gmPG2.dbapi.OperationalError as exc:
            _log.exception('login attempt failed')
            gmPG2.log_pg_exception_details(exc)
            msg = _(
                "Unable to connect to database:\n\n"
                "%s\n\n"
                "Please retry another backend / user / password combination !\n"
                "\n"
                " (for the public and any new GNUmed databases\n"
                "  the default user name and password are\n"
                "  {any-doc, any-doc})\n"
                "\n") % exc
            msg = regex.sub(r'password=[^\s]+',
                            'password=%s' % gmTools.u_replacement_character,
                            msg)
            gmGuiHelpers.gm_show_error(msg, _('Connecting to backend'))
            del exc
            continue

        conn.close()

        # connect was successful
        gmPG2.set_default_login(login=login)
        gmPG2.set_default_client_encoding(
            encoding=dlg.panel.backend_profile.encoding)

        seems_bootstrapped = gmPG2.schema_exists(schema='gm')
        if not seems_bootstrapped:
            _log.error(
                'schema [gm] does not exist - database not bootstrapped ?')
            msg = _('The database you connected to does not seem\n'
                    'to have been boostrapped properly.\n'
                    '\n'
                    'Make sure you have run the GNUmed database\n'
                    'bootstrapper tool to create a new database.\n'
                    '\n'
                    'Further help can be found on the website at\n'
                    '\n'
                    '  http://wiki.gnumed.de\n'
                    '\n'
                    'or on the GNUmed mailing list.')
            gmGuiHelpers.gm_show_error(msg, _('Verifying database'))
            connected = False
            break

        compatible = gmPG2.database_schema_compatible(version=expected_version)
        if compatible or not require_version:
            dlg.panel.save_state()

        if not compatible:
            connected_db_version = gmPG2.get_schema_version()
            msg = msg_generic % (client_version, connected_db_version,
                                 expected_version,
                                 gmTools.coalesce(login.host, '<localhost>'),
                                 login.database, login.user)
            if require_version:
                gmGuiHelpers.gm_show_error(msg + msg_fail,
                                           _('Verifying database version'))
                connected = False
                continue
            gmGuiHelpers.gm_show_info(msg + msg_override,
                                      _('Verifying database version'))

        # FIXME: make configurable
        max_skew = 1  # minutes
        if _cfg.get(option='debug'):
            max_skew = 10
        if not gmPG2.sanity_check_time_skew(tolerance=(max_skew * 60)):
            if _cfg.get(option='debug'):
                gmGuiHelpers.gm_show_warning(msg_time_skew_warn % max_skew,
                                             _('Verifying database settings'))
            else:
                gmGuiHelpers.gm_show_error(msg_time_skew_fail % max_skew,
                                           _('Verifying database settings'))
                connected = False
                continue

        sanity_level, message = gmPG2.sanity_check_database_settings()
        if sanity_level != 0:
            gmGuiHelpers.gm_show_error((msg_insanity % message),
                                       _('Verifying database settings'))
            if sanity_level == 2:
                connected = False
                continue

        gmExceptionHandlingWidgets.set_is_public_database(login.public_db)
        gmExceptionHandlingWidgets.set_helpdesk(login.helpdesk)

        conn = gmPG2.get_connection(
            verbose=True,
            connection_name='GNUmed-[DbListenerThread]',
            pooled=False)
        listener = gmBackendListener.gmBackendListener(conn=conn)
        break

    dlg.DestroyLater()

    return connected
Esempio n. 49
0
def set_active_praxis_branch(parent=None, no_parent=False):

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

    branches = gmPraxis.get_praxis_branches()

    if len(branches) == 1:
        _log.debug('only one praxis branch configured')
        gmPraxis.gmCurrentPraxisBranch(branches[0])
        return True

    if len(branches) == 0:
        orgs = gmOrganization.get_orgs()
        if len(orgs) == 0:
            pk_cat = gmOrganization.create_org_category(category=u'Praxis')
            org = gmOrganization.create_org(_('Your praxis'), pk_cat)
            unit = org.add_unit(_('Your branch'))
            branch = gmPraxis.create_praxis_branch(
                pk_org_unit=unit['pk_org_unit'])
            _log.debug(
                'auto-created praxis branch because no organizations existed: %s',
                branch)
            gmPraxis.gmCurrentPraxisBranch(branch)
            gmGuiHelpers.gm_show_info(
                title=_('Praxis configuration ...'),
                info=_('GNUmed has auto-created the following\n'
                       'praxis branch for you (which you can\n'
                       'later configure as needed):\n'
                       '\n'
                       '%s') % branch.format())
            return True

        if len(orgs) == 1:
            units = orgs[0].units
            if len(units) == 1:
                branch = gmPraxis.create_praxis_branch(
                    pk_org_unit=units[0]['pk_org_unit'])
                _log.debug(
                    'auto-selected praxis branch because only one organization with only one unit existed: %s',
                    branch)
                gmPraxis.gmCurrentPraxisBranch(branch)
                gmGuiHelpers.gm_show_info(
                    title=_('Praxis configuration ...'),
                    info=_('GNUmed has auto-selected the following\n'
                           'praxis branch for you (which you can\n'
                           'later configure as needed):\n'
                           '\n'
                           '%s') % branch.format())
                return True

        _log.debug(
            'no praxis branches configured, selecting from organization units')
        msg = _(
            'No praxis branches configured currently.\n'
            '\n'
            'You MUST select one unit of an organization to be the initial\n'
            'branch (site, office) which you are logging in from.')
        unit = gmOrganizationWidgets.select_org_unit(msg=msg, no_parent=True)
        if unit is None:
            _log.warning('no organization unit selected, aborting')
            return False
        _log.debug('org unit selected as praxis branch: %s', unit)
        branch = gmPraxis.create_praxis_branch(pk_org_unit=unit['pk_org_unit'])
        _log.debug('created praxis branch: %s', branch)
        gmPraxis.gmCurrentPraxisBranch(branch)
        return True

    #--------------------
    def refresh(lctrl):
        branches = gmPraxis.get_praxis_branches()
        items = [[b['branch'],
                  gmTools.coalesce(b['l10n_unit_category'], u'')]
                 for b in branches]
        lctrl.set_string_items(items=items)
        lctrl.set_data(data=branches)

    #--------------------
    branch = gmListWidgets.get_choices_from_list(
        parent=parent,
        msg=_(
            "Select the branch of praxis [%s] which you are logging in from.\n"
        ) % branches[0]['praxis'],
        caption=_('Praxis branch selection ...'),
        columns=[_('Branch'), _('Branch type')],
        can_return_empty=False,
        single_selection=True,
        refresh_callback=refresh)
    if branch is None:
        _log.warning('no praxis branch selected, aborting')
        return False
    gmPraxis.gmCurrentPraxisBranch(branch)
    return True
Esempio n. 50
0
	def _on_enter(self, search_term=None):
		"""This can be overridden in child classes."""

		wx.BeginBusyCursor()

		# get list of matching ids
		idents = self.__person_searcher.get_identities(search_term)

		if idents is None:
			wx.EndBusyCursor()
			gmGuiHelpers.gm_show_info (
				_('Error searching for matching persons.\n\n'
				  'Search term: "%s"'
				) % search_term,
				_('selecting person')
			)
			return None

		_log.info("%s matching person(s) found", len(idents))

		if len(idents) == 0:
			wx.EndBusyCursor()

			dlg = gmGuiHelpers.c2ButtonQuestionDlg (
				wx.GetTopLevelParent(self),
				-1,
				caption = _('Selecting patient'),
				question = _(
					'Cannot find any matching patients for the search term\n\n'
					' "%s"\n\n'
					'You may want to try a shorter search term.\n'
				) % search_term,
				button_defs = [
					{'label': _('Go back'), 'tooltip': _('Go back and search again.'), 'default': True},
					{'label': _('Create new'), 'tooltip': _('Create new patient.')}
				]
			)
			if dlg.ShowModal() != wx.ID_NO:
				return

			success = create_new_person(activate = True)
			if success:
				self.person = gmPerson.gmCurrentPatient()
			else:
				self.person = None
			return None

		# only one matching identity
		if len(idents) == 1:
			self.person = idents[0]
			wx.EndBusyCursor()
			return None

		# more than one matching identity: let user select from pick list
		dlg = cSelectPersonFromListDlg(parent=wx.GetTopLevelParent(self), id=-1)
		dlg.set_persons(persons=idents)
		wx.EndBusyCursor()
		result = dlg.ShowModal()
		if result == wx.ID_CANCEL:
			dlg.DestroyLater()
			return None

		wx.BeginBusyCursor()
		self.person = dlg.get_selected_person()
		dlg.DestroyLater()
		wx.EndBusyCursor()

		return None