Added extra key lookups for customer and product routes.

Now the CRUD routes for these objects can leverage UUIDs of various related
objects in addition to the primary object.  More should be done with this, but
at least we have a start.
This commit is contained in:
Lance Edgar 2013-05-17 23:32:57 -07:00
parent 5f3b91826a
commit 931700131f
3 changed files with 72 additions and 35 deletions

View file

@ -171,9 +171,13 @@ class CrudView(View):
def create(self): def create(self):
return self.crud(self.mapped_class) return self.crud(self.mapped_class)
def get_model(self, key):
model = Session.query(self.mapped_class).get(key)
return model
def read(self): def read(self):
uuid = self.request.matchdict['uuid'] key = self.request.matchdict['uuid']
model = Session.query(self.mapped_class).get(uuid) if uuid else None model = self.get_model(key)
if not model: if not model:
return HTTPFound(location=self.home_url) return HTTPFound(location=self.home_url)
return self.crud(model, readonly=True) return self.crud(model, readonly=True)

View file

@ -29,15 +29,20 @@
from sqlalchemy import and_ from sqlalchemy import and_
import edbob import edbob
from edbob.pyramid.views import SearchableAlchemyGridView, CrudView from edbob.pyramid.views import SearchableAlchemyGridView
from edbob.pyramid.forms import EnumFieldRenderer from edbob.pyramid.forms import EnumFieldRenderer
import rattail import rattail
from rattail.pyramid import Session
from rattail.db.model import (
Customer, CustomerPerson, CustomerGroupAssignment,
CustomerEmailAddress, CustomerPhoneNumber)
from rattail.pyramid.views import CrudView
class CustomersGrid(SearchableAlchemyGridView): class CustomersGrid(SearchableAlchemyGridView):
mapped_class = rattail.Customer mapped_class = Customer
config_prefix = 'customers' config_prefix = 'customers'
sort = 'name' sort = 'name'
clickable = True clickable = True
@ -45,21 +50,21 @@ class CustomersGrid(SearchableAlchemyGridView):
def join_map(self): def join_map(self):
return { return {
'email': 'email':
lambda q: q.outerjoin(rattail.CustomerEmailAddress, and_( lambda q: q.outerjoin(CustomerEmailAddress, and_(
rattail.CustomerEmailAddress.parent_uuid == rattail.Customer.uuid, CustomerEmailAddress.parent_uuid == Customer.uuid,
rattail.CustomerEmailAddress.preference == 1)), CustomerEmailAddress.preference == 1)),
'phone': 'phone':
lambda q: q.outerjoin(rattail.CustomerPhoneNumber, and_( lambda q: q.outerjoin(CustomerPhoneNumber, and_(
rattail.CustomerPhoneNumber.parent_uuid == rattail.Customer.uuid, CustomerPhoneNumber.parent_uuid == Customer.uuid,
rattail.CustomerPhoneNumber.preference == 1)), CustomerPhoneNumber.preference == 1)),
} }
def filter_map(self): def filter_map(self):
return self.make_filter_map( return self.make_filter_map(
exact=['id'], exact=['id'],
ilike=['name'], ilike=['name'],
email=self.filter_ilike(rattail.CustomerEmailAddress.address), email=self.filter_ilike(CustomerEmailAddress.address),
phone=self.filter_ilike(rattail.CustomerPhoneNumber.number)) phone=self.filter_ilike(CustomerPhoneNumber.number))
def filter_config(self): def filter_config(self):
return self.make_filter_config( return self.make_filter_config(
@ -72,8 +77,8 @@ class CustomersGrid(SearchableAlchemyGridView):
def sort_map(self): def sort_map(self):
return self.make_sort_map( return self.make_sort_map(
'id', 'name', 'id', 'name',
email=self.sorter(rattail.CustomerEmailAddress.address), email=self.sorter(CustomerEmailAddress.address),
phone=self.sorter(rattail.CustomerPhoneNumber.number)) phone=self.sorter(CustomerPhoneNumber.number))
def grid(self): def grid(self):
g = self.make_grid() g = self.make_grid()
@ -91,9 +96,24 @@ class CustomersGrid(SearchableAlchemyGridView):
class CustomerCrud(CrudView): class CustomerCrud(CrudView):
mapped_class = rattail.Customer mapped_class = Customer
home_route = 'customers' home_route = 'customers'
def get_model(self, key):
model = super(CustomerCrud, self).get_model(key)
if model:
return model
model = Session.query(Customer).filter_by(id=key).first()
if model:
return model
model = Session.query(CustomerPerson).get(key)
if model:
return model.customer
model = Session.query(CustomerGroupAssignment).get(key)
if model:
return model.customer
return None
def fieldset(self, model): def fieldset(self, model):
fs = self.make_fieldset(model) fs = self.make_fieldset(model)
fs.email_preference.set(renderer=EnumFieldRenderer(edbob.EMAIL_PREFERENCE)) fs.email_preference.set(renderer=EnumFieldRenderer(edbob.EMAIL_PREFERENCE))
@ -108,14 +128,17 @@ class CustomerCrud(CrudView):
return fs return fs
def includeme(config): def add_routes(config):
config.add_route('customers', '/customers') config.add_route('customers', '/customers')
config.add_route('customer.read', '/customers/{uuid}')
def includeme(config):
add_routes(config)
config.add_view(CustomersGrid, route_name='customers', config.add_view(CustomersGrid, route_name='customers',
renderer='/customers/index.mako', renderer='/customers/index.mako',
permission='customers.list') permission='customers.list')
config.add_route('customer.read', '/customers/{uuid}')
config.add_view(CustomerCrud, attr='read', route_name='customer.read', config.add_view(CustomerCrud, attr='read', route_name='customer.read',
renderer='/customers/read.mako', renderer='/customers/read.mako',
permission='customers.read') permission='customers.read')

View file

@ -35,9 +35,8 @@ from pyramid.httpexceptions import HTTPFound
from pyramid.renderers import render_to_response from pyramid.renderers import render_to_response
import edbob import edbob
from edbob.pyramid import Session
from edbob.pyramid.progress import SessionProgress from edbob.pyramid.progress import SessionProgress
from edbob.pyramid.views import SearchableAlchemyGridView, CrudView from edbob.pyramid.views import SearchableAlchemyGridView
import rattail import rattail
import rattail.labels import rattail.labels
@ -45,7 +44,11 @@ from rattail import sil
from rattail import batches from rattail import batches
from rattail.threads import Thread from rattail.threads import Thread
from rattail.exceptions import LabelPrintingError from rattail.exceptions import LabelPrintingError
from rattail.db.model import ProductPrice
from rattail.pyramid import Session
from rattail.pyramid.forms import GPCFieldRenderer, PriceFieldRenderer from rattail.pyramid.forms import GPCFieldRenderer, PriceFieldRenderer
from rattail.pyramid.views import CrudView
class ProductsGrid(SearchableAlchemyGridView): class ProductsGrid(SearchableAlchemyGridView):
@ -197,6 +200,15 @@ class ProductCrud(CrudView):
mapped_class = rattail.Product mapped_class = rattail.Product
home_route = 'products' home_route = 'products'
def get_model(self, key):
model = super(ProductCrud, self).get_model(key)
if model:
return model
model = Session.query(ProductPrice).get(key)
if model:
return model.product
return None
def fieldset(self, model): def fieldset(self, model):
fs = self.make_fieldset(model) fs = self.make_fieldset(model)
fs.upc.set(renderer=GPCFieldRenderer) fs.upc.set(renderer=GPCFieldRenderer)
@ -312,37 +324,35 @@ class CreateProductsBatch(ProductsGrid):
return {'providers': providers} return {'providers': providers}
def includeme(config): def add_routes(config):
config.add_route('products', '/products') config.add_route('products', '/products')
config.add_route('products.print_labels', '/products/labels')
config.add_route('products.create_batch', '/products/batch')
config.add_route('product.create', '/products/new')
config.add_route('product.read', '/products/{uuid}')
config.add_route('product.update', '/products/{uuid}/edit')
config.add_route('product.delete', '/products/{uuid}/delete')
def includeme(config):
add_routes(config)
config.add_view(ProductsGrid, route_name='products', config.add_view(ProductsGrid, route_name='products',
renderer='/products/index.mako', renderer='/products/index.mako',
permission='products.list') permission='products.list')
config.add_route('products.print_labels', '/products/labels')
config.add_view(print_labels, route_name='products.print_labels', config.add_view(print_labels, route_name='products.print_labels',
renderer='json', permission='products.print_labels') renderer='json', permission='products.print_labels')
config.add_route('products.create_batch', '/products/batch')
config.add_view(CreateProductsBatch, route_name='products.create_batch', config.add_view(CreateProductsBatch, route_name='products.create_batch',
renderer='/products/batch.mako', renderer='/products/batch.mako',
permission='batches.create') permission='batches.create')
config.add_route('product.create', '/products/new')
config.add_view(ProductCrud, attr='create', route_name='product.create', config.add_view(ProductCrud, attr='create', route_name='product.create',
renderer='/products/crud.mako', renderer='/products/crud.mako',
permission='products.create') permission='products.create')
config.add_route('product.read', '/products/{uuid}')
config.add_view(ProductCrud, attr='read', route_name='product.read', config.add_view(ProductCrud, attr='read', route_name='product.read',
renderer='/products/read.mako', renderer='/products/read.mako',
permission='products.read') permission='products.read')
config.add_route('product.update', '/products/{uuid}/edit')
config.add_view(ProductCrud, attr='update', route_name='product.update', config.add_view(ProductCrud, attr='update', route_name='product.update',
renderer='/products/crud.mako', renderer='/products/crud.mako',
permission='products.update') permission='products.update')
config.add_route('product.delete', '/products/{uuid}/delete')
config.add_view(ProductCrud, attr='delete', route_name='product.delete', config.add_view(ProductCrud, attr='delete', route_name='product.delete',
permission='products.delete') permission='products.delete')