Ejemplo n.º 1
0
def configure_string_option(parent=None, message=None, option=None, bias='user', default_value='', validator=None):

	dbcfg = gmCfg.cCfgSQL()

	current_value = dbcfg.get2 (
		option = option,
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = bias,
		default = default_value
	)

	if current_value is not None:
		current_value = '%s' % current_value

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

	if validator is None:
		validator = lambda in_val: (True, in_val)

	while True:
		dlg = wx.TextEntryDialog (
			parent,
			message,
			caption = _('Configuration'),
			value = gmTools.coalesce(current_value, ''),
			style = wx.OK | wx.CANCEL | wx.CENTRE
		)
		result = dlg.ShowModal()
		if result == wx.ID_CANCEL:
			dlg.DestroyLater()
			return None

		user_val = dlg.GetValue().strip()
		dlg.DestroyLater()

		if user_val == current_value:
			return user_val

		validated, user_val = validator(user_val)
		if validated:
			break
		gmDispatcher.send (
			signal = 'statustext',
			msg = _('Value [%s] not valid for option <%s>.') % (user_val, option),
			beep = True
		)

	dbcfg = gmCfg.cCfgSQL()
	dbcfg.set (
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		option = option,
		value = user_val
	)

	return user_val
Ejemplo n.º 2
0
def configure_string_from_list_option(parent=None,
                                      message=None,
                                      option=None,
                                      bias='user',
                                      default_value='',
                                      choices=None,
                                      columns=None,
                                      data=None,
                                      caption=None):

    dbcfg = gmCfg.cCfgSQL()

    current_value = dbcfg.get2(
        option=option,
        workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
        bias=bias,
        default=default_value)

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

    if caption is None:
        caption = _('Configuration')

    selections = None
    if current_value is not None:
        try:
            selections = [choices.index(current_value)]
        except ValueError:
            pass

    choice = gmListWidgets.get_choices_from_list(parent=parent,
                                                 msg=message,
                                                 caption=caption,
                                                 choices=choices,
                                                 columns=columns,
                                                 data=data,
                                                 selections=selections,
                                                 single_selection=True,
                                                 can_return_empty=False)

    # aborted
    if choice is None:
        return

    # same value selected again
    if choice == current_value:
        return

    dbcfg = gmCfg.cCfgSQL()
    dbcfg.set(workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
              option=option,
              value=choice)

    return
Ejemplo n.º 3
0
def configure_string_option(parent=None, message=None, option=None, bias='user', default_value='', validator=None):

	dbcfg = gmCfg.cCfgSQL()

	current_value = dbcfg.get2 (
		option = option,
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = bias,
		default = default_value
	)

	if current_value is not None:
		current_value = '%s' % current_value

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

	while True:
		dlg = wx.TextEntryDialog (
			parent,
			message,
			caption = _('Configuration'),
			value = gmTools.coalesce(current_value, ''),
			style = wx.OK | wx.CANCEL | wx.CENTRE
		)
		result = dlg.ShowModal()
		if result == wx.ID_CANCEL:
			dlg.DestroyLater()
			return None

		user_val = dlg.GetValue().strip()
		dlg.DestroyLater()

		if user_val == current_value:
			return user_val

		validated, user_val = validator(user_val)
		if validated:
			break

		gmDispatcher.send (
			signal = 'statustext',
			msg = _('Value [%s] not valid for option <%s>.') % (user_val, option),
			beep = True
		)

	dbcfg = gmCfg.cCfgSQL()
	dbcfg.set (
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		option = option,
		value = user_val
	)

	return user_val
Ejemplo n.º 4
0
def configure_string_from_list_option(parent=None, message=None, option=None, bias='user', default_value='', choices=None, columns=None, data=None, caption=None):

	dbcfg = gmCfg.cCfgSQL()

	current_value = dbcfg.get2 (
		option = option,
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = bias,
		default = default_value
	)

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

	if caption is None:
		caption = _('Configuration')

	selections = None
	if current_value is not None:
		try:
			selections = [choices.index(current_value)]
		except ValueError:
			pass

	choice = gmListWidgets.get_choices_from_list (
		parent = parent,
		msg = message,
		caption = caption,
		choices = choices,
		columns = columns,
		data = data,
		selections = selections,
		single_selection = True,
		can_return_empty = False
	)

	# aborted
	if choice is None:
		return

	# same value selected again
	if choice == current_value:
		return

	dbcfg = gmCfg.cCfgSQL()
	dbcfg.set (
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		option = option,
		value = choice
	)

	return
Ejemplo n.º 5
0
	def clone(workplace=None):
		if workplace is None:
			return False

		new_name = wx.GetTextFromUser (
			message = _('Enter a name for the new workplace !'),
			caption = _('Cloning workplace'),
			default_value = '%s-2' % workplace,
			parent = parent
		).strip()

		if new_name == '':
			return False

		dbcfg = gmCfg.cCfgSQL()
		opt = 'horstspace.notebook.plugin_load_order'

		plugins = dbcfg.get2 (
			option = opt,
			workplace = workplace,
			bias = 'workplace'
		)

		dbcfg.set (
			option = opt,
			value = plugins,
			workplace = new_name
		)

		# FIXME: clone cfg, too

		return True
Ejemplo n.º 6
0
def _check_birthday(patient=None):

	if patient['dob'] is None:
		return

	dbcfg = gmCfg.cCfgSQL()
	dob_distance = dbcfg.get2 (
		option = 'patient_search.dob_warn_interval',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'user',
		default = '1 week'
	)

	if not patient.dob_in_range(dob_distance, dob_distance):
		return

	now = gmDateTime.pydt_now_here()
	enc = gmI18N.get_encoding()
	msg = _('%(pat)s turns %(age)s on %(month)s %(day)s ! (today is %(month_now)s %(day_now)s)') % {
		'pat': patient.get_description_gender(),
		'age': patient.get_medical_age().strip('y'),
		'month': patient.get_formatted_dob(format = '%B'),
		'day': patient.get_formatted_dob(format = '%d'),
		'month_now': gmDateTime.pydt_strftime(now, '%B', gmDateTime.acc_months),
		'day_now': gmDateTime.pydt_strftime(now, '%d', gmDateTime.acc_days)
	}
	gmDispatcher.send(signal = 'statustext', msg = msg)
Ejemplo n.º 7
0
	def __on_add_unassociated(self, evt):
		"""Add new editor for as-yet unassociated progress note.

		Clinical logic as per discussion with Jim Busser:

		- if patient has no episodes:
			- new patient
			- always allow several NEWs
		- if patient has episodes:
			- allow several NEWs per configuration
		"""
		emr = self.__pat.emr
		epis = emr.get_episodes()

		if len(epis) == 0:
			value = True
		else:
			dbcfg = gmCfg.cCfgSQL()
			value = bool(dbcfg.get2 (
				option = 'horstspace.soap_editor.allow_same_episode_multiple_times',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user',
				default = False
			))

		self.__soap_notebook.add_editor(allow_same_problem = value)
Ejemplo n.º 8
0
	def delete(item):
		delete_it = gmGuiHelpers.gm_show_question (
			aTitle = _('Deleting option'),
			aMessage = '%s\n\n%s %s (#%s) %s\n\n%s\n\n%s' % (
				tooltip(item),
				gmTools.u_box_horiz_single * 3,
				item['option'],
				item['pk_cfg_item'],
				gmTools.u_box_horiz_single * 3,
				_('Do you really want to delete this option ?'),
				_('(GNUmed will re-create options as needed.)')
			)
		)
		if not delete_it:
			return False

		from Gnumed.wxpython.gmAuthWidgets import get_dbowner_connection
		conn = get_dbowner_connection(procedure = _('Deleting option'))
		if conn is None:
			gmDispatcher.send(signal = 'statustext', msg = _('Cannot connect as database owner. Unable to delete option.'))
			return False

		cfg = gmCfg.cCfgSQL()
		cfg.delete(conn = conn, pk_option = item['pk_cfg_item'])
		return True
