From f3d449c9f3f4663b8f8b9aae0e6de0cc03be7885 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 11 Feb 2015 00:52:23 -0600 Subject: [PATCH] Add UI support for `Product.deleted` column. This leverages the 'products.view_deleted' permission to hide products which are marked as deleted from various views. Also adds a 'deleted' class to product grid rows where the flag is set, and adds a flash warning when viewing a deleted product. --- tailbone/views/crud.py | 7 ++++++ tailbone/views/products.py | 47 ++++++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/tailbone/views/crud.py b/tailbone/views/crud.py index c54ce13f..ce2f6203 100644 --- a/tailbone/views/crud.py +++ b/tailbone/views/crud.py @@ -162,6 +162,10 @@ class CrudView(View): self.validation_failed(form) + result = self.post_crud(model, form) + if result is not None: + return result + kwargs = self.template_kwargs(form) kwargs['form'] = form return kwargs @@ -169,6 +173,9 @@ class CrudView(View): def pre_crud(self, model): pass + def post_crud(self, model, form): + pass + def template_kwargs(self, form): if not form.creating and is_versioned(self.mapped_class): return {'version_count': self.count_versions()} diff --git a/tailbone/views/products.py b/tailbone/views/products.py index d30aa2cf..a322edd5 100644 --- a/tailbone/views/products.py +++ b/tailbone/views/products.py @@ -184,6 +184,8 @@ class ProductsGrid(SearchableAlchemyGridView): def query(self): q = self.make_query() + if not self.request.has_perm('products.view_deleted'): + q = q.filter(model.Product.deleted == False) q = q.options(joinedload(Product.brand)) q = q.options(joinedload(Product.department)) q = q.options(joinedload(Product.subdepartment)) @@ -194,7 +196,12 @@ class ProductsGrid(SearchableAlchemyGridView): def grid(self): def extra_row_class(row, i): - return 'not-for-sale' if row.not_for_sale else None + cls = [] + if row.not_for_sale: + cls.append('not-for-sale') + if row.deleted: + cls.append('deleted') + return ' '.join(cls) if cls else None g = self.make_grid(extra_row_class=extra_row_class) g.upc.set(renderer=GPCFieldRenderer) g.regular_price.set(renderer=PriceFieldRenderer) @@ -278,12 +285,20 @@ class ProductCrud(CrudView): fs.regular_price, fs.current_price, fs.not_for_sale, + fs.deleted, ]) if not self.readonly: del fs.regular_price del fs.current_price return fs + def pre_crud(self, product): + self.product_deleted = not self.creating and product.deleted + + def post_crud(self, product, form): + if self.product_deleted: + self.request.session.flash("This product is marked as deleted.", 'error') + def template_kwargs(self, form): kwargs = super(ProductCrud, self).template_kwargs(form) kwargs['image'] = False @@ -310,6 +325,25 @@ class ProductVersionView(VersionView): (model.ProductPrice, 'product_uuid'), ] + def warn_if_deleted(self): + """ + Maybe set flash warning if product is marked deleted. + """ + uuid = self.request.matchdict['uuid'] + product = Session.query(model.Product).get(uuid) + assert product, "No product found for UUID: {0}".format(repr(uuid)) + if product.deleted: + self.request.session.flash("This product is marked as deleted.", 'error') + + def list(self): + self.warn_if_deleted() + return super(ProductVersionView, self).list() + + def details(self): + self.warn_if_deleted() + return super(ProductVersionView, self).details() + + def products_search(request): """ @@ -328,10 +362,13 @@ def products_search(request): upc = GPC(upc, calc_check_digit='upc') product = get_product_by_upc(Session, upc) if product: - product = { - 'uuid': product.uuid, - 'full_description': product.full_description, - } + if product.deleted and not request.has_perm('products.view_deleted'): + product = None + else: + product = { + 'uuid': product.uuid, + 'full_description': product.full_description, + } return {'product': product}