Convert 'people' view to use MasterView pattern.

This commit is contained in:
Lance Edgar 2015-12-06 18:04:23 -06:00
parent 717a614194
commit fee00b96a2
5 changed files with 62 additions and 139 deletions

View file

@ -29,7 +29,7 @@ from formencode import Schema
from .core import Form, Field, FieldSet
from .simpleform import SimpleForm, FormRenderer
from .alchemy import AlchemyForm
from .fields import *
from .fields import AssociationProxyField
from .renderers import *
from tailbone.forms import renderers

View file

@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2012 Lance Edgar
# Copyright © 2010-2015 Lance Edgar
#
# This file is part of Rattail.
#
@ -21,17 +20,15 @@
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
FormAlchemy Fields
"""
"""
``tailbone.forms.fields`` -- FormAlchemy Fields
"""
from __future__ import unicode_literals, absolute_import
from formalchemy import Field
__all__ = ['AssociationProxyField']
def AssociationProxyField(name, **kwargs):
"""
Returns a FormAlchemy ``Field`` class which is aware of association

View file

@ -1,13 +0,0 @@
## -*- coding: utf-8 -*-
<%inherit file="/crud.mako" />
<%def name="context_menu_items()">
<li>${h.link_to("Back to People", url('people'))}</li>
% if form.readonly:
<li>${h.link_to("Edit this Person", url('person.update', uuid=form.fieldset.model.uuid))}</li>
% elif form.updating:
<li>${h.link_to("View this Person", url('person.read', uuid=form.fieldset.model.uuid))}</li>
% endif
</%def>
${parent.body()}

View file

@ -1,12 +0,0 @@
## -*- coding: utf-8 -*-
<%inherit file="/grid.mako" />
<%def name="title()">People</%def>
<%def name="context_menu_items()">
## % if request.has_perm('people.create'):
## <li>${h.link_to("Create a new Person", url('person.new'))}</li>
## % endif
</%def>
${parent.body()}

View file