Ejemplo n.º 9
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')
	)
Ejemplo n.º 10
0
	def _on_problem_activated(self, event):
		"""Open progress note editor for this problem.
		"""
		problem = self._LCTRL_active_problems.get_selected_item_data(only_one = True)
		if problem is None:
			return True

		dbcfg = gmCfg.cCfgSQL()
		allow_duplicate_editors = bool(dbcfg.get2 (
			option = 'horstspace.soap_editor.allow_same_episode_multiple_times',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user',
			default = False
		))
		if self._PNL_editors.add_editor(problem = problem, allow_same_problem = allow_duplicate_editors):
			return True

		gmGuiHelpers.gm_show_error (
			aMessage = _(
				'Cannot open progress note editor for\n\n'
				'[%s].\n\n'
			) % problem['problem'],
			aTitle = _('opening progress note editor')
		)
		return False
Ejemplo n.º 11
0
    def __on_add_unassociated(self, evt):
        """Add new editor for as-yet unassociated progress note.

		Clinical logic as per discussion with Jim Busser:

		- if patient has no episodes:
			- new patient
			- always allow several NEWs
		- if patient has episodes:
			- allow several NEWs per configuration
		"""
        emr = self.__pat.emr
        epis = emr.get_episodes()

        if len(epis) == 0:
            value = True
        else:
            dbcfg = gmCfg.cCfgSQL()
            value = bool(
                dbcfg.get2(
                    option=
                    'horstspace.soap_editor.allow_same_episode_multiple_times',
                    workplace=gmPraxis.gmCurrentPraxisBranch(
                    ).active_workplace,
                    bias='user',
                    default=False))

        self.__soap_notebook.add_editor(allow_same_problem=value)
Ejemplo n.º 12
0
    def __get_lab_panel(self):
        # get panel to use
        dbcfg = gmCfg.cCfgSQL()
        pk_panel = dbcfg.get2(
            option=u'horstspace.top_panel.lab_panel',
            workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
            bias='user')
        if pk_panel is None:
            return None

        try:
            panel = gmPathLab.cTestPanel(aPK_obj=pk_panel)
        except gmExceptions.ConstructorError:
            _log.exception('cannot load configured test panel')
            panel = None
        if panel is not None:
            return panel

        _log.error(
            'Cannot load test panel [#%s] configured for patient pane (horstspace.top_panel.lab_panel).',
            pk_panel)
        gmGuiHelpers.gm_show_error(
            title=_('GNUmed startup'),
            error=_('Cannot load test panel [#%s] configured\n'
                    'for the top pane with option\n'
                    '\n'
                    ' <horstspace.top_panel.lab_panel>\n'
                    '\n'
                    'Please reconfigure.') % pk_panel)
        return None
Ejemplo n.º 13
0
def _check_birthday(patient=None):

	if patient['dob'] is None:
		return

	dbcfg = gmCfg.cCfgSQL()
	dob_distance = dbcfg.get2 (
		option = 'patient_search.dob_warn_interval',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'user',
		default = '1 week'
	)

	if not patient.dob_in_range(dob_distance, dob_distance):
		return

	now = gmDateTime.pydt_now_here()
	msg = _('%(pat)s turns %(age)s on %(month)s %(day)s ! (today is %(month_now)s %(day_now)s)') % {
		'pat': patient.get_description_gender(),
		'age': patient.get_medical_age(at_date = patient.birthday_this_year).strip('y'),
		'month': patient.get_formatted_dob(format = '%B'),
		'day': patient.get_formatted_dob(format = '%d'),
		'month_now': gmDateTime.pydt_strftime(now, '%B', gmDateTime.acc_months),
		'day_now': gmDateTime.pydt_strftime(now, '%d', gmDateTime.acc_days)
	}
	gmDispatcher.send(signal = 'statustext', msg = msg)
Ejemplo n.º 14
0
	def __init__ (self, *args, **kwargs):

		cPersonSearchCtrl.__init__(self, *args, **kwargs)

		# get configuration
		cfg = gmCfg.cCfgSQL()

		self.__always_dismiss_on_search = bool ( 
			cfg.get2 (
				option = 'patient_search.always_dismiss_previous_patient',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user',
				default = 0
			)
		)

		self.__always_reload_after_search = bool (
			cfg.get2 (
				option = 'patient_search.always_reload_new_patient',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user',
				default = 0
			)
		)

		self.__register_events()
Ejemplo n.º 15
0
	def clone(workplace=None):
		if workplace is None:
			return False

		new_name = wx.GetTextFromUser (
			message = _('Enter a name for the new workplace !'),
			caption = _('Cloning workplace'),
			default_value = u'%s-2' % workplace,
			parent = parent
		).strip()

		if new_name == u'':
			return False

		dbcfg = gmCfg.cCfgSQL()
		opt = u'horstspace.notebook.plugin_load_order'

		plugins = dbcfg.get2 (
			option = opt,
			workplace = workplace,
			bias = 'workplace'
		)

		dbcfg.set (
			option = opt,
			value = plugins,
			workplace = new_name
		)

		# FIXME: clone cfg, too

		return True
Ejemplo n.º 16
0
	def __init__(self, *args, **kwargs):

		try:
			self.problem = kwargs['problem']
			del kwargs['problem']
		except KeyError:
			self.problem = None

		wxgProgressNotesEAPnl.wxgProgressNotesEAPnl.__init__(self, *args, **kwargs)

		dbcfg = gmCfg.cCfgSQL()
		self.__use_soap_fields = bool(dbcfg.get2 (
			option = 'horstspace.soap_editor.use_one_field_per_soap_category',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user',
			default = True
		))

		self.__soap_fields = [
			self._TCTRL_Soap,
			self._TCTRL_sOap,
			self._TCTRL_soAp,
			self._TCTRL_soaP
		]

		self.__init_ui()
		self.__register_interests()

		return
Ejemplo n.º 17
0
	def __init__ (self, *args, **kwargs):

		cPersonSearchCtrl.__init__(self, *args, **kwargs)

		# get configuration
		cfg = gmCfg.cCfgSQL()

		self.__always_dismiss_on_search = bool ( 
			cfg.get2 (
				option = 'patient_search.always_dismiss_previous_patient',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user',
				default = 0
			)
		)

		self.__always_reload_after_search = bool (
			cfg.get2 (
				option = 'patient_search.always_reload_new_patient',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user',
				default = 0
			)
		)

		self.__register_events()
Ejemplo n.º 18
0
	def _on_problem_activated(self, event):
		"""Open progress note editor for this problem.
		"""
		problem = self._LCTRL_active_problems.get_selected_item_data(only_one = True)
		if problem is None:
			return True

		dbcfg = gmCfg.cCfgSQL()
		allow_duplicate_editors = bool(dbcfg.get2 (
			option = 'horstspace.soap_editor.allow_same_episode_multiple_times',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user',
			default = False
		))
		if self._PNL_editors.add_editor(problem = problem, allow_same_problem = allow_duplicate_editors):
			return True

		gmGuiHelpers.gm_show_error (
			aMessage = _(
				'Cannot open progress note editor for\n\n'
				'[%s].\n\n'
			) % problem['problem'],
			aTitle = _('opening progress note editor')
		)
		return False
