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 + + + +
+ + + +${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 + + + 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 + + + +
+ + + +${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)