diff --git a/tailbone_corepos/menus.py b/tailbone_corepos/menus.py index ae5fa4d..e213dff 100644 --- a/tailbone_corepos/menus.py +++ b/tailbone_corepos/menus.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2021 Lance Edgar +# Copyright © 2010-2022 Lance Edgar # # This file is part of Rattail. # @@ -68,6 +68,11 @@ def make_corepos_menu(request): 'url': url('corepos.users'), 'perm': 'corepos.users.list', }, + { + 'title': "User Groups", + 'url': url('corepos.user_groups'), + 'perm': 'corepos.user_groups.list', + }, ], }, { diff --git a/tailbone_corepos/templates/core-pos/user-groups/view.mako b/tailbone_corepos/templates/core-pos/user-groups/view.mako new file mode 100644 index 0000000..de2b0f8 --- /dev/null +++ b/tailbone_corepos/templates/core-pos/user-groups/view.mako @@ -0,0 +1,13 @@ +## -*- coding: utf-8; -*- +<%inherit file="/master/view.mako" /> + +<%def name="modify_this_page_vars()"> + ${parent.modify_this_page_vars()} + + + +${parent.body()} diff --git a/tailbone_corepos/views/corepos/__init__.py b/tailbone_corepos/views/corepos/__init__.py index 4856bfa..6939c6e 100644 --- a/tailbone_corepos/views/corepos/__init__.py +++ b/tailbone_corepos/views/corepos/__init__.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2021 Lance Edgar +# Copyright © 2010-2022 Lance Edgar # # This file is part of Rattail. # @@ -31,6 +31,7 @@ def includeme(config): config.include('tailbone_corepos.views.corepos.parameters') config.include('tailbone_corepos.views.corepos.tablesyncrules') config.include('tailbone_corepos.views.corepos.users') + config.include('tailbone_corepos.views.corepos.groups') config.include('tailbone_corepos.views.corepos.stores') config.include('tailbone_corepos.views.corepos.departments') config.include('tailbone_corepos.views.corepos.subdepartments') diff --git a/tailbone_corepos/views/corepos/groups.py b/tailbone_corepos/views/corepos/groups.py new file mode 100644 index 0000000..2578190 --- /dev/null +++ b/tailbone_corepos/views/corepos/groups.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2022 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# Rattail. If not, see . +# +################################################################################ +""" +CORE-POS group views +""" + +from corepos.db.office_op import model as corepos + +from rattail.util import OrderedDict + +from webhelpers2.html import HTML + +from .master import CoreOfficeMasterView + + +class UserGroupView(CoreOfficeMasterView): + """ + Master view for CORE Office groups + """ + model_class = corepos.UserGroup + model_key = 'group_id' + model_title = "CORE-POS User Group" + url_prefix = '/core-pos/user-groups' + route_prefix = 'corepos.user_groups' + filterable = False + pageable = False + + # TODO: maybe add support for these? + creatable = False + editable = False + deletable = False + + labels = { + 'group_id': "Group ID", + } + + grid_columns = [ + 'group_id', + 'name', + ] + + form_fields = [ + 'group_id', + 'name', + 'users', + ] + + def get_data(self, session=None): + groups = OrderedDict() + + if session is None: + session = self.Session() + query = session.query(corepos.UserGroup)\ + .order_by(corepos.UserGroup.group_id, + corepos.UserGroup.name) + + for usergroup in query: + if usergroup.group_id not in groups: + groups[usergroup.group_id] = self.normalize(usergroup) + + return list(groups.values()) + + def normalize(self, group): + return { + 'group_id': group.group_id, + 'name': group.name, + } + + def configure_grid(self, g): + super(UserGroupView, self).configure_grid(g) + + g.sorters['group_id'] = g.make_simple_sorter('group_id') + g.sorters['name'] = g.make_simple_sorter('name', foldcase=True) + + g.set_sort_defaults('group_id') + + g.set_link('group_id') + g.set_link('name') + + def get_instance(self): + gid = self.request.matchdict['group_id'] + group = self.Session.query(corepos.UserGroup)\ + .filter(corepos.UserGroup.group_id == gid)\ + .first() + return self.normalize(group) + + def get_instance_title(self, group): + return group['name'] + + def configure_form(self, f): + super(UserGroupView, self).configure_form(f) + + if self.creating or self.editing: + f.remove('users') + else: + f.set_renderer('users', self.render_users) + + def render_users(self, group, field): + groups = self.Session.query(corepos.UserGroup)\ + .filter(corepos.UserGroup.group_id == group['group_id'])\ + .order_by(corepos.UserGroup.username)\ + .all() + + route_prefix = self.get_route_prefix() + permission_prefix = self.get_permission_prefix() + factory = self.get_grid_factory() + g = factory( + key='{}.users'.format(route_prefix), + data=[], + columns=[ + 'username', + ], + ) + + return HTML.literal( + g.render_buefy_table_element(data_prop='usersData')) + + def template_kwargs_view(self, **kwargs): + group_info = kwargs['instance'] + + users_data = [] + usergroups = self.Session.query(corepos.UserGroup)\ + .filter(corepos.UserGroup.group_id == group_info['group_id'])\ + .order_by(corepos.UserGroup.username) + for usergroup in usergroups: + users_data.append({'username': usergroup.username}) + kwargs['users_data'] = users_data + + return kwargs + + +def includeme(config): + UserGroupView.defaults(config)