Ejemplo n.º 19
0
    def __init_ui(self):
        cfg = gmCfg2.gmCfgData()
        if cfg.get(option='slave'):
            self._TCTRL_patient_selector.SetEditable(0)
            self._TCTRL_patient_selector.SetToolTip(None)

        if sys.platform == 'darwin':
            _log.debug('adjusting font size on Mac for top panel parts')
            for ctrl in [
                    self._TCTRL_patient_selector, self._LBL_age,
                    self._LBL_allergies, self._TCTRL_allergies
            ]:
                curr_font = ctrl.GetFont()
                mac_font = wx.Font(curr_font.GetNativeFontInfo())
                mac_font.SetPointSize(pointSize=int(curr_font.GetPointSize() /
                                                    0.8))
                ctrl.SetFont(mac_font)

        # get panel to use
        dbcfg = gmCfg.cCfgSQL()
        pk_panel = dbcfg.get2(
            option='horstspace.top_panel.lab_panel',
            workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
            bias='user')
        if pk_panel is None:
            self.__lab_panel = None
        else:
            self.__lab_panel = gmPathLab.cTestPanel(aPK_obj=pk_panel)
Ejemplo n.º 20
0
	def __init_ui(self):
		cfg = gmCfg2.gmCfgData()
		if cfg.get(option = 'slave'):
			self._TCTRL_patient_selector.SetEditable(0)
			self._TCTRL_patient_selector.SetToolTip(None)

		if sys.platform == u'darwin':
			_log.debug('adjusting font size on Mac for top panel parts')
			for ctrl in [self._TCTRL_patient_selector, self._LBL_age, self._LBL_allergies, self._TCTRL_allergies]:
				curr_font = ctrl.GetFont()
				mac_font = wx.FontFromNativeInfo(curr_font.NativeFontInfo)
				mac_font.SetPointSize(pointSize = int(curr_font.GetPointSize() / 0.8))
				ctrl.SetFont(mac_font)

		# get panel to use
		dbcfg = gmCfg.cCfgSQL()
		pk_panel = dbcfg.get2 (
			option = u'horstspace.top_panel.lab_panel',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user'
		)
		if pk_panel is None:
			self.__lab_panel = None
		else:
			self.__lab_panel = gmPathLab.cTestPanel(aPK_obj = pk_panel)
Ejemplo n.º 21
0
def _get_update_status():

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

	_cfg = gmCfg2.gmCfgData()
	update_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
	)

	return update_found, msg
Ejemplo n.º 22
0
 def _on_post_patient_selection(self, **kwargs):
     db_cfg = gmCfg.cCfgSQL()
     default_plugin = db_cfg.get2(
         option='patient_search.plugin_to_raise_after_search',
         workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
         bias='user',
         default='gmPatientOverviewPlugin')
     gmDispatcher.send(signal='display_widget', name=default_plugin)
Ejemplo n.º 23
0
    def edit_old(workplace=None):

        available_plugins = gmPlugin.get_installed_plugins(plugin_dir='gui')

        dbcfg = gmCfg.cCfgSQL()

        if workplace is None:
            dlg = wx.TextEntryDialog(
                parent=parent,
                message=_('Enter a descriptive name for the new workplace:'),
                caption=_('Configuring GNUmed workplaces ...'),
                defaultValue=u'',
                style=wx.OK | wx.CENTRE)
            dlg.ShowModal()
            workplace = dlg.GetValue().strip()
            if workplace == u'':
                gmGuiHelpers.gm_show_error(
                    _('Cannot save a new workplace without a name.'),
                    _('Configuring GNUmed workplaces ...'))
                return False
            curr_plugins = []
            choices = available_plugins
        else:
            curr_plugins = gmTools.coalesce(
                dbcfg.get2(option=u'horstspace.notebook.plugin_load_order',
                           workplace=workplace,
                           bias='workplace'), [])
            choices = curr_plugins[:]
            for p in available_plugins:
                if p not in choices:
                    choices.append(p)

        sels = range(len(curr_plugins))
        new_plugins = gmListWidgets.get_choices_from_list(
            parent=parent,
            msg=_('\n'
                  'Select the plugin(s) to be loaded the next time\n'
                  'the client is restarted under the workplace:\n'
                  '\n'
                  ' [%s]'
                  '\n') % workplace,
            caption=_('Configuring GNUmed workplaces ...'),
            choices=choices,
            selections=sels,
            columns=[_('Plugins')],
            single_selection=False)

        if new_plugins == curr_plugins:
            return True

        if new_plugins is None:
            return True

        dbcfg.set(option=u'horstspace.notebook.plugin_load_order',
                  value=new_plugins,
                  workplace=workplace)

        return True
Ejemplo n.º 24
0
def create_new_person(parent=None, activate=False):

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

    if activate:  # meaning we will switch away from the current patient if any
        msg = _('Before creating a new person review the encounter details\n'
                'of the patient you just worked on:\n')
        gmEncounterWidgets.sanity_check_encounter_of_active_patient(
            parent=parent, msg=msg)

        msg = _(
            'Edit the current encounter of the patient you are ABOUT TO LEAVE:'
        )

    dbcfg = gmCfg.cCfgSQL()

    def_region = dbcfg.get2(
        option='person.create.default_region',
        workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
        bias='user')
    def_country = None

    if def_region is None:
        def_country = dbcfg.get2(
            option='person.create.default_country',
            workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
            bias='user')
    else:
        countries = gmDemographicRecord.get_country_for_region(
            region=def_region)
        if len(countries) == 1:
            def_country = countries[0]['code_country']

    ea = cNewPatientEAPnl(parent, -1, country=def_country, region=def_region)
    dlg = gmEditArea.cGenericEditAreaDlg2(parent,
                                          -1,
                                          edit_area=ea,
                                          single_entry=True)
    dlg.SetTitle(_('Adding new person'))
    ea._PRW_lastname.SetFocus()
    result = dlg.ShowModal()
    pat = ea.data
    dlg.Destroy()

    if result != wx.ID_OK:
        return False

    _log.debug('created new person [%s]', pat.ID)

    if activate:
        from Gnumed.wxpython import gmPatSearchWidgets
        gmPatSearchWidgets.set_active_patient(patient=pat)

    gmDispatcher.send(signal='display_widget',
                      name='gmNotebookedPatientEditionPlugin')

    return True
Ejemplo n.º 25
0
	def _on_post_patient_selection(self, **kwargs):
		db_cfg = gmCfg.cCfgSQL()
		default_plugin = db_cfg.get2 (
			option = u'patient_search.plugin_to_raise_after_search',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = u'user',
			default = u'gmPatientOverviewPlugin'
		)
		gmDispatcher.send(signal = 'display_widget', name = default_plugin)
Ejemplo n.º 26
0
	def _on_char(self, evt):
		"""True: patient was selected.
		   False: no patient was selected.
		"""
		keycode = evt.GetKeyCode()

		# list of previously active patients
		if keycode == wx.WXK_DOWN:
			evt.Skip()
			if len(self.__prev_idents) == 0:
				return False

			dlg = cSelectPersonFromListDlg(wx.GetTopLevelParent(self), -1)
			dlg.set_persons(persons = self.__prev_idents)
			result = dlg.ShowModal()
			if result == wx.ID_OK:
				wx.BeginBusyCursor()
				self.person = dlg.get_selected_person()
				dlg.DestroyLater()
				wx.EndBusyCursor()
				return True

			dlg.DestroyLater()
			return False

		# recall previous search fragment
		if keycode == wx.WXK_UP:
			evt.Skip()
			# FIXME: cycling through previous fragments
			if self._prev_search_term is not None:
				self.SetValue(self._prev_search_term)
			return False

		# invoke external patient sources
		if keycode == wx.WXK_F2:
			evt.Skip()
			dbcfg = gmCfg.cCfgSQL()
			search_immediately = bool(dbcfg.get2 (
				option = 'patient_search.external_sources.immediately_search_if_single_source',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user',
				default = 0
			))
			p = get_person_from_external_sources (
				parent = wx.GetTopLevelParent(self),
				search_immediately = search_immediately
			)
			if p is not None:
				self.person = p
				return True
			return False

		# FIXME: invoke add new person
		# FIXME: add popup menu apart from system one

		evt.Skip()
