Stop using sa-filters for basic grid sorting
this just breaks if we need to use "aliased" models e.g. when sorting and/or filtering by Product "regular price" column and similar. so now sorting more like we always used to, except for multi-column. nb. this still assumes callers use `Grid.make_sorter()` when declaring the sorters. if caller must specify more custom/explicit sort logic then it likely will not work and we'll have to add a workaround to allow avoiding the common logic..but that's another day
This commit is contained in:
parent
421266e70c
commit
6d79766b24
|
@ -30,7 +30,6 @@ import logging
|
|||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
from sa_filters import apply_sort
|
||||
|
||||
from rattail.db.types import GPCType
|
||||
from rattail.util import prettify, pretty_boolean, pretty_quantity
|
||||
|
@ -1235,29 +1234,29 @@ class Grid(object):
|
|||
# TODO: is there a better way to check for SA sorting?
|
||||
if self.model_class:
|
||||
|
||||
# convert sort settings into a 'sortspec' for use with sa-filters
|
||||
full_spec = []
|
||||
# collect actual column sorters for order_by clause
|
||||
sorters = []
|
||||
for sorter in self.active_sorters:
|
||||
sortkey = sorter['field']
|
||||
sortdir = sorter['order']
|
||||
sortfunc = self.sorters.get(sortkey)
|
||||
if sortfunc:
|
||||
spec = {
|
||||
'sortkey': sortkey,
|
||||
'model': sortfunc._class.__name__,
|
||||
'field': sortfunc._column.key,
|
||||
'direction': sortdir or 'asc',
|
||||
}
|
||||
full_spec.append(spec)
|
||||
if not sortfunc:
|
||||
log.warning("unknown sorter: %s", sorter)
|
||||
continue
|
||||
|
||||
# apply joins needed for this sort spec
|
||||
for spec in full_spec:
|
||||
sortkey = spec['sortkey']
|
||||
# join appropriate model if needed
|
||||
if sortkey in self.joiners and sortkey not in self.joined:
|
||||
data = self.joiners[sortkey](data)
|
||||
self.joined.add(sortkey)
|
||||
|
||||
return apply_sort(data, full_spec)
|
||||
# add column/dir to collection
|
||||
sortdir = sorter['order']
|
||||
sorters.append(getattr(sortfunc._column, sortdir)())
|
||||
|
||||
# apply sorting to query
|
||||
if sorters:
|
||||
data = data.order_by(*sorters)
|
||||
|
||||
return data
|
||||
|
||||
else:
|
||||
# not a SQLAlchemy grid, custom sorter
|
||||
|
|
|
@ -160,12 +160,6 @@ class ProductView(MasterView):
|
|||
'inventory_on_order',
|
||||
]
|
||||
|
||||
# same, but for prices
|
||||
RegularPrice = orm.aliased(model.ProductPrice)
|
||||
CurrentPrice = orm.aliased(model.ProductPrice)
|
||||
SalePrice = orm.aliased(model.ProductPrice)
|
||||
TPRPrice = orm.aliased(model.ProductPrice)
|
||||
|
||||
def __init__(self, request):
|
||||
super().__init__(request)
|
||||
self.expose_label_printing = self.rattail_config.getbool(
|
||||
|
@ -332,28 +326,34 @@ class ProductView(MasterView):
|
|||
g.set_joiner('family', lambda q: q.outerjoin(model.Family))
|
||||
g.set_filter('family', model.Family.name)
|
||||
|
||||
# regular_price
|
||||
g.set_label('regular_price', "Reg. Price")
|
||||
RegularPrice = orm.aliased(model.ProductPrice)
|
||||
g.set_joiner('regular_price', lambda q: q.outerjoin(
|
||||
self.RegularPrice, self.RegularPrice.uuid == model.Product.regular_price_uuid))
|
||||
g.set_sorter('regular_price', self.RegularPrice.price)
|
||||
g.set_filter('regular_price', self.RegularPrice.price, label="Regular Price")
|
||||
RegularPrice, RegularPrice.uuid == model.Product.regular_price_uuid))
|
||||
g.set_sorter('regular_price', RegularPrice.price)
|
||||
g.set_filter('regular_price', RegularPrice.price, label="Regular Price")
|
||||
|
||||
# current_price
|
||||
g.set_label('current_price', "Cur. Price")
|
||||
g.set_renderer('current_price', self.render_current_price_for_grid)
|
||||
CurrentPrice = orm.aliased(model.ProductPrice)
|
||||
g.set_joiner('current_price', lambda q: q.outerjoin(
|
||||
self.CurrentPrice, self.CurrentPrice.uuid == model.Product.current_price_uuid))
|
||||
g.set_sorter('current_price', self.CurrentPrice.price)
|
||||
g.set_filter('current_price', self.CurrentPrice.price, label="Current Price")
|
||||
CurrentPrice, CurrentPrice.uuid == model.Product.current_price_uuid))
|
||||
g.set_sorter('current_price', CurrentPrice.price)
|
||||
g.set_filter('current_price', CurrentPrice.price, label="Current Price")
|
||||
|
||||
# tpr_price
|
||||
TPRPrice = orm.aliased(model.ProductPrice)
|
||||
g.set_joiner('tpr_price', lambda q: q.outerjoin(
|
||||
self.TPRPrice, self.TPRPrice.uuid == model.Product.tpr_price_uuid))
|
||||
g.set_filter('tpr_price', self.TPRPrice.price)
|
||||
TPRPrice, TPRPrice.uuid == model.Product.tpr_price_uuid))
|
||||
g.set_filter('tpr_price', TPRPrice.price)
|
||||
|
||||
# sale_price
|
||||
SalePrice = orm.aliased(model.ProductPrice)
|
||||
g.set_joiner('sale_price', lambda q: q.outerjoin(
|
||||
self.SalePrice, self.SalePrice.uuid == model.Product.sale_price_uuid))
|
||||
g.set_filter('sale_price', self.SalePrice.price)
|
||||
SalePrice, SalePrice.uuid == model.Product.sale_price_uuid))
|
||||
g.set_filter('sale_price', SalePrice.price)
|
||||
|
||||
# suggested_price
|
||||
g.set_renderer('suggested_price', self.render_grid_suggested_price)
|
||||
|
@ -402,7 +402,9 @@ class ProductView(MasterView):
|
|||
return "${:0.2f}".format(cost.unit_cost)
|
||||
|
||||
def render_price(self, product, field):
|
||||
if not product.not_for_sale:
|
||||
# TODO: previously this rendered null (empty string) if
|
||||
# product was marked "not for sale" - but why? important?
|
||||
#if not product.not_for_sale:
|
||||
price = product[field]
|
||||
if price:
|
||||
return self.products_handler.render_price(price)
|
||||
|
|
Loading…
Reference in a new issue