diff --git a/tailbone/grids/core.py b/tailbone/grids/core.py index f918fad4..d825e4b4 100644 --- a/tailbone/grids/core.py +++ b/tailbone/grids/core.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2021 Lance Edgar +# Copyright © 2010-2022 Lance Edgar # # This file is part of Rattail. # @@ -197,7 +197,7 @@ class Grid(object): """ Mark the given column as "invisible" (but do not remove it). - Use :meth:`hide_column()` if you actually want to remove it. + Use :meth:`remove()` if you actually want to remove it. """ if invisible: if key not in self.invisible: @@ -217,7 +217,7 @@ class Grid(object): def replace(self, oldfield, newfield): self.insert_after(oldfield, newfield) - self.hide_column(oldfield) + self.remove(oldfield) def set_joiner(self, key, joiner): if joiner is None: diff --git a/tailbone/templates/formposter.mako b/tailbone/templates/formposter.mako index 6fc6eadc..885ac6c2 100644 --- a/tailbone/templates/formposter.mako +++ b/tailbone/templates/formposter.mako @@ -21,7 +21,8 @@ } else { this.$buefy.toast.open({ - message: "Submit failed: " + response.data.error, + message: "Submit failed: " + (response.data.error || + "(unknown error)"), type: 'is-danger', duration: 4000, // 4 seconds }) diff --git a/tailbone/templates/master/index.mako b/tailbone/templates/master/index.mako index 48e51286..5830519b 100644 --- a/tailbone/templates/master/index.mako +++ b/tailbone/templates/master/index.mako @@ -162,9 +162,6 @@
  • ${h.link_to("Create a new {}".format(model_title), url('{}.create'.format(route_prefix)))}
  • % endif % endif - % if not use_buefy and master.configurable and master.has_perm('configure'): -
  • ${h.link_to("Configure {}".format(config_title), url('{}.configure'.format(route_prefix)))}
  • - % endif % if master.has_input_file_templates and master.has_perm('create'): % for template in six.itervalues(input_file_templates):
  • ${h.link_to("Download {} Template".format(template['label']), template['effective_url'])}
  • diff --git a/tailbone/templates/products/configure.mako b/tailbone/templates/products/configure.mako index 3b75bc7f..612b8d36 100644 --- a/tailbone/templates/products/configure.mako +++ b/tailbone/templates/products/configure.mako @@ -3,7 +3,7 @@ <%def name="form_content()"> -

    Key Field

    +

    Display

    @@ -27,6 +27,15 @@ + + + Show "POD" Images as fallback + + +

    Handling

    @@ -43,18 +52,28 @@ -

    Display

    +

    Labels

    - - + - Show "POD" Images as fallback + Allow quick/direct label printing from Products page + + + + +
    diff --git a/tailbone/templates/products/index.mako b/tailbone/templates/products/index.mako index 3f65cd68..8eada2fc 100644 --- a/tailbone/templates/products/index.mako +++ b/tailbone/templates/products/index.mako @@ -1,8 +1,9 @@ -## -*- coding: utf-8 -*- +## -*- coding: utf-8; -*- <%inherit file="/master/index.mako" /> <%def name="extra_styles()"> ${parent.extra_styles()} + % if not use_buefy: + % endif <%def name="extra_javascript()"> ${parent.extra_javascript()} - % if label_profiles and request.has_perm('products.print_labels'): + % if not use_buefy and label_profiles and master.has_perm('print_labels'): + % endif + + + ${parent.body()} diff --git a/tailbone/views/master.py b/tailbone/views/master.py index 7eb9ebc8..7fd3cccf 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -4368,6 +4368,8 @@ class MasterView(View): if simple.get('type') is bool: value = six.text_type(bool(value)).lower() + elif simple.get('type') is int: + value = six.text_type(int(value or '0')) else: value = six.text_type(value) diff --git a/tailbone/views/products.py b/tailbone/views/products.py index 0e192bca..cf7be401 100644 --- a/tailbone/views/products.py +++ b/tailbone/views/products.py @@ -181,7 +181,9 @@ class ProductView(MasterView): self.print_labels = request.rattail_config.getbool('tailbone', 'products.print_labels', default=False) app = self.get_rattail_app() - self.handler = app.get_products_handler() + self.product_handler = app.get_products_handler() + # TODO: deprecate / remove this + self.handler = self.product_handler def query(self, session): user = self.request.user @@ -358,8 +360,13 @@ class ProductView(MasterView): g.set_sort_defaults('upc') - if self.print_labels and self.request.has_perm('products.print_labels'): - g.more_actions.append(grids.GridAction('print_label', icon='print')) + if self.print_labels and self.has_perm('print_labels'): + if use_buefy: + g.more_actions.append(self.make_action( + 'print_label', icon='print', url='#', + click_handler='quickLabelPrint(props.row)')) + else: + g.more_actions.append(grids.GridAction('print_label', icon='print')) g.set_type('upc', 'gpc') @@ -522,7 +529,7 @@ class ProductView(MasterView): if not product.not_for_sale: price = product[field] if price: - return self.handler.render_price(price) + return self.product_handler.render_price(price) def render_current_price_for_grid(self, product, field): text = self.render_price(product, field) or "" @@ -651,13 +658,20 @@ class ProductView(MasterView): return pretty_quantity(inventory.on_order) def template_kwargs_index(self, **kwargs): - if self.print_labels: - kwargs['label_profiles'] = Session.query(model.LabelProfile)\ - .filter(model.LabelProfile.visible == True)\ - .order_by(model.LabelProfile.ordinal)\ - .all() - return kwargs + kwargs = super(ProductView, self).template_kwargs_index(**kwargs) + model = self.model + if self.print_labels: + + kwargs['label_profiles'] = self.Session.query(model.LabelProfile)\ + .filter(model.LabelProfile.visible == True)\ + .order_by(model.LabelProfile.ordinal)\ + .all() + + kwargs['quick_label_speedbump_threshold'] = self.rattail_config.getint( + 'tailbone', 'products.quick_labels.speedbump_threshold') + + return kwargs def grid_extra_class(self, product, i): classes = [] @@ -794,10 +808,10 @@ class ProductView(MasterView): def get_instance(self): key = self.request.matchdict['uuid'] - product = Session.query(model.Product).get(key) + product = self.Session.query(model.Product).get(key) if product: return product - price = Session.query(model.ProductPrice).get(key) + price = self.Session.query(model.ProductPrice).get(key) if price: return price.product raise httpexceptions.HTTPNotFound() @@ -1151,7 +1165,7 @@ class ProductView(MasterView): product = kwargs['instance'] use_buefy = self.get_use_buefy() - kwargs['image_url'] = self.handler.get_image_url(product) + kwargs['image_url'] = self.product_handler.get_image_url(product) kwargs['product_key_field'] = self.rattail_config.product_key() # add price history, if user has access @@ -1701,11 +1715,11 @@ class ProductView(MasterView): upc = self.request.GET.get('upc', '').strip() upc = re.sub(r'\D', '', upc) if upc: - product = api.get_product_by_upc(Session(), upc) + product = api.get_product_by_upc(self.Session(), upc) if not product: # Try again, assuming caller did not include check digit. upc = GPC(upc, calc_check_digit='upc') - product = api.get_product_by_upc(Session(), upc) + product = api.get_product_by_upc(self.Session(), upc) if product and (not product.deleted or self.request.has_perm('products.view_deleted')): data = { 'uuid': product.uuid, @@ -1716,7 +1730,7 @@ class ProductView(MasterView): } uuid = self.request.GET.get('with_vendor_cost') if uuid: - vendor = Session.query(model.Vendor).get(uuid) + vendor = self.Session.query(model.Vendor).get(uuid) if not vendor: return {'error': "Vendor not found"} cost = product.cost_for_vendor(vendor) @@ -1912,21 +1926,28 @@ class ProductView(MasterView): def configure_get_simple_settings(self): return [ - # key field + # display {'section': 'rattail', 'option': 'product.key'}, {'section': 'rattail', 'option': 'product.key_title'}, + {'section': 'tailbone', + 'option': 'products.show_pod_image', + 'type': bool}, # handling {'section': 'rattail', 'option': 'products.convert_type2_for_gpc_lookup', 'type': bool}, - # display + # labels {'section': 'tailbone', - 'option': 'products.show_pod_image', + 'option': 'products.print_labels', 'type': bool}, + {'section': 'tailbone', + 'option': 'products.quick_labels.speedbump_threshold', + 'type': int}, + ] @classmethod @@ -2254,7 +2275,7 @@ def print_labels(request): except Exception as error: log.warning("error occurred while printing labels", exc_info=True) return {'error': six.text_type(error)} - return {} + return {'ok': True} def includeme(config):