Ejemplo n.º 27
0
	def _on_char(self, evt):
		"""True: patient was selected.
		   False: no patient was selected.
		"""
		keycode = evt.GetKeyCode()

		# list of previously active patients
		if keycode == wx.WXK_DOWN:
			evt.Skip()
			if len(self.__prev_idents) == 0:
				return False

			dlg = cSelectPersonFromListDlg(wx.GetTopLevelParent(self), -1)
			dlg.set_persons(persons = self.__prev_idents)
			result = dlg.ShowModal()
			if result == wx.ID_OK:
				wx.BeginBusyCursor()
				self.person = dlg.get_selected_person()
				dlg.DestroyLater()
				wx.EndBusyCursor()
				return True

			dlg.DestroyLater()
			return False

		# recall previous search fragment
		if keycode == wx.WXK_UP:
			evt.Skip()
			# FIXME: cycling through previous fragments
			if self._prev_search_term is not None:
				self.SetValue(self._prev_search_term)
			return False

		# invoke external patient sources
		if keycode == wx.WXK_F2:
			evt.Skip()
			dbcfg = gmCfg.cCfgSQL()
			search_immediately = bool(dbcfg.get2 (
				option = 'patient_search.external_sources.immediately_search_if_single_source',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user',
				default = 0
			))
			p = get_person_from_external_sources (
				parent = wx.GetTopLevelParent(self),
				search_immediately = search_immediately
			)
			if p is not None:
				self.person = p
				return True
			return False

		# FIXME: invoke add new person
		# FIXME: add popup menu apart from system one

		evt.Skip()
Ejemplo n.º 28
0
    def __init__(self, aUser=None, aWorkplace='xxxDEFAULTxxx'):
        """ Init DB connection"""
        ConfigData.__init__(self, "DB")

        # connect to config database
        if ConfigDataDB._dbcfg is None:
            ConfigDataDB._dbcfg = gmCfg.cCfgSQL()

        self.mUser = aUser
        self.mWorkplace = aWorkplace
Ejemplo n.º 29
0
	def __init__(self, aUser = None, aWorkplace = 'xxxDEFAULTxxx'):
		""" Init DB connection"""
		ConfigData.__init__(self,"DB")
		
		# connect to config database
		if ConfigDataDB._dbcfg is None:
			ConfigDataDB._dbcfg = gmCfg.cCfgSQL()

		self.mUser = aUser
		self.mWorkplace = aWorkplace
Ejemplo n.º 30
0
	def browse2schedules(vaccination=None):
		dbcfg = gmCfg.cCfgSQL()
		url = dbcfg.get2 (
			option = 'external.urls.vaccination_plans',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user',
			default = gmVaccination.URL_vaccination_plan
		)

		gmNetworkTools.open_url_in_browser(url = url)
		return False
Ejemplo n.º 31
0
	def browse2schedules(vaccination=None):
		dbcfg = gmCfg.cCfgSQL()
		url = dbcfg.get2 (
			option = 'external.urls.vaccination_plans',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user',
			default = u'http://www.bundesaerztekammer.de/downloads/STIKOEmpf2011.pdf'
		)

		gmNetworkTools.open_url_in_browser(url = url)
		return False
Ejemplo n.º 32
0
	def browse2schedules(vaccination=None):
		dbcfg = gmCfg.cCfgSQL()
		url = dbcfg.get2 (
			option = 'external.urls.vaccination_plans',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user',
			default = gmVaccination.URL_vaccination_plan
		)

		gmNetworkTools.open_url_in_browser(url = url)
		return False
Ejemplo n.º 33
0
def create_new_person(parent=None, activate=False):

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

	if activate:			# meaning we will switch away from the current patient if any
		msg = _(
			'Before creating a new person review the encounter details\n'
			'of the patient you just worked on:\n'
		)
		gmEncounterWidgets.sanity_check_encounter_of_active_patient(parent = parent, msg = msg)

		msg = _('Edit the current encounter of the patient you are ABOUT TO LEAVE:')

	dbcfg = gmCfg.cCfgSQL()

	def_region = dbcfg.get2 (
		option = 'person.create.default_region',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'user'
	)
	def_country = None

	if def_region is None:
		def_country = dbcfg.get2 (
			option = 'person.create.default_country',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user'
		)
	else:
		countries = gmDemographicRecord.get_country_for_region(region = def_region)
		if len(countries) == 1:
			def_country = countries[0]['code_country']

	ea = cNewPatientEAPnl(parent, -1, country = def_country, region = def_region)
	dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = True)
	dlg.SetTitle(_('Adding new person'))
	ea._PRW_lastname.SetFocus()
	result = dlg.ShowModal()
	pat = ea.data
	dlg.DestroyLater()

	if result != wx.ID_OK:
		return False

	_log.debug('created new person [%s]', pat.ID)

	if activate:
		from Gnumed.wxpython import gmPatSearchWidgets
		gmPatSearchWidgets.set_active_patient(patient = pat)

	gmDispatcher.send(signal = 'display_widget', name = 'gmNotebookedPatientEditionPlugin')

	return True
Ejemplo n.º 34
0
    def edit(workplace=None):

        dbcfg = gmCfg.cCfgSQL()

        if workplace is None:
            dlg = wx.TextEntryDialog(
                parent=parent,
                message=_('Enter a descriptive name for the new workplace:'),
                caption=_('Configuring GNUmed workplaces ...'),
                defaultValue=u'',
                style=wx.OK | wx.CENTRE)
            dlg.ShowModal()
            workplace = dlg.GetValue().strip()
            if workplace == u'':
                gmGuiHelpers.gm_show_error(
                    _('Cannot save a new workplace without a name.'),
                    _('Configuring GNUmed workplaces ...'))
                return False
            curr_plugins = []
        else:
            curr_plugins = gmTools.coalesce(
                dbcfg.get2(option=u'horstspace.notebook.plugin_load_order',
                           workplace=workplace,
                           bias='workplace'), [])

        msg = _(
            'Pick the plugin(s) to be loaded the next time the client is restarted under the workplace:\n'
            '\n'
            '    [%s]\n') % workplace

        picker = gmListWidgets.cItemPickerDlg(
            parent, -1, title=_('Configuring workplace plugins ...'), msg=msg)
        picker.set_columns(['Available plugins'], ['Active plugins'])
        available_plugins = gmPlugin.get_installed_plugins(plugin_dir='gui')
        picker.set_choices(available_plugins)
        picker.set_picks(picks=curr_plugins[:])
        btn_pressed = picker.ShowModal()
        if btn_pressed != wx.ID_OK:
            picker.Destroy()
            return False

        new_plugins = picker.get_picks()
        picker.Destroy()
        if new_plugins == curr_plugins:
            return True

        if new_plugins is None:
            return True

        dbcfg.set(option=u'horstspace.notebook.plugin_load_order',
                  value=new_plugins,
                  workplace=workplace)

        return True
Ejemplo n.º 35
0
	def _on_report_button_pressed(self, event):
		event.Skip()
		dbcfg = gmCfg.cCfgSQL()
		url = dbcfg.get2 (
			option = 'external.urls.report_vaccine_ADR',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user'
		)
		if url.strip() == '':
			url = dbcfg.get2 (
				option = 'external.urls.report_ADR',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user'
			)
		gmNetworkTools.open_url_in_browser(url = url)
