diff --git a/tailbone/templates/customers/configure.mako b/tailbone/templates/customers/configure.mako
index 9013bd5b..93a72327 100644
--- a/tailbone/templates/customers/configure.mako
+++ b/tailbone/templates/customers/configure.mako
@@ -26,6 +26,15 @@
+
+
+ Link directly to Profile when applicable
+
+
+
+
+<%def name="form_content()">
+
+ General
+
+
+
+
+ Link directly to Profile when applicable
+
+
+
+
+%def>
+
+
+${parent.body()}
diff --git a/tailbone/templates/members/configure.mako b/tailbone/templates/members/configure.mako
index 07d67970..c0e0355d 100644
--- a/tailbone/templates/members/configure.mako
+++ b/tailbone/templates/members/configure.mako
@@ -26,6 +26,15 @@
+
+
+ Link directly to Profile when applicable
+
+
+
%def>
diff --git a/tailbone/templates/people/configure.mako b/tailbone/templates/people/configure.mako
new file mode 100644
index 00000000..c936b2f9
--- /dev/null
+++ b/tailbone/templates/people/configure.mako
@@ -0,0 +1,22 @@
+## -*- coding: utf-8; -*-
+<%inherit file="/configure.mako" />
+
+<%def name="form_content()">
+
+
General
+
+
+
+
+ Link directly to Profile when applicable
+
+
+
+
+%def>
+
+
+${parent.body()}
diff --git a/tailbone/views/customers.py b/tailbone/views/customers.py
index 601f8423..217d0770 100644
--- a/tailbone/views/customers.py
+++ b/tailbone/views/customers.py
@@ -124,6 +124,7 @@ class CustomerView(MasterView):
def configure_grid(self, g):
super(CustomerView, self).configure_grid(g)
model = self.model
+ route_prefix = self.get_route_prefix()
# customer key
field = self.get_customer_key_field()
@@ -172,10 +173,42 @@ class CustomerView(MasterView):
g.filters['active_in_pos'].default_active = True
g.filters['active_in_pos'].default_verb = 'is_true'
+ if (self.request.has_perm('people.view_profile')
+ and self.should_link_straight_to_profile()):
+
+ # add View Raw action
+ url = lambda r, i: self.request.route_url(
+ f'{route_prefix}.view', **self.get_action_route_kwargs(r))
+ # nb. insert to slot 1, just after normal View action
+ g.main_actions.insert(1, self.make_action(
+ 'view_raw', url=url, icon='eye'))
+
g.set_link('name')
g.set_link('person')
g.set_link('email')
+ def default_view_url(self):
+ if (self.request.has_perm('people.view_profile')
+ and self.should_link_straight_to_profile()):
+ app = self.get_rattail_app()
+
+ def url(customer, i):
+ person = app.get_person(customer)
+ if person:
+ return self.request.route_url(
+ 'people.view_profile', uuid=person.uuid,
+ _anchor='customer')
+ return self.get_action_url('view', customer)
+
+ return url
+
+ return super().default_view_url()
+
+ def should_link_straight_to_profile(self):
+ return self.rattail_config.getbool('rattail',
+ 'customers.straight_to_profile',
+ default=False)
+
def grid_extra_class(self, customer, i):
if self.get_expose_active_in_pos():
if not customer.active_in_pos:
@@ -579,6 +612,9 @@ class CustomerView(MasterView):
{'section': 'rattail',
'option': 'customers.choice_uses_dropdown',
'type': bool},
+ {'section': 'rattail',
+ 'option': 'customers.straight_to_profile',
+ 'type': bool},
{'section': 'rattail',
'option': 'customers.expose_shoppers',
'type': bool,
diff --git a/tailbone/views/employees.py b/tailbone/views/employees.py
index 37692996..cba75fb9 100644
--- a/tailbone/views/employees.py
+++ b/tailbone/views/employees.py
@@ -45,6 +45,7 @@ class EmployeeView(MasterView):
touchable = True
supports_autocomplete = True
results_downloadable = True
+ configurable = True
labels = {
'id': "ID",
@@ -143,9 +144,41 @@ class EmployeeView(MasterView):
g.set_label('email', "Email Address")
+ if (self.request.has_perm('people.view_profile')
+ and self.should_link_straight_to_profile()):
+
+ # add View Raw action
+ url = lambda r, i: self.request.route_url(
+ f'{route_prefix}.view', **self.get_action_route_kwargs(r))
+ # nb. insert to slot 1, just after normal View action
+ g.main_actions.insert(1, self.make_action(
+ 'view_raw', url=url, icon='eye'))
+
g.set_link('first_name')
g.set_link('last_name')
+ def default_view_url(self):
+ if (self.request.has_perm('people.view_profile')
+ and self.should_link_straight_to_profile()):
+ app = self.get_rattail_app()
+
+ def url(employee, i):
+ person = app.get_person(employee)
+ if person:
+ return self.request.route_url(
+ 'people.view_profile', uuid=person.uuid,
+ _anchor='employee')
+ return self.get_action_url('view', employee)
+
+ return url
+
+ return super().default_view_url()
+
+ def should_link_straight_to_profile(self):
+ return self.rattail_config.getbool('rattail',
+ 'employees.straight_to_profile',
+ default=False)
+
def query(self, session):
query = super(EmployeeView, self).query(session)
query = query.join(model.Person)
@@ -313,6 +346,15 @@ class EmployeeView(MasterView):
(model.EmployeeDepartment, 'employee_uuid'),
]
+ def configure_get_simple_settings(self):
+ return [
+
+ # General
+ {'section': 'rattail',
+ 'option': 'employees.straight_to_profile',
+ 'type': bool},
+ ]
+
@classmethod
def defaults(cls, config):
cls._defaults(config)
diff --git a/tailbone/views/members.py b/tailbone/views/members.py
index 9f96e667..2a02ea5f 100644
--- a/tailbone/views/members.py
+++ b/tailbone/views/members.py
@@ -131,6 +131,7 @@ class MemberView(MasterView):
def configure_grid(self, g):
super(MemberView, self).configure_grid(g)
+ route_prefix = self.get_route_prefix()
model = self.model
# member key
@@ -174,9 +175,41 @@ class MemberView(MasterView):
g.set_filter('membership_type', model.MembershipType.name,
label="Membership Type Name")
+ if (self.request.has_perm('people.view_profile')
+ and self.should_link_straight_to_profile()):
+
+ # add View Raw action
+ url = lambda r, i: self.request.route_url(
+ f'{route_prefix}.view', **self.get_action_route_kwargs(r))
+ # nb. insert to slot 1, just after normal View action
+ g.main_actions.insert(1, self.make_action(
+ 'view_raw', url=url, icon='eye'))
+
g.set_link('person')
g.set_link('customer')
+ def default_view_url(self):
+ if (self.request.has_perm('people.view_profile')
+ and self.should_link_straight_to_profile()):
+ app = self.get_rattail_app()
+
+ def url(member, i):
+ person = app.get_person(member)
+ if person:
+ return self.request.route_url(
+ 'people.view_profile', uuid=person.uuid,
+ _anchor='member')
+ return self.get_action_url('view', member)
+
+ return url
+
+ return super().default_view_url()
+
+ def should_link_straight_to_profile(self):
+ return self.rattail_config.getbool('rattail',
+ 'members.straight_to_profile',
+ default=False)
+
def grid_extra_class(self, member, i):
if not member.active:
return 'warning'
@@ -272,6 +305,9 @@ class MemberView(MasterView):
'option': 'members.key_field'},
{'section': 'rattail',
'option': 'members.key_label'},
+ {'section': 'rattail',
+ 'option': 'members.straight_to_profile',
+ 'type': bool},
]
diff --git a/tailbone/views/people.py b/tailbone/views/people.py
index 0c80b8a4..0f50e7fc 100644
--- a/tailbone/views/people.py
+++ b/tailbone/views/people.py
@@ -62,6 +62,7 @@ class PersonView(MasterView):
is_contact = True
manage_notes_from_profile_view = False
supports_autocomplete = True
+ configurable = True
labels = {
'default_phone': "Phone Number",
@@ -114,6 +115,7 @@ class PersonView(MasterView):
def configure_grid(self, g):
super(PersonView, self).configure_grid(g)
+ route_prefix = self.get_route_prefix()
model = self.model
g.joiners['email'] = lambda q: q.outerjoin(model.PersonEmailAddress, sa.and_(
@@ -162,10 +164,32 @@ class PersonView(MasterView):
g.set_label('email', "Email Address")
g.set_label('customer_id', "Customer ID")
+ if (self.has_perm('view_profile')
+ and self.should_link_straight_to_profile()):
+
+ # add View Raw action
+ url = lambda r, i: self.request.route_url(
+ f'{route_prefix}.view', **self.get_action_route_kwargs(r))
+ # nb. insert to slot 1, just after normal View action
+ g.main_actions.insert(1, self.make_action(
+ 'view_raw', url=url, icon='eye'))
+
g.set_link('display_name')
g.set_link('first_name')
g.set_link('last_name')
+ def default_view_url(self):
+ if (self.has_perm('view_profile')
+ and self.should_link_straight_to_profile()):
+ return lambda p, i: self.get_action_url('view_profile', p)
+
+ return super().default_view_url()
+
+ def should_link_straight_to_profile(self):
+ return self.rattail_config.getbool('rattail',
+ 'people.straight_to_profile',
+ default=False)
+
def render_merge_requested(self, person, field):
model = self.model
merge_request = self.Session.query(model.MergePeopleRequest)\
@@ -1363,6 +1387,16 @@ class PersonView(MasterView):
self.request.POST['keeping_uuid'])
return self.redirect(self.get_index_url())
+ def configure_get_simple_settings(self):
+ return [
+
+ # General
+ {'section': 'rattail',
+ 'option': 'people.straight_to_profile',
+ 'type': bool},
+
+ ]
+
@classmethod
def defaults(cls, config):
cls._people_defaults(config)