You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
419 lines
14 KiB
419 lines
14 KiB
import deform |
|
|
|
from pyramid.httpexceptions import HTTPFound |
|
from pyramid.renderers import render |
|
from pyramid.security import remember, forget |
|
from pyramid.view import view_config |
|
|
|
from ordr2.events import AccountActivation, PasswordReset |
|
from ordr2.models import Category, Consumable, User, Role |
|
from ordr2.schemas.account import UserSchema |
|
from ordr2.schemas.orders import ConsumableSchema |
|
|
|
from . import update_column_display |
|
|
|
# admin section |
|
|
|
@view_config( |
|
context='ordr2:resources.Admin', |
|
permission='view', |
|
renderer='ordr2:templates/admin/admin_section.jinja2' |
|
) |
|
def admin_section(context, request): |
|
''' display the admin section ''' |
|
new_users = request.dbsession.query(User).filter_by(role=Role.NEW).count() |
|
if new_users: |
|
plural = 's' if new_users > 1 else '' |
|
request.flash( |
|
'info', |
|
'{} new user{} have registered.'.format(new_users, plural), |
|
'''Please <a href="{}">take a look at them</a> and confirm or |
|
reject the registration by setting the role accordingly. This |
|
message will disappear when all new registrations have been |
|
processed.'''.format( |
|
request.resource_url(context, 'users', query={'role': 'new'}) |
|
) |
|
) |
|
return {} |
|
|
|
|
|
# user list and user editing |
|
|
|
@view_config( |
|
context='ordr2:resources.UserList', |
|
permission='view', |
|
renderer='ordr2:templates/admin/user_list.jinja2' |
|
) |
|
def user_list(context, request): |
|
''' display the user list ''' |
|
users = context.items() |
|
roles = [(role.value.lower(), role.value.capitalize()) for role in Role] |
|
return {'users':users, 'roles':roles} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.UserList', |
|
name = 'changeview', |
|
permission='view', |
|
request_method='POST' |
|
) |
|
def change_column_view(context, request): |
|
''' changes the columns to display ''' |
|
update_column_display(request, 'users') |
|
return HTTPFound(context.url()) |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.UserList', |
|
name='actions', |
|
request_param='action=delete', |
|
permission='delete', |
|
request_method='POST', |
|
renderer='ordr2:templates/admin/users_delete.jinja2' |
|
) |
|
def delete_multiple_accounts_form(context, request): |
|
account_ids = [v for k, v in request.POST.items() if k == 'marked'] |
|
accounts = request.dbsession.\ |
|
query(User).\ |
|
filter(User.id.in_(account_ids)).\ |
|
order_by(User.user_name).\ |
|
all() |
|
if len(accounts) == 0: |
|
return HTTPFound(context.url()) |
|
return {'accounts': accounts} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.UserList', |
|
name='actions', |
|
request_param='action=role', |
|
permission='edit', |
|
request_method='POST', |
|
renderer='ordr2:templates/admin/users_change_roles.jinja2' |
|
) |
|
def edit_multiple_roles_form(context, request): |
|
account_ids = [v for k, v in request.POST.items() if k == 'marked'] |
|
accounts = request.dbsession.\ |
|
query(User).\ |
|
filter(User.id.in_(account_ids)).\ |
|
order_by(User.user_name).\ |
|
all() |
|
if len(accounts) == 0: |
|
return HTTPFound(context.url()) |
|
roles = [(role.name, role.value.capitalize()) for role in Role] |
|
return {'accounts': accounts, 'roles': roles} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.UserList', |
|
name='roles', |
|
permission='edit', |
|
request_method='POST' |
|
) |
|
def edit_multiple_roles_form_processing(context, request): |
|
|
|
if 'change' in request.POST: |
|
count = 0 |
|
for key, value in request.POST.items(): |
|
if not key.startswith('account-'): |
|
continue |
|
_, account_id = key.split('-', 1) |
|
account = request.dbsession.query(User).get(account_id) |
|
if account: |
|
was_active = account.is_active |
|
try: |
|
account.role = Role[value] |
|
except ValueError: |
|
pass |
|
if not was_active and account.is_active: |
|
# user account was activated, notify user |
|
event = AccountActivation(request, account) |
|
request.registry.notify(event) |
|
count += 1 |
|
|
|
if count == 1: |
|
request.flash('success', 'One user account was updated') |
|
elif count > 1: |
|
msg = '{} user accounts were updated.'.format(count) |
|
request.flash('success', msg) |
|
|
|
return HTTPFound(context.url()) |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.UserAccount', |
|
permission='edit', |
|
request_method='GET', |
|
renderer='ordr2:templates/admin/user_edit.jinja2' |
|
) |
|
def user_account_form(context, request): |
|
''' display the user edit form ''' |
|
form = UserSchema.as_form(request) |
|
form_data = { |
|
'user_name': context.model.user_name, |
|
'first_name': context.model.first_name, |
|
'last_name': context.model.last_name, |
|
'email': context.model.email, |
|
'role': context.model.role.name |
|
} |
|
form.set_appstruct(form_data) |
|
return {'form': form} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.UserAccount', |
|
permission='edit', |
|
request_method='POST', |
|
renderer='ordr2:templates/admin/user_edit.jinja2' |
|
) |
|
def user_account_form_processing(context, request): |
|
''' process the user edit form ''' |
|
|
|
form = UserSchema.as_form(request) |
|
data = request.POST.items() |
|
if 'delete' in request.POST: |
|
return HTTPFound(request.resource_url(context, 'delete')) |
|
|
|
elif 'save' in request.POST: |
|
try: |
|
appstruct = form.validate(data) |
|
except deform.ValidationFailure as e: |
|
return {'form': form} |
|
|
|
# form validation sucessful, change settings |
|
was_active = context.model.is_active |
|
context.model.first_name = appstruct['first_name'] |
|
context.model.last_name = appstruct['last_name'] |
|
context.model.email = appstruct['email'] |
|
context.model.role = Role[appstruct['role']] |
|
|
|
if not was_active and context.model.is_active: |
|
# user account was activated, notify user |
|
event = AccountActivation(request, context.model) |
|
request.registry.notify(event) |
|
text = 'An activation email was sent to <em>{}</em>'.format( |
|
appstruct['email'] |
|
) |
|
else: |
|
text = '' |
|
|
|
msg = 'User account <em>{}</em> updated.'.format( |
|
context.model.user_name |
|
) |
|
request.flash('success', msg, text) |
|
|
|
elif 'reset' in request.POST: |
|
token = context.model.generate_password_token() |
|
event = PasswordReset(request, context.model, token) |
|
request.registry.notify(event) |
|
msg = 'Password reset mail sent to {}.'.format(context.model.email) |
|
request.flash('success', msg) |
|
|
|
elif 'delete' in request.POST: |
|
return HTTPFound(context, 'delete') |
|
|
|
return HTTPFound(context.__parent__.url()) |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.UserAccount', |
|
name='delete', |
|
permission='delete', |
|
request_method='GET', |
|
renderer='ordr2:templates/admin/users_delete.jinja2' |
|
) |
|
def user_delete_form(context, request): |
|
return {'accounts': [context.model]} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.UserList', |
|
name='delete', |
|
permission='delete', |
|
request_method='POST' |
|
) |
|
@view_config( |
|
context='ordr2:resources.UserAccount', |
|
name='delete', |
|
permission='delete', |
|
request_method='POST' |
|
) |
|
def user_delete_form_processing(context, request): |
|
if 'delete' in request.POST: |
|
account_ids = [v for k, v in request.POST.items() if k == 'account'] |
|
accounts = request.dbsession.\ |
|
query(User).\ |
|
filter(User.id.in_(account_ids)).\ |
|
all() |
|
for account in accounts: |
|
request.dbsession.delete(account) |
|
|
|
if len(accounts) == 1: |
|
request.flash('success', 'One user account was deleted') |
|
elif len(accounts) > 1: |
|
msg = '{} user accounts were deleted.'.format(len(accounts)) |
|
request.flash('success', msg) |
|
|
|
return HTTPFound(request.resource_url(request.root, 'admin', 'users')) |
|
|
|
|
|
# consumables |
|
|
|
@view_config( |
|
context='ordr2:resources.ConsumableList', |
|
permission='view', |
|
renderer='ordr2:templates/admin/consumable_list.jinja2' |
|
) |
|
def consumable_list(context, request): |
|
''' display the consumable list ''' |
|
consumables = context.items() |
|
categories = [(c.value.lower(), c.value.capitalize()) for c in Category] |
|
return {'consumables': consumables, 'categories': categories} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.ConsumableList', |
|
name='new', |
|
permission='create', |
|
request_method='GET', |
|
renderer='ordr2:templates/admin/consumable_new.jinja2' |
|
) |
|
def consumable_new_form(context, request): |
|
''' display the new consumable form ''' |
|
form = ConsumableSchema.as_form(request, is_new_consumable=True) |
|
return {'form': form} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.ConsumableList', |
|
name='new', |
|
permission='create', |
|
request_method='POST', |
|
renderer='ordr2:templates/admin/consumable_new.jinja2' |
|
) |
|
def consumable_new_form_processing(context, request): |
|
''' process the new consumable form ''' |
|
|
|
form = ConsumableSchema.as_form(request, is_new_consumable=True) |
|
data = request.POST.items() |
|
if 'save' in request.POST: |
|
try: |
|
appstruct = form.validate(data) |
|
except deform.ValidationFailure as e: |
|
return {'form': form} |
|
|
|
# form validation sucessful, change consumable |
|
consumable = Consumable( |
|
cas_description=appstruct['cas_description'], |
|
category=Category[appstruct['category']], |
|
vendor=appstruct['vendor'], |
|
catalog_nr=appstruct['catalog_nr'], |
|
package_size=appstruct['package_size'], |
|
unit_price=appstruct['unit_price']['amount'], |
|
currency=appstruct['unit_price']['currency'], |
|
comment=appstruct['comment'] |
|
) |
|
request.dbsession.add(consumable) |
|
|
|
msg = 'Consumable <em>{!s}</em> added.'.format(consumable) |
|
request.flash('success', msg) |
|
|
|
return HTTPFound(context.url()) |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.ConsumableResource', |
|
permission='edit', |
|
request_method='GET', |
|
renderer='ordr2:templates/admin/consumable_edit.jinja2' |
|
) |
|
def consumable_edit_form(context, request): |
|
''' display the consumable edit form ''' |
|
form = ConsumableSchema.as_form(request, is_new_consumable=False) |
|
form_data = { |
|
'cas_description': context.model.cas_description, |
|
'category': context.model.category.name, |
|
'vendor': context.model.vendor, |
|
'catalog_nr': context.model.catalog_nr, |
|
'package_size': context.model.package_size, |
|
'unit_price': { |
|
'amount': context.model.unit_price, |
|
'currency': context.model.currency |
|
}, |
|
'comment': context.model.comment |
|
} |
|
form.set_appstruct(form_data) |
|
return {'form': form} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.ConsumableResource', |
|
permission='edit', |
|
request_method='POST', |
|
renderer='ordr2:templates/admin/consumable_edit.jinja2' |
|
) |
|
def consumable_edit_form_processing(context, request): |
|
''' process the consumable edit form ''' |
|
|
|
form = ConsumableSchema.as_form(request, is_new_consumable=False) |
|
data = request.POST.items() |
|
if 'save' in request.POST: |
|
try: |
|
appstruct = form.validate(data) |
|
except deform.ValidationFailure as e: |
|
return {'form': form} |
|
|
|
# form validation sucessful, change consumable |
|
context.model.cas_description = appstruct['cas_description'] |
|
context.model.category = Category[appstruct['category']] |
|
context.model.vendor = appstruct['vendor'] |
|
context.model.catalog_nr = appstruct['catalog_nr'] |
|
context.model.package_size = appstruct['package_size'] |
|
context.model.unit_price = appstruct['unit_price']['amount'] |
|
context.model.currency = appstruct['unit_price']['currency'] |
|
context.model.comment = appstruct['comment'] |
|
|
|
msg = 'Consumable <em>{!s}</em> updated.'.format(context.model) |
|
request.flash('success', msg) |
|
|
|
elif 'delete' in request.POST and context.model: |
|
return HTTPFound(request.resource_url(context, 'delete')) |
|
|
|
return HTTPFound(context.__parent__.url()) |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.ConsumableResource', |
|
name='delete', |
|
permission='delete', |
|
request_method='GET', |
|
renderer='ordr2:templates/admin/consumable_delete.jinja2' |
|
) |
|
def consumable_delete_form(context, request): |
|
return {'consumables': [context.model]} |
|
|
|
|
|
@view_config( |
|
context='ordr2:resources.ConsumableResource', |
|
name='delete', |
|
permission='delete', |
|
request_method='POST' |
|
) |
|
def consumable_delete_form_processing(context, request): |
|
if 'delete' in request.POST: |
|
c_ids = [v for k, v in request.POST.items() if k == 'consumable'] |
|
consumables = request.dbsession.\ |
|
query(Consumable).\ |
|
filter(Consumable.id.in_(c_ids)).\ |
|
all() |
|
for consumable in consumables: |
|
request.dbsession.delete(consumable) |
|
|
|
if len(consumables) == 1: |
|
request.flash('success', 'One consumable was deleted') |
|
elif len(consumables) > 1: |
|
msg = '{} consumables were deleted.'.format(len(accounts)) |
|
request.flash('success', msg) |
|
|
|
return HTTPFound(context.__parent__.url()) |
|
|
|
|