Ejemplo n.º 36
0
	def _on_report_button_pressed(self, event):
		event.Skip()
		dbcfg = gmCfg.cCfgSQL()
		url = dbcfg.get2 (
			option = 'external.urls.report_vaccine_ADR',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user'
		)
		if url.strip() == '':
			url = dbcfg.get2 (
				option = 'external.urls.report_ADR',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = 'user'
			)
		gmNetworkTools.open_url_in_browser(url = url)
Ejemplo n.º 37
0
	def __init__(self, parent, id):
		"""Set up our specialised grid.
		"""
		# get connection
		self.__backend = gmPG.ConnectionPool()
		self.__defconn = self.__backend.GetConnection('blobs')
		if self.__defconn is None:
			_log.Log(gmLog.lErr, "Cannot retrieve lab data without database connection !")
			raise gmExceptions.ConstructorError, "cLabDataGrid.__init__(): need db conn"

		# connect to config database
		self.__dbcfg = gmCfg.cCfgSQL(
			aConn = self.__backend.GetConnection('default'),
			aDBAPI = gmPG.dbapi
		)
		
		wx.Grid.__init__(
			self,
			parent,
			id,
			pos = wx.DefaultPosition,
			size = wx.DefaultSize,
			style= wx.WANTS_CHARS
			)
		
		self.__pat = gmPerson.gmCurrentPatient()

		#wx.EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick)
		
		# create new grid
		self.__grid_unreviewed_results = self.CreateGrid(0, 0, wx.Grid.wx.GridSelectCells )
		self.SetDefaultCellAlignment(wx.ALIGN_RIGHT,wx.ALIGN_CENTRE)
		#renderer = apply(wxGridCellStringRenderer, ())
		renderer = apply(cLabDataGridCellRenderer, ())
		self.SetDefaultRenderer(renderer)
		
		# There is a bug in wxGTK for this method...
		self.AutoSizeColumns(True)
		self.AutoSizeRows(True)
		# attribute objects let you keep a set of formatting values
		# in one spot, and reuse them if needed
		font = self.GetFont()
		#font.SetWeight(wx.BOLD)
		attr = wx.GridCellAttr()
		attr.SetFont(font)
		#attr.SetBackgroundColour(wx.LIGHT_GREY)
		attr.SetReadOnly(True)
Ejemplo n.º 38
0
	def __init__(self, parent, id):
		"""Set up our specialised grid.
		"""
		# get connection
		self.__backend = gmPG.ConnectionPool()
		self.__defconn = self.__backend.GetConnection('blobs')
		if self.__defconn is None:
			_log.Log(gmLog.lErr, "Cannot retrieve lab data without database connection !")
			raise gmExceptions.ConstructorError, "cLabDataGrid.__init__(): need db conn"

		# connect to config database
		self.__dbcfg = gmCfg.cCfgSQL(
			aConn = self.__backend.GetConnection('default'),
			aDBAPI = gmPG.dbapi
		)
		
		wx.Grid.__init__(
			self,
			parent,
			id,
			pos = wx.DefaultPosition,
			size = wx.DefaultSize,
			style= wx.WANTS_CHARS
			)
		
		self.__pat = gmPerson.gmCurrentPatient()

		#wx.EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick)
		
		# create new grid
		self.__grid_unreviewed_results = self.CreateGrid(0, 0, wx.Grid.wx.GridSelectCells )
		self.SetDefaultCellAlignment(wx.ALIGN_RIGHT,wx.ALIGN_CENTRE)
		#renderer = apply(wxGridCellStringRenderer, ())
		renderer = apply(cLabDataGridCellRenderer, ())
		self.SetDefaultRenderer(renderer)
		
		# There is a bug in wxGTK for this method...
		self.AutoSizeColumns(True)
		self.AutoSizeRows(True)
		# attribute objects let you keep a set of formatting values
		# in one spot, and reuse them if needed
		font = self.GetFont()
		#font.SetWeight(wx.BOLD)
		attr = wx.GridCellAttr()
		attr.SetFont(font)
		#attr.SetBackgroundColour(wx.LIGHT_GREY)
		attr.SetReadOnly(True)
Ejemplo n.º 39
0
	def new():
		cfg_db = gmCfg.cCfgSQL()
		enc_type = cfg_db.get2 (
			option = u'encounter.default_type',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = u'user'
		)
		if enc_type is None:
			enc_type = gmEMRStructItems.get_most_commonly_used_encounter_type()
		if enc_type is None:
			enc_type = u'in surgery'
		enc = gmEMRStructItems.create_encounter(fk_patient = patient.ID, enc_type = enc_type)
		saved = edit_encounter(parent = parent, encounter = enc)
		if saved:
			return True
		gmEMRStructItems.delete_encounter(pk_encounter = enc['pk_encounter'])
		return False
Ejemplo n.º 40
0
def GetPluginLoadList(option, plugin_dir = '', defaults = None, workplace=None):
	"""Get a list of plugins to load.

	1) from database if option is not None
	2) from list of defaults
	3) if 2 is None, from source directory (then stored in database)

	FIXME: NOT from files in directories (important for py2exe)
	"""
	if workplace == 'System Fallback':
		return ['gmProviderInboxPlugin', 'gmDataMiningPlugin']

	if workplace is None:
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace

	p_list = None

	if option is not None:
		dbcfg = gmCfg.cCfgSQL()
		p_list = dbcfg.get2 (
			option = option,
			workplace = workplace,
			bias = 'workplace',
			default = defaults
		)

	if p_list is not None:
		return p_list

	if defaults is None:
		p_list = get_installed_plugins(plugin_dir = plugin_dir)
		if (len(p_list) == 0):
			_log.error('cannot find plugins by scanning plugin directory ?!?')
			return defaults
	else:
		p_list = defaults

	# store for current user/current workplace
	dbcfg.set (
		option = option,
		value = p_list,
		workplace = workplace
	)

	_log.debug("plugin load list stored: %s" % str(p_list))
	return p_list
Ejemplo n.º 41
0
	def _on_report_button_pressed(self, event):
		event.Skip()
		dbcfg = gmCfg.cCfgSQL()
		url = dbcfg.get2 (
			option = u'external.urls.report_vaccine_ADR',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = u'user',
			default = u'http://www.pei.de/cln_042/SharedDocs/Downloads/fachkreise/uaw/meldeboegen/b-ifsg-meldebogen,templateId=raw,property=publicationFile.pdf/b-ifsg-meldebogen.pdf'
		)

		if url.strip() == u'':
			url = dbcfg.get2 (
				option = u'external.urls.report_ADR',
				workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
				bias = u'user'
			)
		gmNetworkTools.open_url_in_browser(url = url)
Ejemplo n.º 42
0
def load_persons_from_kvks():

	dbcfg = gmCfg.cCfgSQL()
	kvk_dir = os.path.abspath(os.path.expanduser(dbcfg.get2 (
		option = 'DE.KVK.spool_dir',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'workplace',
		default = '/var/spool/kvkd/'
		#default = u'/home/ncq/gnumed/'
	)))
	dtos = []
	for dto in gmKVK.get_available_kvks_as_dtos(spool_dir = kvk_dir):
		dtos.append({'dto': dto, 'source': 'KVK'})
#	for dto in gmKVK.get_available_CCRdr_files_as_dtos(spool_dir = kvk_dir):
#		dtos.append({'dto': dto, 'source': dto.source})

	return dtos
Ejemplo n.º 43
0
def load_persons_from_kvks():

	dbcfg = gmCfg.cCfgSQL()
	kvk_dir = os.path.abspath(os.path.expanduser(dbcfg.get2 (
		option = 'DE.KVK.spool_dir',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'workplace',
		default = '/var/spool/kvkd/'
		#default = u'/home/ncq/gnumed/'
	)))
	dtos = []
	for dto in gmKVK.get_available_kvks_as_dtos(spool_dir = kvk_dir):
		dtos.append({'dto': dto, 'source': 'KVK'})