@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2012 Lance Edgar
# Copyright © 2010-2015 Lance Edgar
#
# This file is part of Rattail.
#
@ -21,63 +20,53 @@
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Person Views
"""
from sqlalchemy import and_
from __future__ import unicode_literals, absolute_import
from . import SearchableAlchemyGridView, CrudView, AutocompleteView
import sqlalchemy as sa
from ..db import Session
from pyramid.httpexceptions import HTTPFound, HTTPNotFound
from tailbone.views import MasterView, AutocompleteView
from rattail.db import model
from rattail.db.model import (Person, PersonEmailAddress, PersonPhoneNumber,
VendorContact)
class PeopleGrid(SearchableAlchemyGridView):
class PeopleView(MasterView):
"""
Master view for the Person class.
"""
model_class = model.Person
model_title_plural = "People"
route_prefix = 'people'
mapped_class = Person
config_prefix = 'people'
sort = 'display_name'
def configure_grid(self, g):
g.joiners['email'] = lambda q: q.outerjoin(model.PersonEmailAddress, sa.and_(
model.PersonEmailAddress.parent_uuid == model.Person.uuid,
model.PersonEmailAddress.preference == 1))
g.joiners['phone'] = lambda q: q.outerjoin(model.PersonPhoneNumber, sa.and_(
model.PersonPhoneNumber.parent_uuid == model.Person.uuid,
model.PersonPhoneNumber.preference == 1))
def join_map(self):
return {
'email':
lambda q: q.outerjoin(PersonEmailAddress, and_(
PersonEmailAddress.parent_uuid == Person.uuid,
PersonEmailAddress.preference == 1)),
'phone':
lambda q: q.outerjoin(PersonPhoneNumber, and_(
PersonPhoneNumber.parent_uuid == Person.uuid,
PersonPhoneNumber.preference == 1)),
}
g.filters['email'] = g.make_filter('email', model.PersonEmailAddress.address,
label="Email Address")
g.filters['phone'] = g.make_filter('phone', model.PersonPhoneNumber.number,
label="Phone Number")
def filter_map(self):
return self.make_filter_map(
ilike=['first_name', 'last_name', 'display_name'],
email=self.filter_ilike(PersonEmailAddress.address),
phone=self.filter_ilike(PersonPhoneNumber.number))
g.filters['first_name'].default_active = True
g.filters['first_name'].default_verb = 'contains'
def filter_config(self):
return self.make_filter_config(
include_filter_first_name=True,
filter_type_first_name='lk',
include_filter_last_name=True,
filter_type_last_name='lk',
filter_label_phone="Phone Number",
filter_label_email="Email Address")
g.filters['last_name'].default_active = True
g.filters['last_name'].default_verb = 'contains'
def sort_map(self):
return self.make_sort_map(
'first_name', 'last_name', 'display_name',
email=self.sorter(PersonEmailAddress.address),
phone=self.sorter(PersonPhoneNumber.number))
g.sorters['email'] = lambda q, d: q.order_by(getattr(model.PersonEmailAddress.address, d)())
g.sorters['phone'] = lambda q, d: q.order_by(getattr(model.PersonPhoneNumber.number, d)())
g.default_sortkey = 'display_name'
def grid(self):
g = self.make_grid()
g.configure(
include=[
g.first_name,
@ -85,38 +74,22 @@ class PeopleGrid(SearchableAlchemyGridView):
g.display_name,
g.phone.label("Phone Number"),
g.email.label("Email Address"),
],
],
readonly=True)
if self.request.has_perm('people.read'):
g.viewable = True
g.view_route_name = 'person.read'
if self.request.has_perm('people.update'):
g.editable = True
g.edit_route_name = 'person.update'
# if self.request.has_perm('products.delete'):
# g.deletable = True
# g.delete_route_name = 'product.delete'
def get_instance(self):
# TODO: I don't recall why this fallback check for a vendor contact
# exists here, but leaving it intact for now.
key = self.request.matchdict['uuid']
instance = self.Session.query(model.Person).get(key)
if instance:
return instance
instance = self.Session.query(model.VendorContact).get(key)
if instance:
return instance.person
raise HTTPNotFound
return g
class PersonCrud(CrudView):
mapped_class = Person
home_route = 'people'
def get_model(self, key):
model = super(PersonCrud, self).get_model(key)
if model:
return model
model = Session.query(VendorContact).get(key)
if model:
return model.person
return None
def fieldset(self, model):
fs = self.make_fieldset(model)
def configure_fieldset(self, fs):
fs.configure(
include=[
fs.first_name,
@ -124,13 +97,12 @@ class PersonCrud(CrudView):
fs.display_name,
fs.phone.label("Phone Number").readonly(),
fs.email.label("Email Address").readonly(),
])
return fs
])
class PeopleAutocomplete(AutocompleteView):
mapped_class = Person
mapped_class = model.Person
fieldname = 'display_name'
@ -144,34 +116,13 @@ class PeopleEmployeesAutocomplete(PeopleAutocomplete):
return q.join(model.Employee)
def add_routes(config):
config.add_route('people', '/people')
config.add_route('people.autocomplete', '/people/autocomplete')
config.add_route(u'people.autocomplete.employees', u'/people/autocomplete/employees')
config.add_route('person.read', '/people/{uuid}')
config.add_route('person.update', '/people/{uuid}/edit')
def includeme(config):
add_routes(config)
PeopleView.defaults(config)
# List
config.add_view(PeopleGrid, route_name='people',
renderer='/people/index.mako',
permission='people.list')
# CRUD
config.add_view(PersonCrud, attr='read', route_name='person.read',
renderer='/people/crud.mako',
permission='people.read')
config.add_view(PersonCrud, attr='update', route_name='person.update',
renderer='/people/crud.mako',
permission='people.update')
# Autocomplete
# autocomplete
config.add_route('people.autocomplete', '/people/autocomplete')
config.add_view(PeopleAutocomplete, route_name='people.autocomplete',
renderer='json',
permission='people.list')
config.add_view(PeopleEmployeesAutocomplete, route_name=u'people.autocomplete.employees',
renderer=u'json',
permission=u'people.list')
renderer='json', permission='people.list')
config.add_route('people.autocomplete.employees', '/people/autocomplete/employees')
config.add_view(PeopleEmployeesAutocomplete, route_name='people.autocomplete.employees',
renderer='json', permission='people.list')