Refactor products view(s) per new master pattern.

Finally!
This commit is contained in:
Lance Edgar 2016-02-12 20:44:41 -06:00
parent 254c68034a
commit 583548cad5
12 changed files with 421 additions and 394 deletions

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2015 Lance Edgar
# Copyright © 2010-2016 Lance Edgar
#
# This file is part of Rattail.
#
@ -24,18 +24,20 @@
FormAlchemy Grid Classes
"""
from __future__ import unicode_literals
from __future__ import unicode_literals, absolute_import
import logging
import sqlalchemy as sa
from sqlalchemy import orm
from edbob.util import prettify
from rattail.db.types import GPCType
import formalchemy
from webhelpers import paginate
from edbob.util import prettify
from tailbone.db import Session
from tailbone.newgrids import Grid, GridColumn, filters
@ -64,7 +66,8 @@ class AlchemyGrid(Grid):
def __init__(self, *args, **kwargs):
super(AlchemyGrid, self).__init__(*args, **kwargs)
fa_grid = formalchemy.Grid(self.model_class, instances=self.data,
session=Session(), request=self.request)
session=kwargs.get('session', Session()),
request=self.request)
fa_grid.prettify = prettify
self._fa_grid = fa_grid
@ -99,6 +102,8 @@ class AlchemyGrid(Grid):
factory = filters.AlchemyBooleanFilter
elif isinstance(column.type, (sa.Date, sa.DateTime)):
factory = filters.AlchemyDateFilter
elif isinstance(column.type, GPCType):
factory = filters.AlchemyGPCFilter
return factory(key, column=column, **kwargs)
def iter_filters(self):
@ -107,6 +112,24 @@ class AlchemyGrid(Grid):
"""
return self.filters.itervalues()
def filter_data(self, query):
"""
Filter and return the given data set, according to current settings.
"""
# This overrides the core version only slightly, in that it will only
# invoke a join if any particular filter(s) actually modifies the
# query. The main motivation for this is on the products page, where
# the tricky "vendor (any)" filter has a weird join and causes
# unpredictable results. Now we can skip the join for that unless the
# user actually enters some criteria for it.
for filtr in self.iter_active_filters():
original = query
query = filtr.filter(query)
if query is not original and filtr.key in self.joiners and filtr.key not in self.joined:
query = self.joiners[filtr.key](query)
self.joined.add(filtr.key)
return query
def make_sorters(self, sorters):
"""
Returns a mapping of sort options for the grid. Keyword args override

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2015 Lance Edgar
# Copyright © 2010-2016 Lance Edgar
#
# This file is part of Rattail.
#
@ -24,7 +24,7 @@
Core Grid Classes
"""
from __future__ import unicode_literals
from __future__ import unicode_literals, absolute_import
from edbob.util import prettify
@ -246,11 +246,17 @@ class Grid(object):
"""
Check to see if the current user has default settings on file for this grid.
"""
if not self.request.user:
user = self.request.user
if not user:
return False
session = getattr(self, 'session', Session())
if user not in session:
user = session.merge(user)
# User defaults should have all or nothing, so just check one key.
key = 'tailbone.{0}.grid.{1}.sortkey'.format(self.request.user.uuid, self.key)
return get_setting(Session(), key) is not None
key = 'tailbone.{}.grid.{}.sortkey'.format(user.uuid, self.key)
return get_setting(session, key) is not None
def apply_user_defaults(self, settings):
"""
@ -600,10 +606,11 @@ class Grid(object):
"""
url = action.get_url(row)
if url:
kwargs = {'class_': action.key}
if action.icon:
icon = HTML.tag('span', class_='ui-icon ui-icon-{0}'.format(action.icon))
return tags.link_to(icon + action.label, url)
return tags.link_to(action.label, url)
icon = HTML.tag('span', class_='ui-icon ui-icon-{}'.format(action.icon))
return tags.link_to(icon + action.label, url, **kwargs)
return tags.link_to(action.label, url, **kwargs)
def iter_rows(self):
return self.make_visible_data()

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2015 Lance Edgar
# Copyright © 2010-2016 Lance Edgar
#
# This file is part of Rattail.
#
@ -24,12 +24,13 @@
Grid Filters
"""
from __future__ import unicode_literals
from __future__ import unicode_literals, absolute_import
import sqlalchemy as sa
from edbob.util import prettify
from rattail.gpc import GPC
from rattail.util import OrderedDict
from rattail.core import UNSPECIFIED
@ -367,6 +368,44 @@ class AlchemyDateFilter(AlchemyGridFilter):
return self.filter_is_null(query, value)
class AlchemyGPCFilter(AlchemyGridFilter):
"""
GPC filter for SQLAlchemy.
"""
default_verbs = ['equal', 'not_equal']
def filter_equal(self, query, value):
"""
Filter data with an equal ('=') query.
"""
if value is None or value == '':
return query
try:
return query.filter(self.column.in_((
GPC(value),
GPC(value, calc_check_digit='upc'))))
except ValueError:
return query
def filter_not_equal(self, query, value):
"""
Filter data with a not eqaul ('!=') query.
"""
if value is None or value == '':
return query
# When saying something is 'not equal' to something else, we must also
# include things which are nothing at all, in our result set.
try:
return query.filter(sa.or_(
~self.column.in_((
GPC(value),
GPC(value, calc_check_digit='upc'))),
self.column == None))
except ValueError:
return query
class GridFilterSet(OrderedDict):
"""
Collection class for :class:`GridFilter` instances.