#	for dto in gmKVK.get_available_CCRdr_files_as_dtos(spool_dir = kvk_dir):
#		dtos.append({'dto': dto, 'source': dto.source})

	return dtos
Ejemplo n.º 44
0
def configure_list_from_list_option(parent=None,
                                    message=None,
                                    option=None,
                                    bias='user',
                                    default_value=None,
                                    choices=None,
                                    columns=None,
                                    data=None,
                                    caption=None,
                                    picks=None):

    if default_value is None:
        default_value = []

    dbcfg = gmCfg.cCfgSQL()

    current_value = dbcfg.get2(
        option=option,
        workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
        bias=bias,
        default=default_value)

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

    if caption is None:
        caption = _('Configuration')

    # setup item picker
    picker = gmListWidgets.cItemPickerDlg(parent, -1, msg=message)
    picker.set_columns(columns)
    picker.set_choices(choices)
    picker.set_picks(picks)
    result = picker.ShowModal()
    if result == wx.ID_CANCEL:
        picker.DestroyLater()
        return

    picks = picker.get_picks()
    picker.DestroyLater()

    dbcfg.set(workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
              option=option,
              value=picks)

    return
Ejemplo n.º 45
0
 def new():
     cfg_db = gmCfg.cCfgSQL()
     enc_type = cfg_db.get2(
         option=u'encounter.default_type',
         workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
         bias=u'user')
     if enc_type is None:
         enc_type = gmEMRStructItems.get_most_commonly_used_encounter_type()
     if enc_type is None:
         enc_type = u'in surgery'
     enc = gmEMRStructItems.create_encounter(fk_patient=patient.ID,
                                             enc_type=enc_type)
     saved = edit_encounter(parent=parent, encounter=enc)
     if saved:
         return True
     gmEMRStructItems.delete_encounter(pk_encounter=enc['pk_encounter'])
     return False
Ejemplo n.º 46
0
def configure_boolean_option(parent=None,
                             question=None,
                             option=None,
                             button_tooltips=None):

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

    tooltips = [
        _('Set "%s" to <True>.') % option,
        _('Set "%s" to <False>.') % option,
        _('Abort the dialog and do not change the current setting.')
    ]
    if button_tooltips is not None:
        for idx in range(len(button_tooltips)):
            tooltips[idx] = button_tooltips[idx]

    dlg = gmGuiHelpers.c3ButtonQuestionDlg(parent,
                                           -1,
                                           caption=_('Configuration'),
                                           question=question,
                                           button_defs=[{
                                               'label': _('Yes'),
                                               'tooltip': tooltips[0]
                                           }, {
                                               'label': _('No'),
                                               'tooltip': tooltips[1]
                                           }, {
                                               'label': _('Cancel'),
                                               'tooltip': tooltips[2],
                                               'default': True
                                           }])

    decision = dlg.ShowModal()
    dbcfg = gmCfg.cCfgSQL()
    if decision == wx.ID_YES:
        dbcfg.set(workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
                  option=option,
                  value=True)
    elif decision == wx.ID_NO:
        dbcfg.set(workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
                  option=option,
                  value=False)

    return
Ejemplo n.º 47
0
def configure_boolean_option(parent=None, question=None, option=None, button_tooltips=None):

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

	tooltips = [
		_('Set "%s" to <True>.') % option,
		_('Set "%s" to <False>.') % option,
		_('Abort the dialog and do not change the current setting.')
	]
	if button_tooltips is not None:
		for idx in range(len(button_tooltips)):
			tooltips[idx] = button_tooltips[idx]

	dlg = gmGuiHelpers.c3ButtonQuestionDlg (
		parent,
		-1,
		caption = _('Configuration'),
		question = question,
		button_defs = [
			{'label': _('Yes'), 'tooltip': tooltips[0]},
			{'label': _('No'), 'tooltip': tooltips[1]},
			{'label': _('Cancel'), 'tooltip': tooltips[2], 'default': True}
		]
	)

	decision = dlg.ShowModal()
	dbcfg = gmCfg.cCfgSQL()
	if decision == wx.ID_YES:
		dbcfg.set (
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			option = option,
			value = True
		)
	elif decision == wx.ID_NO:
		dbcfg.set (
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			option = option,
			value = False
		)

	return
Ejemplo n.º 48
0
def GetPluginLoadList(option, plugin_dir='', defaults=None, workplace=None):
    """Get a list of plugins to load.

	1) from database if option is not None
	2) from list of defaults
	3) if 2 is None, from source directory (then stored in database)

	FIXME: NOT from files in directories (important for py2exe)
	"""
    if workplace == 'System Fallback':
        return ['gmProviderInboxPlugin', 'gmDataMiningPlugin']

    if workplace is None:
        workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace

    p_list = None

    if option is not None:
        dbcfg = gmCfg.cCfgSQL()
        p_list = dbcfg.get2(option=option,
                            workplace=workplace,
                            bias='workplace',
                            default=defaults)

    if p_list is not None:
        return p_list

    if defaults is None:
        p_list = get_installed_plugins(plugin_dir=plugin_dir)
        if (len(p_list) == 0):
            _log.error('cannot find plugins by scanning plugin directory ?!?')
            return defaults
    else:
        p_list = defaults

    # store for current user/current workplace
    dbcfg.set(option=option, value=p_list, workplace=workplace)

    _log.debug("plugin load list stored: %s" % str(p_list))
    return p_list
Ejemplo n.º 49
0
def configure_list_from_list_option(parent=None, message=None, option=None, bias='user', default_value=None, choices=None, columns=None, data=None, caption=None, picks=None):

	if default_value is None:
		default_value = []

	dbcfg = gmCfg.cCfgSQL()

	current_value = dbcfg.get2 (
		option = option,
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = bias,
		default = default_value
	)

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

	if caption is None:
		caption = _('Configuration')

	# setup item picker
	picker = gmListWidgets.cItemPickerDlg(parent, -1, msg = message)
	picker.set_columns(columns)
	picker.set_choices(choices)
	picker.set_picks(picks)
	result = picker.ShowModal()
	if result == wx.ID_CANCEL:
		picker.DestroyLater()
		return

	picks = picker.get_picks()
	picker.DestroyLater()

	dbcfg.set (
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		option = option,
		value = picks
	)

	return
Ejemplo n.º 50
0
def _get_very_recent_encounter(pk_identity):
	cfg_db = gmCfg.cCfgSQL()
	min_ttl = cfg_db.get2 (
		option = u'encounter.minimum_ttl',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = u'user',
		default = u'1 hour 30 minutes'
	)
	cmd = u"""
		SELECT pk_encounter
		FROM clin.v_most_recent_encounters
		WHERE
			pk_patient = %s
				and
			last_affirmed > (now() - %s::interval)
		ORDER BY
			last_affirmed DESC"""
	rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [pk_identity, min_ttl]}])
	if len(rows) == 0:
		_log.debug('no <very recent> encounter (younger than [%s]) found' % min_ttl)
		return None
	_log.debug('"very recent" encounter [%s] found and re-activated', rows[0][0])
	return gmEMRStructItems.cEncounter(aPK_obj = rows[0][0])
Ejemplo n.º 51
0
def _decide_on_active_encounter(pk_identity):

	enc = _get_very_recent_encounter(pk_identity)
	if enc is not None:
		return enc

	_here = gmPraxis.gmCurrentPraxisBranch()
	cfg_db = gmCfg.cCfgSQL()
	enc_type = cfg_db.get2 (
		option = u'encounter.default_type',
		workplace = _here.active_workplace,
		bias = u'user'
	)
	if enc_type is None:
		enc_type = gmEMRStructItems.get_most_commonly_used_encounter_type()
	if enc_type is None:
		enc_type = u'in surgery'
	enc = gmEMRStructItems.create_encounter(fk_patient = pk_identity, enc_type = enc_type)
	enc['pk_org_unit'] = _here['pk_org_unit']
	enc.save()
	_log.debug('new encounter [%s] initiated' % enc['pk_encounter'])

	return enc
Ejemplo n.º 52
0
	def __refresh_soap_notebook(self):
		self.__reset_soap_notebook()

		if self.__pat is None:
			return

		dbcfg = gmCfg.cCfgSQL()
		auto_open_recent_problems = bool(dbcfg.get2 (
			option = 'horstspace.soap_editor.auto_open_latest_episodes',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user',
			default = True
		))

		emr = self.__pat.emr
		recent_epis = emr.active_encounter.get_episodes()
		prev_enc = emr.get_last_but_one_encounter()
		if prev_enc is not None:
			recent_epis.extend(prev_enc.get_episodes())

		for epi in recent_epis:
			if not epi['episode_open']:
				continue
			self._NB_soap_editors.add_editor(problem = epi)
Ejemplo n.º 53
0
	def __refresh_soap_notebook(self):
		self.__reset_soap_notebook()

		if self.__pat is None:
			return

		dbcfg = gmCfg.cCfgSQL()
		auto_open_recent_problems = bool(dbcfg.get2 (
			option = 'horstspace.soap_editor.auto_open_latest_episodes',
			workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
			bias = 'user',
			default = True
		))

		emr = self.__pat.emr
		recent_epis = emr.active_encounter.get_episodes()
		prev_enc = emr.get_last_but_one_encounter()
		if prev_enc is not None:
			recent_epis.extend(prev_enc.get_episodes())

		for epi in recent_epis:
			if not epi['episode_open']:
				continue
			self._NB_soap_editors.add_editor(problem = epi)
Ejemplo n.º 54
0
def load_data_packs_list():

    dbcfg = gmCfg.cCfgSQL()
    dpl_url = dbcfg.get2(
        option=dpl_url_option,
        workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
        bias='workplace',
        default=default_dpl_url)

    items = []
    data = []

    dpl_fname = gmNetworkTools.download_data_packs_list(dpl_url)
    if dpl_fname is None:
        return (items, data)
    try:
        _cfg.add_file_source(source='data-packs', file=dpl_fname)
    except (UnicodeDecodeError):
        _log.exception("cannot read data pack list from [%s]", dpl_fname)
        return (items, data)

    packs = _cfg.get('data packs',
                     'data packs',
                     source_order=[('data-packs', 'return')])
    if packs is None:
        _log.info('no data packs listed in data packs list file')
        _cfg.remove_source('data-packs')
        return (items, data)

    for pack in packs:
        _log.debug('reading pack [%s] metadata', pack)
        pack_group = u'pack %s' % pack
        name = _cfg.get(pack_group,
                        u'name',
                        source_order=[('data-packs', 'return')])
        pack_url = _cfg.get(pack_group,
                            u'URL',
                            source_order=[('data-packs', 'return')])
        md5_url = pack_url + u'.md5'
        db_min = _cfg.get(pack_group,
                          u'minimum database version',
                          source_order=[('data-packs', 'return')])
        converted, db_min = gmTools.input2int(
            db_min,
            # here we introduced data packs:
            #16,
            0,
            # no use looking at data packs requiring a database > the current database:
            _cfg.get(option='database_version'))
        if not converted:
            _log.error('cannot convert minimum database version [%s]', db_min)
            continue

        db_max = _cfg.get(pack_group,
                          u'maximum database version',
                          source_order=[('data-packs', 'return')])
        if db_max is None:
            db_max = sys.maxint
        converted, db_max = gmTools.input2int(
            db_max,
            db_min  # max version must be at least db_min
        )
        if not converted:
            _log.error('cannot convert maximum database version [%s]', db_max)
            continue

        if _cfg.get(option='database_version') < db_min:
            _log.error(
                'ignoring data pack: current database version (%s) < minimum required database version (%s)',
                _cfg.get(option='database_version'), db_min)
            continue

        if _cfg.get(option='database_version') > db_max:
            _log.error(
                'ignoring data pack: current database version (%s) > maximum allowable database version (%s)',
                _cfg.get(option='database_version'), db_max)
            continue

        items.append([name, u'v%s' % db_min, u'v%s' % db_max, pack_url])
        data.append({
            'name': name,
            'pack_url': pack_url,
            'md5_url': md5_url,
            'db_min': db_min,
            'db_max': db_max
        })

    _cfg.remove_source('data-packs')
    return (items, data)
Ejemplo n.º 55
0
def move_episode_to_issue(episode=None, target_issue=None, save_to_backend=False):
	"""Prepare changing health issue for an episode.

	Checks for two-open-episodes conflict. When this
	function succeeds, the pk_health_issue has been set
	on the episode instance and the episode should - for
	all practical purposes - be ready for save_payload().
	"""
	# episode is closed: should always work
	if not episode['episode_open']:
		episode['pk_health_issue'] = target_issue['pk_health_issue']
		if save_to_backend:
			episode.save_payload()
		return True

	# un-associate: should always work, too
	if target_issue is None:
		episode['pk_health_issue'] = None
		if save_to_backend:
			episode.save_payload()
		return True

	# try closing possibly expired episode on target issue if any
	db_cfg = gmCfg.cCfgSQL()
	epi_ttl = int(db_cfg.get2 (
		option = 'episode.ttl',
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'user',
		default = 60				# 2 months
	))
	if target_issue.close_expired_episode(ttl=epi_ttl) is True:
		gmDispatcher.send(signal='statustext', msg=_('Closed episodes older than %s days on health issue [%s]') % (epi_ttl, target_issue['description']))
	existing_epi = target_issue.get_open_episode()

	# no more open episode on target issue: should work now
	if existing_epi is None:
		episode['pk_health_issue'] = target_issue['pk_health_issue']
		if save_to_backend:
			episode.save_payload()
		return True

	# don't conflict on SELF ;-)
	if existing_epi['pk_episode'] == episode['pk_episode']:
		episode['pk_health_issue'] = target_issue['pk_health_issue']
		if save_to_backend:
			episode.save_payload()
		return True

	# we got two open episodes at once, ask user
	move_range = (episode.best_guess_clinical_start_date, episode.best_guess_clinical_end_date)
	if move_range[1] is None:
		move_range_end = '?'
	else:
		move_range_end = move_range[1].strftime('%m/%y')
	exist_range = (existing_epi.best_guess_clinical_start_date, existing_epi.best_guess_clinical_end_date)
	if exist_range[1] is None:
		exist_range_end = '?'
	else:
		exist_range_end = exist_range[1].strftime('%m/%y')
	question = _(
		'You want to associate the running episode:\n\n'
		' "%(new_epi_name)s" (%(new_epi_start)s - %(new_epi_end)s)\n\n'
		'with the health issue:\n\n'
		' "%(issue_name)s"\n\n'
		'There already is another episode running\n'
		'for this health issue:\n\n'
		' "%(old_epi_name)s" (%(old_epi_start)s - %(old_epi_end)s)\n\n'
		'However, there can only be one running\n'
		'episode per health issue.\n\n'
		'Which episode do you want to close ?'
	) % {
		'new_epi_name': episode['description'],
		'new_epi_start': move_range[0].strftime('%m/%y'),
		'new_epi_end': move_range_end,
		'issue_name': target_issue['description'],
		'old_epi_name': existing_epi['description'],
		'old_epi_start': exist_range[0].strftime('%m/%y'),
		'old_epi_end': exist_range_end
	}
	dlg = gmGuiHelpers.c3ButtonQuestionDlg (
		parent = None,
		id = -1,
		caption = _('Resolving two-running-episodes conflict'),
		question = question,
		button_defs = [
			{'label': _('old episode'), 'default': True, 'tooltip': _('close existing episode "%s"') % existing_epi['description']},
			{'label': _('new episode'), 'default': False, 'tooltip': _('close moving (new) episode "%s"') % episode['description']}
		]
	)
	decision = dlg.ShowModal()

	if decision == wx.ID_CANCEL:
		# button 3: move cancelled by user
		return False

	elif decision == wx.ID_YES:
		# button 1: close old episode
		existing_epi['episode_open'] = False
		existing_epi.save_payload()

	elif decision == wx.ID_NO:
		# button 2: close new episode
		episode['episode_open'] = False

	else:
		raise ValueError('invalid result from c3ButtonQuestionDlg: [%s]' % decision)

	episode['pk_health_issue'] = target_issue['pk_health_issue']
	if save_to_backend:
		episode.save_payload()
	return True
Ejemplo n.º 56
0
def edit_visual_progress_note(filename=None,
                              episode=None,
                              discard_unmodified=False,
                              doc_part=None,
                              health_issue=None):
    """This assumes <filename> contains an image which can be handled by the configured image editor."""

    if doc_part is not None:
        filename = doc_part.export_to_file()
        if filename is None:
            gmDispatcher.send(
                signal=u'statustext',
                msg=_('Cannot export visual progress note to file.'))
            return None

    dbcfg = gmCfg.cCfgSQL()
    cmd = dbcfg.get2(
        option=u'external.tools.visual_soap_editor_cmd',
        workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace,
        bias='user')

    if cmd is None:
        gmDispatcher.send(
            signal=u'statustext',
            msg=_('Editor for visual progress note not configured.'),
            beep=False)
        cmd = configure_visual_progress_note_editor()
        if cmd is None:
            gmDispatcher.send(
                signal=u'statustext',
                msg=_('Editor for visual progress note not configured.'),
                beep=True)
            return None

    if u'%(img)s' in cmd:
        cmd = cmd % {u'img': filename}
    else:
        cmd = u'%s %s' % (cmd, filename)

    if discard_unmodified:
        original_stat = os.stat(filename)
        original_md5 = gmTools.file2md5(filename)

    success = gmShellAPI.run_command_in_shell(cmd, blocking=True)
    if not success:
        gmGuiHelpers.gm_show_error(
            _('There was a problem with running the editor\n'
              'for visual progress notes.\n'
              '\n'
              ' [%s]\n'
              '\n') % cmd, _('Editing visual progress note'))
        return None

    try:
        open(filename, 'r').close()
    except Exception:
        _log.exception('problem accessing visual progress note file [%s]',
                       filename)
        gmGuiHelpers.gm_show_error(
            _('There was a problem reading the visual\n'
              'progress note from the file:\n'
              '\n'
              ' [%s]\n'
              '\n') % filename, _('Saving visual progress note'))
        return None

    if discard_unmodified:
        modified_stat = os.stat(filename)
        # same size ?
        if original_stat.st_size == modified_stat.st_size:
            modified_md5 = gmTools.file2md5(filename)
            # same hash ?
            if original_md5 == modified_md5:
                _log.debug('visual progress note (template) not modified')
                # ask user to decide
                msg = _(
                    u'You either created a visual progress note from a template\n'
                    u'in the database (rather than from a file on disk) or you\n'
                    u'edited an existing visual progress note.\n'
                    u'\n'
                    u'The template/original was not modified at all, however.\n'
                    u'\n'
                    u'Do you still want to save the unmodified image as a\n'
                    u'visual progress note into the EMR of the patient ?\n')
                save_unmodified = gmGuiHelpers.gm_show_question(
                    msg, _('Saving visual progress note'))
                if not save_unmodified:
                    _log.debug('user discarded unmodified note')
                    return

    if doc_part is not None:
        _log.debug('updating visual progress note')
        doc_part.update_data_from_file(fname=filename)
        doc_part.set_reviewed(technically_abnormal=False,
                              clinically_relevant=True)
        return None

    if not isinstance(episode, gmEMRStructItems.cEpisode):
        if episode is None:
            episode = _('visual progress notes')
        pat = gmPerson.gmCurrentPatient()
        emr = pat.emr
        episode = emr.add_episode(episode_name=episode.strip(),
                                  pk_health_issue=health_issue,
                                  is_open=False)

    doc = gmDocumentWidgets.save_file_as_new_document(
        filename=filename,
        document_type=gmDocuments.DOCUMENT_TYPE_VISUAL_PROGRESS_NOTE,
        episode=episode,
        unlock_patient=False,
        pk_org_unit=gmPraxis.gmCurrentPraxisBranch()['pk_org_unit'])
    doc.set_reviewed(technically_abnormal=False, clinically_relevant=True)

    return doc
Ejemplo n.º 57
0
def load_data_packs_list():

	dbcfg = gmCfg.cCfgSQL()
	dpl_url = dbcfg.get2 (
		option = dpl_url_option,
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'workplace',
		default = default_dpl_url
	)

	items = []
	data = []

	dpl_fname = gmNetworkTools.download_data_packs_list(dpl_url)
	if dpl_fname is None:
		return (items, data)
	try:
		_cfg.add_file_source(source = 'data-packs', file = dpl_fname)
	except (UnicodeDecodeError):
		_log.exception("cannot read data pack list from [%s]", dpl_fname)
		return (items, data)

	packs = _cfg.get('data packs', 'data packs', source_order = [('data-packs', 'return')])
	if packs is None:
		_log.info('no data packs listed in data packs list file')
		_cfg.remove_source('data-packs')
		return (items, data)

	for pack in packs:
		_log.debug('reading pack [%s] metadata', pack)
		pack_group = u'pack %s' % pack
		name = _cfg.get(pack_group, u'name', source_order = [('data-packs', 'return')])
		pack_url = _cfg.get(pack_group, u'URL', source_order = [('data-packs', 'return')])
		md5_url = pack_url + u'.md5'
		db_min = _cfg.get(pack_group, u'minimum database version', source_order = [('data-packs', 'return')])
		converted, db_min = gmTools.input2int (
			db_min,
			# here we introduced data packs:
			#16,
			0,
			# no use looking at data packs requiring a database > the current database:
			_cfg.get(option = 'database_version')
		)
		if not converted:
			_log.error('cannot convert minimum database version [%s]', db_min)
			continue

		db_max = _cfg.get(pack_group, u'maximum database version', source_order = [('data-packs', 'return')])
		if db_max is None:
			db_max = sys.maxint
		converted, db_max = gmTools.input2int (
			db_max,
			db_min		# max version must be at least db_min
		)
		if not converted:
			_log.error('cannot convert maximum database version [%s]', db_max)
			continue

		if _cfg.get(option = 'database_version') < db_min:
			_log.error('ignoring data pack: current database version (%s) < minimum required database version (%s)', _cfg.get(option = 'database_version'), db_min)
			continue

		if _cfg.get(option = 'database_version') > db_max:
			_log.error('ignoring data pack: current database version (%s) > maximum allowable database version (%s)', _cfg.get(option = 'database_version'), db_max)
			continue

		items.append([name, u'v%s' % db_min, u'v%s' % db_max, pack_url])
		data.append ({
			'name': name,
			'pack_url': pack_url,
			'md5_url': md5_url,
			'db_min': db_min,
			'db_max': db_max
		})

	_cfg.remove_source('data-packs')
	return (items, data)