Compare commits
	
		
			29 commits
		
	
	
		
			04de98a787
			...
			614189531f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 614189531f | |||
| 45e20926ef | |||
| e0a58dc524 | |||
| 8008b0edad | |||
| a56f6e9b91 | |||
| c3e262804c | |||
| 3ba57e3640 | |||
| efa13362e1 | |||
| 8d8f276793 | |||
| 54602f605d | |||
| c01f9395f0 | |||
| 281d654e32 | |||
| b2beeb4df3 | |||
| 1374910d65 | |||
| 258a1ed287 | |||
| c439bacf4f | |||
| 5a0d59ee36 | |||
| d2b5dce8e3 | |||
| e884263779 | |||
| a4c9e3070c | |||
| becf4fa822 | |||
| e5dbc4a98c | |||
| 93855e79d1 | |||
| fee44b455a | |||
| 625a22c83b | |||
| 2e248adb82 | |||
| 4194d20988 | |||
| 2d61d6aecf | |||
| 7833ad502a | 
					 27 changed files with 423 additions and 295 deletions
				
			
		
							
								
								
									
										32
									
								
								.pylintrc
									
										
									
									
									
								
							
							
						
						
									
										32
									
								
								.pylintrc
									
										
									
									
									
								
							| 
						 | 
					@ -3,35 +3,3 @@
 | 
				
			||||||
[MESSAGES CONTROL]
 | 
					[MESSAGES CONTROL]
 | 
				
			||||||
disable=fixme,
 | 
					disable=fixme,
 | 
				
			||||||
        duplicate-code,
 | 
					        duplicate-code,
 | 
				
			||||||
        abstract-method,
 | 
					 | 
				
			||||||
        arguments-differ,
 | 
					 | 
				
			||||||
        arguments-renamed,
 | 
					 | 
				
			||||||
        attribute-defined-outside-init,
 | 
					 | 
				
			||||||
        broad-exception-caught,
 | 
					 | 
				
			||||||
        consider-using-dict-comprehension,
 | 
					 | 
				
			||||||
        consider-using-f-string,
 | 
					 | 
				
			||||||
        consider-using-set-comprehension,
 | 
					 | 
				
			||||||
        empty-docstring,
 | 
					 | 
				
			||||||
        implicit-str-concat,
 | 
					 | 
				
			||||||
        inconsistent-return-statements,
 | 
					 | 
				
			||||||
        invalid-name,
 | 
					 | 
				
			||||||
        missing-class-docstring,
 | 
					 | 
				
			||||||
        missing-function-docstring,
 | 
					 | 
				
			||||||
        no-else-return,
 | 
					 | 
				
			||||||
        no-member,
 | 
					 | 
				
			||||||
        no-self-argument,
 | 
					 | 
				
			||||||
        redefined-outer-name,
 | 
					 | 
				
			||||||
        singleton-comparison,
 | 
					 | 
				
			||||||
        too-few-public-methods,
 | 
					 | 
				
			||||||
        too-many-arguments,
 | 
					 | 
				
			||||||
        too-many-branches,
 | 
					 | 
				
			||||||
        too-many-lines,
 | 
					 | 
				
			||||||
        too-many-locals,
 | 
					 | 
				
			||||||
        too-many-positional-arguments,
 | 
					 | 
				
			||||||
        too-many-public-methods,
 | 
					 | 
				
			||||||
        unnecessary-lambda-assignment,
 | 
					 | 
				
			||||||
        unused-argument,
 | 
					 | 
				
			||||||
        unused-import,
 | 
					 | 
				
			||||||
        unused-variable,
 | 
					 | 
				
			||||||
        unused-wildcard-import,
 | 
					 | 
				
			||||||
        wildcard-import,
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,9 @@ project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. _test coverage: https://buildbot.rattailproject.org/coverage/sideshow/
 | 
					.. _test coverage: https://buildbot.rattailproject.org/coverage/sideshow/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. image:: https://img.shields.io/badge/linting-pylint-yellowgreen
 | 
				
			||||||
 | 
					    :target: https://github.com/pylint-dev/pylint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
 | 
					.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
 | 
				
			||||||
   :target: https://github.com/psf/black
 | 
					   :target: https://github.com/psf/black
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@ class SideshowAppProvider(base.AppProvider):
 | 
				
			||||||
    handler`.
 | 
					    handler`.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_order_handler(self, **kwargs):
 | 
					    def get_order_handler(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Get the configured :term:`order handler` for the app.
 | 
					        Get the configured :term:`order handler` for the app.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,9 +49,9 @@ class SideshowAppProvider(base.AppProvider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :returns: Instance of :class:`~sideshow.orders.OrderHandler`.
 | 
					        :returns: Instance of :class:`~sideshow.orders.OrderHandler`.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if "order_handler" not in self.__dict__:
 | 
					        if "orders" not in self.app.handlers:
 | 
				
			||||||
            spec = self.config.get(
 | 
					            spec = self.config.get(
 | 
				
			||||||
                "sideshow.orders.handler_spec", default="sideshow.orders:OrderHandler"
 | 
					                "sideshow.orders.handler_spec", default="sideshow.orders:OrderHandler"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            self.order_handler = self.app.load_object(spec)(self.config)
 | 
					            self.app.handlers["orders"] = self.app.load_object(spec)(self.config)
 | 
				
			||||||
        return self.order_handler
 | 
					        return self.app.handlers["orders"]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
New Order Batch Handler
 | 
					New Order Batch Handler
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					# pylint: disable=too-many-lines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
import decimal
 | 
					import decimal
 | 
				
			||||||
| 
						 | 
					@ -35,7 +36,7 @@ from wuttjamaican.batch import BatchHandler
 | 
				
			||||||
from sideshow.db.model import NewOrderBatch
 | 
					from sideshow.db.model import NewOrderBatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NewOrderBatchHandler(BatchHandler):
 | 
					class NewOrderBatchHandler(BatchHandler):  # pylint: disable=too-many-public-methods
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    The :term:`batch handler` for :term:`new order batches <new order
 | 
					    The :term:`batch handler` for :term:`new order batches <new order
 | 
				
			||||||
    batch>`.
 | 
					    batch>`.
 | 
				
			||||||
| 
						 | 
					@ -116,6 +117,7 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        discount = self.config.get("sideshow.orders.default_item_discount")
 | 
					        discount = self.config.get("sideshow.orders.default_item_discount")
 | 
				
			||||||
        if discount:
 | 
					        if discount:
 | 
				
			||||||
            return decimal.Decimal(discount)
 | 
					            return decimal.Decimal(discount)
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def autocomplete_customers_external(self, session, term, user=None):
 | 
					    def autocomplete_customers_external(self, session, term, user=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -137,7 +139,9 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        raise NotImplementedError
 | 
					        raise NotImplementedError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def autocomplete_customers_local(self, session, term, user=None):
 | 
					    def autocomplete_customers_local(  # pylint: disable=unused-argument
 | 
				
			||||||
 | 
					        self, session, term, user=None
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Return autocomplete search results for
 | 
					        Return autocomplete search results for
 | 
				
			||||||
        :class:`~sideshow.db.model.customers.LocalCustomer` records.
 | 
					        :class:`~sideshow.db.model.customers.LocalCustomer` records.
 | 
				
			||||||
| 
						 | 
					@ -343,7 +347,9 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        raise NotImplementedError
 | 
					        raise NotImplementedError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def autocomplete_products_local(self, session, term, user=None):
 | 
					    def autocomplete_products_local(  # pylint: disable=unused-argument
 | 
				
			||||||
 | 
					        self, session, term, user=None
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Return autocomplete search results for
 | 
					        Return autocomplete search results for
 | 
				
			||||||
        :class:`~sideshow.db.model.products.LocalProduct` records.
 | 
					        :class:`~sideshow.db.model.products.LocalProduct` records.
 | 
				
			||||||
| 
						 | 
					@ -468,7 +474,9 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        raise NotImplementedError
 | 
					        raise NotImplementedError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_product_info_local(self, session, uuid, user=None):
 | 
					    def get_product_info_local(  # pylint: disable=unused-argument
 | 
				
			||||||
 | 
					        self, session, uuid, user=None
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Returns basic info for a :term:`local product` as pertains to
 | 
					        Returns basic info for a :term:`local product` as pertains to
 | 
				
			||||||
        ordering.
 | 
					        ordering.
 | 
				
			||||||
| 
						 | 
					@ -597,7 +605,6 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :returns: List of product info dicts.
 | 
					        :returns: List of product info dicts.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        model = self.app.model
 | 
					 | 
				
			||||||
        session = self.app.get_session(batch)
 | 
					        session = self.app.get_session(batch)
 | 
				
			||||||
        use_local = self.use_local_products()
 | 
					        use_local = self.use_local_products()
 | 
				
			||||||
        user = user or batch.created_by
 | 
					        user = user or batch.created_by
 | 
				
			||||||
| 
						 | 
					@ -650,7 +657,7 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return products
 | 
					        return products
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def add_item(
 | 
					    def add_item(  # pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        batch,
 | 
					        batch,
 | 
				
			||||||
        product_info,
 | 
					        product_info,
 | 
				
			||||||
| 
						 | 
					@ -761,7 +768,7 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        session.flush()
 | 
					        session.flush()
 | 
				
			||||||
        return row
 | 
					        return row
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update_item(
 | 
					    def update_item(  # pylint: disable=too-many-arguments,too-many-positional-arguments
 | 
				
			||||||
        self, row, product_info, order_qty, order_uom, discount_percent=None, user=None
 | 
					        self, row, product_info, order_qty, order_uom, discount_percent=None, user=None
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -865,7 +872,7 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        # refresh per new info
 | 
					        # refresh per new info
 | 
				
			||||||
        self.refresh_row(row)
 | 
					        self.refresh_row(row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def refresh_row(self, row):
 | 
					    def refresh_row(self, row):  # pylint: disable=too-many-branches
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Refresh data for the row.  This is called when adding a new
 | 
					        Refresh data for the row.  This is called when adding a new
 | 
				
			||||||
        row to the batch, or anytime the row is updated (e.g. when
 | 
					        row to the batch, or anytime the row is updated (e.g. when
 | 
				
			||||||
| 
						 | 
					@ -1023,7 +1030,7 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        super().remove_row(row)
 | 
					        super().remove_row(row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def do_delete(self, batch, user, **kwargs):
 | 
					    def do_delete(self, batch, user, **kwargs):  # pylint: disable=arguments-differ
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Delete a batch completely.
 | 
					        Delete a batch completely.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1047,7 +1054,7 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        # continue with normal deletion
 | 
					        # continue with normal deletion
 | 
				
			||||||
        super().do_delete(batch, user, **kwargs)
 | 
					        super().do_delete(batch, user, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def why_not_execute(self, batch, **kwargs):
 | 
					    def why_not_execute(self, batch, **kwargs):  # pylint: disable=arguments-differ
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        By default this checks to ensure the batch has a customer with
 | 
					        By default this checks to ensure the batch has a customer with
 | 
				
			||||||
        phone number, and at least one item.  It also may check to
 | 
					        phone number, and at least one item.  It also may check to
 | 
				
			||||||
| 
						 | 
					@ -1068,6 +1075,8 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        if not rows:
 | 
					        if not rows:
 | 
				
			||||||
            return "Must add at least one valid item"
 | 
					            return "Must add at least one valid item"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_effective_rows(self, batch):
 | 
					    def get_effective_rows(self, batch):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Only rows with
 | 
					        Only rows with
 | 
				
			||||||
| 
						 | 
					@ -1188,7 +1197,7 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        session.flush()
 | 
					        session.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_new_order(self, batch, rows, user=None, progress=None, **kwargs):
 | 
					    def make_new_order(self, batch, rows, user=None, progress=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Create a new :term:`order` from the batch data.
 | 
					        Create a new :term:`order` from the batch data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1205,7 +1214,6 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        :returns: :class:`~sideshow.db.model.orders.Order` instance.
 | 
					        :returns: :class:`~sideshow.db.model.orders.Order` instance.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					 | 
				
			||||||
        session = self.app.get_session(batch)
 | 
					        session = self.app.get_session(batch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        batch_fields = [
 | 
					        batch_fields = [
 | 
				
			||||||
| 
						 | 
					@ -1247,17 +1255,17 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # make order
 | 
					        # make order
 | 
				
			||||||
        kw = dict([(field, getattr(batch, field)) for field in batch_fields])
 | 
					        kw = {field: getattr(batch, field) for field in batch_fields}
 | 
				
			||||||
        kw["order_id"] = batch.id
 | 
					        kw["order_id"] = batch.id
 | 
				
			||||||
        kw["created_by"] = user
 | 
					        kw["created_by"] = user
 | 
				
			||||||
        order = model.Order(**kw)
 | 
					        order = model.Order(**kw)
 | 
				
			||||||
        session.add(order)
 | 
					        session.add(order)
 | 
				
			||||||
        session.flush()
 | 
					        session.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def convert(row, i):
 | 
					        def convert(row, i):  # pylint: disable=unused-argument
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # make order item
 | 
					            # make order item
 | 
				
			||||||
            kw = dict([(field, getattr(row, field)) for field in row_fields])
 | 
					            kw = {field: getattr(row, field) for field in row_fields}
 | 
				
			||||||
            item = model.OrderItem(**kw)
 | 
					            item = model.OrderItem(**kw)
 | 
				
			||||||
            order.items.append(item)
 | 
					            order.items.append(item)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1270,7 +1278,7 @@ class NewOrderBatchHandler(BatchHandler):
 | 
				
			||||||
        session.flush()
 | 
					        session.flush()
 | 
				
			||||||
        return order
 | 
					        return order
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_initial_item_status(self, item, user, **kwargs):
 | 
					    def set_initial_item_status(self, item, user):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Set the initial status and attach event(s) for the given item.
 | 
					        Set the initial status and attach event(s) for the given item.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -38,10 +38,10 @@ def install(
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    config = ctx.parent.wutta_config
 | 
					    config = ctx.parent.wutta_config
 | 
				
			||||||
    app = config.get_app()
 | 
					    app = config.get_app()
 | 
				
			||||||
    install = app.get_install_handler(
 | 
					    handler = app.get_install_handler(
 | 
				
			||||||
        pkg_name="sideshow",
 | 
					        pkg_name="sideshow",
 | 
				
			||||||
        app_title="Sideshow",
 | 
					        app_title="Sideshow",
 | 
				
			||||||
        pypi_name="Sideshow",
 | 
					        pypi_name="Sideshow",
 | 
				
			||||||
        egg_name="Sideshow",
 | 
					        egg_name="Sideshow",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    install.run()
 | 
					    handler.run()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ class SideshowConfig(WuttaConfigExtension):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    key = "sideshow"
 | 
					    key = "sideshow"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure(self, config):
 | 
					    def configure(self, config):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # app info
 | 
					        # app info
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@ class NewOrderBatch(model.BatchMixin, model.Base):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @declared_attr
 | 
					    @declared_attr
 | 
				
			||||||
    def __table_args__(cls):
 | 
					    def __table_args__(cls):  # pylint: disable=no-self-argument
 | 
				
			||||||
        return cls.__default_table_args__() + (
 | 
					        return cls.__default_table_args__() + (
 | 
				
			||||||
            sa.ForeignKeyConstraint(
 | 
					            sa.ForeignKeyConstraint(
 | 
				
			||||||
                ["local_customer_uuid"], ["sideshow_customer_local.uuid"]
 | 
					                ["local_customer_uuid"], ["sideshow_customer_local.uuid"]
 | 
				
			||||||
| 
						 | 
					@ -95,7 +95,9 @@ class NewOrderBatch(model.BatchMixin, model.Base):
 | 
				
			||||||
    local_customer_uuid = sa.Column(model.UUID(), nullable=True)
 | 
					    local_customer_uuid = sa.Column(model.UUID(), nullable=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @declared_attr
 | 
					    @declared_attr
 | 
				
			||||||
    def local_customer(cls):
 | 
					    def local_customer(  # pylint: disable=no-self-argument,missing-function-docstring
 | 
				
			||||||
 | 
					        cls,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        return orm.relationship(
 | 
					        return orm.relationship(
 | 
				
			||||||
            "LocalCustomer",
 | 
					            "LocalCustomer",
 | 
				
			||||||
            back_populates="new_order_batches",
 | 
					            back_populates="new_order_batches",
 | 
				
			||||||
| 
						 | 
					@ -111,7 +113,9 @@ class NewOrderBatch(model.BatchMixin, model.Base):
 | 
				
			||||||
    pending_customer_uuid = sa.Column(model.UUID(), nullable=True)
 | 
					    pending_customer_uuid = sa.Column(model.UUID(), nullable=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @declared_attr
 | 
					    @declared_attr
 | 
				
			||||||
    def pending_customer(cls):
 | 
					    def pending_customer(  # pylint: disable=no-self-argument,missing-function-docstring
 | 
				
			||||||
 | 
					        cls,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        return orm.relationship(
 | 
					        return orm.relationship(
 | 
				
			||||||
            "PendingCustomer",
 | 
					            "PendingCustomer",
 | 
				
			||||||
            back_populates="new_order_batches",
 | 
					            back_populates="new_order_batches",
 | 
				
			||||||
| 
						 | 
					@ -170,7 +174,7 @@ class NewOrderBatchRow(model.BatchRowMixin, model.Base):
 | 
				
			||||||
    __batch_class__ = NewOrderBatch
 | 
					    __batch_class__ = NewOrderBatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @declared_attr
 | 
					    @declared_attr
 | 
				
			||||||
    def __table_args__(cls):
 | 
					    def __table_args__(cls):  # pylint: disable=no-self-argument
 | 
				
			||||||
        return cls.__default_table_args__() + (
 | 
					        return cls.__default_table_args__() + (
 | 
				
			||||||
            sa.ForeignKeyConstraint(
 | 
					            sa.ForeignKeyConstraint(
 | 
				
			||||||
                ["local_product_uuid"], ["sideshow_product_local.uuid"]
 | 
					                ["local_product_uuid"], ["sideshow_product_local.uuid"]
 | 
				
			||||||
| 
						 | 
					@ -222,7 +226,9 @@ class NewOrderBatchRow(model.BatchRowMixin, model.Base):
 | 
				
			||||||
    local_product_uuid = sa.Column(model.UUID(), nullable=True)
 | 
					    local_product_uuid = sa.Column(model.UUID(), nullable=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @declared_attr
 | 
					    @declared_attr
 | 
				
			||||||
    def local_product(cls):
 | 
					    def local_product(  # pylint: disable=no-self-argument,missing-function-docstring
 | 
				
			||||||
 | 
					        cls,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        return orm.relationship(
 | 
					        return orm.relationship(
 | 
				
			||||||
            "LocalProduct",
 | 
					            "LocalProduct",
 | 
				
			||||||
            back_populates="new_order_batch_rows",
 | 
					            back_populates="new_order_batch_rows",
 | 
				
			||||||
| 
						 | 
					@ -238,7 +244,9 @@ class NewOrderBatchRow(model.BatchRowMixin, model.Base):
 | 
				
			||||||
    pending_product_uuid = sa.Column(model.UUID(), nullable=True)
 | 
					    pending_product_uuid = sa.Column(model.UUID(), nullable=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @declared_attr
 | 
					    @declared_attr
 | 
				
			||||||
    def pending_product(cls):
 | 
					    def pending_product(  # pylint: disable=no-self-argument,missing-function-docstring
 | 
				
			||||||
 | 
					        cls,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        return orm.relationship(
 | 
					        return orm.relationship(
 | 
				
			||||||
            "PendingProduct",
 | 
					            "PendingProduct",
 | 
				
			||||||
            back_populates="new_order_batch_rows",
 | 
					            back_populates="new_order_batch_rows",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ from wuttjamaican.db import model
 | 
				
			||||||
from sideshow.enum import PendingCustomerStatus
 | 
					from sideshow.enum import PendingCustomerStatus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CustomerMixin:
 | 
					class CustomerMixin:  # pylint: disable=too-few-public-methods
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Base class for customer tables.  This has shared columns, used by e.g.:
 | 
					    Base class for customer tables.  This has shared columns, used by e.g.:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,9 @@ class CustomerMixin:
 | 
				
			||||||
        return self.full_name or ""
 | 
					        return self.full_name or ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LocalCustomer(CustomerMixin, model.Base):
 | 
					class LocalCustomer(  # pylint: disable=too-few-public-methods
 | 
				
			||||||
 | 
					    CustomerMixin, model.Base
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    This table contains the :term:`local customer` records.
 | 
					    This table contains the :term:`local customer` records.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,7 +138,9 @@ class LocalCustomer(CustomerMixin, model.Base):
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PendingCustomer(CustomerMixin, model.Base):
 | 
					class PendingCustomer(  # pylint: disable=too-few-public-methods
 | 
				
			||||||
 | 
					    CustomerMixin, model.Base
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    This table contains the :term:`pending customer` records, used
 | 
					    This table contains the :term:`pending customer` records, used
 | 
				
			||||||
    when creating an :term:`order` for new/unknown customer.
 | 
					    when creating an :term:`order` for new/unknown customer.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ from sqlalchemy.ext.orderinglist import ordering_list
 | 
				
			||||||
from wuttjamaican.db import model
 | 
					from wuttjamaican.db import model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Order(model.Base):
 | 
					class Order(model.Base):  # pylint: disable=too-few-public-methods
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Represents an :term:`order` for a customer.  Each order has one or
 | 
					    Represents an :term:`order` for a customer.  Each order has one or
 | 
				
			||||||
    more :attr:`items`.
 | 
					    more :attr:`items`.
 | 
				
			||||||
| 
						 | 
					@ -519,7 +519,7 @@ class OrderItem(model.Base):
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def full_description(self):
 | 
					    def full_description(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        fields = [
 | 
					        fields = [
 | 
				
			||||||
            self.product_brand or "",
 | 
					            self.product_brand or "",
 | 
				
			||||||
| 
						 | 
					@ -542,7 +542,7 @@ class OrderItem(model.Base):
 | 
				
			||||||
        self.events.append(OrderItemEvent(**kwargs))
 | 
					        self.events.append(OrderItemEvent(**kwargs))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrderItemEvent(model.Base):
 | 
					class OrderItemEvent(model.Base):  # pylint: disable=too-few-public-methods
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    An event in the life of an :term:`order item`.
 | 
					    An event in the life of an :term:`order item`.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -169,7 +169,7 @@ class ProductMixin:
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def full_description(self):
 | 
					    def full_description(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        fields = [self.brand_name or "", self.description or "", self.size or ""]
 | 
					        fields = [self.brand_name or "", self.description or "", self.size or ""]
 | 
				
			||||||
        fields = [f.strip() for f in fields if f.strip()]
 | 
					        fields = [f.strip() for f in fields if f.strip()]
 | 
				
			||||||
| 
						 | 
					@ -179,7 +179,7 @@ class ProductMixin:
 | 
				
			||||||
        return self.full_description
 | 
					        return self.full_description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LocalProduct(ProductMixin, model.Base):
 | 
					class LocalProduct(ProductMixin, model.Base):  # pylint: disable=too-few-public-methods
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    This table contains the :term:`local product` records.
 | 
					    This table contains the :term:`local product` records.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -228,7 +228,9 @@ class LocalProduct(ProductMixin, model.Base):
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PendingProduct(ProductMixin, model.Base):
 | 
					class PendingProduct(  # pylint: disable=too-few-public-methods
 | 
				
			||||||
 | 
					    ProductMixin, model.Base
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    This table contains the :term:`pending product` records, used when
 | 
					    This table contains the :term:`pending product` records, used when
 | 
				
			||||||
    creating an :term:`order` for new/unknown product(s).
 | 
					    creating an :term:`order` for new/unknown product(s).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ Enum Values
 | 
				
			||||||
from enum import Enum
 | 
					from enum import Enum
 | 
				
			||||||
from collections import OrderedDict
 | 
					from collections import OrderedDict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from wuttjamaican.enum import *
 | 
					from wuttjamaican.enum import *  # pylint: disable=wildcard-import,unused-wildcard-import
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ORDER_UOM_CASE = "CS"
 | 
					ORDER_UOM_CASE = "CS"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,15 +72,15 @@ class OrderHandler(GenericHandler):
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                case_qty = self.app.render_quantity(case_size)
 | 
					                case_qty = self.app.render_quantity(case_size)
 | 
				
			||||||
                unit_qty = self.app.render_quantity(order_qty * case_size)
 | 
					                unit_qty = self.app.render_quantity(order_qty * case_size)
 | 
				
			||||||
            CS = enum.ORDER_UOM[enum.ORDER_UOM_CASE]
 | 
					            CS = enum.ORDER_UOM[enum.ORDER_UOM_CASE]  # pylint: disable=invalid-name
 | 
				
			||||||
            EA = enum.ORDER_UOM[enum.ORDER_UOM_UNIT]
 | 
					            EA = enum.ORDER_UOM[enum.ORDER_UOM_UNIT]  # pylint: disable=invalid-name
 | 
				
			||||||
            order_qty = self.app.render_quantity(order_qty)
 | 
					            order_qty = self.app.render_quantity(order_qty)
 | 
				
			||||||
            times = "×" if html else "x"
 | 
					            times = "×" if html else "x"
 | 
				
			||||||
            return f"{order_qty} {CS} ({times} {case_qty} = {unit_qty} {EA})"
 | 
					            return f"{order_qty} {CS} ({times} {case_qty} = {unit_qty} {EA})"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # units
 | 
					        # units
 | 
				
			||||||
        unit_qty = self.app.render_quantity(order_qty)
 | 
					        unit_qty = self.app.render_quantity(order_qty)
 | 
				
			||||||
        EA = enum.ORDER_UOM[enum.ORDER_UOM_UNIT]
 | 
					        EA = enum.ORDER_UOM[enum.ORDER_UOM_UNIT]  # pylint: disable=invalid-name
 | 
				
			||||||
        return f"{unit_qty} {EA}"
 | 
					        return f"{unit_qty} {EA}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def item_status_to_variant(self, status_code):
 | 
					    def item_status_to_variant(self, status_code):
 | 
				
			||||||
| 
						 | 
					@ -105,6 +105,7 @@ class OrderHandler(GenericHandler):
 | 
				
			||||||
            enum.ORDER_ITEM_STATUS_INACTIVE,
 | 
					            enum.ORDER_ITEM_STATUS_INACTIVE,
 | 
				
			||||||
        ):
 | 
					        ):
 | 
				
			||||||
            return "warning"
 | 
					            return "warning"
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_pending_product(self, pending_product, product_info, user, note=None):
 | 
					    def resolve_pending_product(self, pending_product, product_info, user, note=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -159,7 +160,10 @@ class OrderHandler(GenericHandler):
 | 
				
			||||||
        items = (
 | 
					        items = (
 | 
				
			||||||
            session.query(model.OrderItem)
 | 
					            session.query(model.OrderItem)
 | 
				
			||||||
            .filter(model.OrderItem.pending_product == pending_product)
 | 
					            .filter(model.OrderItem.pending_product == pending_product)
 | 
				
			||||||
            .filter(model.OrderItem.product_id == None)
 | 
					            .filter(
 | 
				
			||||||
 | 
					                model.OrderItem.product_id  # pylint: disable=singleton-comparison
 | 
				
			||||||
 | 
					                == None
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            .all()
 | 
					            .all()
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,7 +187,7 @@ class OrderHandler(GenericHandler):
 | 
				
			||||||
            if note:
 | 
					            if note:
 | 
				
			||||||
                item.add_event(enum.ORDER_ITEM_EVENT_NOTE_ADDED, user, note=note)
 | 
					                item.add_event(enum.ORDER_ITEM_EVENT_NOTE_ADDED, user, note=note)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def process_placement(
 | 
					    def process_placement(  # pylint: disable=too-many-arguments,too-many-positional-arguments
 | 
				
			||||||
        self, items, user, vendor_name=None, po_number=None, note=None
 | 
					        self, items, user, vendor_name=None, po_number=None, note=None
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -226,7 +230,7 @@ class OrderHandler(GenericHandler):
 | 
				
			||||||
                item.add_event(enum.ORDER_ITEM_EVENT_NOTE_ADDED, user, note=note)
 | 
					                item.add_event(enum.ORDER_ITEM_EVENT_NOTE_ADDED, user, note=note)
 | 
				
			||||||
            item.status_code = enum.ORDER_ITEM_STATUS_PLACED
 | 
					            item.status_code = enum.ORDER_ITEM_STATUS_PLACED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def process_receiving(
 | 
					    def process_receiving(  # pylint: disable=too-many-arguments,too-many-positional-arguments
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        items,
 | 
					        items,
 | 
				
			||||||
        user,
 | 
					        user,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,10 @@ from wuttaweb import testing as base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WebTestCase(base.WebTestCase):
 | 
					class WebTestCase(base.WebTestCase):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Custom class for web tests; it configures defaults specific to
 | 
				
			||||||
 | 
					    Sideshow.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_config(self, **kwargs):
 | 
					    def make_config(self, **kwargs):
 | 
				
			||||||
        config = super().make_config(**kwargs)
 | 
					        config = super().make_config(**kwargs)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ Sideshow web app
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    config.include("sideshow.web.static")
 | 
					    config.include("sideshow.web.static")
 | 
				
			||||||
    config.include("wuttaweb.subscribers")
 | 
					    config.include("wuttaweb.subscribers")
 | 
				
			||||||
    config.include("sideshow.web.views")
 | 
					    config.include("sideshow.web.views")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ Sideshow web app
 | 
				
			||||||
from wuttaweb import app as base
 | 
					from wuttaweb import app as base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main(global_config, **settings):
 | 
					def main(global_config, **settings):  # pylint: disable=unused-argument
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Make and return the WSGI app (Paste entry point).
 | 
					    Make and return the WSGI app (Paste entry point).
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ def main(global_config, **settings):
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # make config objects
 | 
					    # make config objects
 | 
				
			||||||
    wutta_config = base.make_wutta_config(settings)
 | 
					    wutta_config = base.make_wutta_config(settings)  # pylint: disable=unused-variable
 | 
				
			||||||
    pyramid_config = base.make_pyramid_config(settings)
 | 
					    pyramid_config = base.make_pyramid_config(settings)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # bring in the rest of Sideshow
 | 
					    # bring in the rest of Sideshow
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -37,17 +37,18 @@ class OrderRef(ObjectRef):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def model_class(self):
 | 
					    def model_class(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        return model.Order
 | 
					        return model.Order
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sort_query(self, query):
 | 
					    def sort_query(self, query):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        return query.order_by(self.model_class.order_id)
 | 
					        return query.order_by(self.model_class.order_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_object_url(self, order):
 | 
					    def get_object_url(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        order = obj
 | 
				
			||||||
        return self.request.route_url("orders.view", uuid=order.uuid)
 | 
					        return self.request.route_url("orders.view", uuid=order.uuid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,17 +63,18 @@ class LocalCustomerRef(ObjectRef):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def model_class(self):
 | 
					    def model_class(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        return model.LocalCustomer
 | 
					        return model.LocalCustomer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sort_query(self, query):
 | 
					    def sort_query(self, query):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        return query.order_by(self.model_class.full_name)
 | 
					        return query.order_by(self.model_class.full_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_object_url(self, customer):
 | 
					    def get_object_url(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        customer = obj
 | 
				
			||||||
        return self.request.route_url("local_customers.view", uuid=customer.uuid)
 | 
					        return self.request.route_url("local_customers.view", uuid=customer.uuid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,17 +89,18 @@ class PendingCustomerRef(ObjectRef):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def model_class(self):
 | 
					    def model_class(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        return model.PendingCustomer
 | 
					        return model.PendingCustomer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sort_query(self, query):
 | 
					    def sort_query(self, query):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        return query.order_by(self.model_class.full_name)
 | 
					        return query.order_by(self.model_class.full_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_object_url(self, customer):
 | 
					    def get_object_url(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        customer = obj
 | 
				
			||||||
        return self.request.route_url("pending_customers.view", uuid=customer.uuid)
 | 
					        return self.request.route_url("pending_customers.view", uuid=customer.uuid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,17 +114,18 @@ class LocalProductRef(ObjectRef):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def model_class(self):
 | 
					    def model_class(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        return model.LocalProduct
 | 
					        return model.LocalProduct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sort_query(self, query):
 | 
					    def sort_query(self, query):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        return query.order_by(self.model_class.scancode)
 | 
					        return query.order_by(self.model_class.scancode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_object_url(self, product):
 | 
					    def get_object_url(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        product = obj
 | 
				
			||||||
        return self.request.route_url("local_products.view", uuid=product.uuid)
 | 
					        return self.request.route_url("local_products.view", uuid=product.uuid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,15 +140,16 @@ class PendingProductRef(ObjectRef):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def model_class(self):
 | 
					    def model_class(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        return model.PendingProduct
 | 
					        return model.PendingProduct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sort_query(self, query):
 | 
					    def sort_query(self, query):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        return query.order_by(self.model_class.scancode)
 | 
					        return query.order_by(self.model_class.scancode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_object_url(self, product):
 | 
					    def get_object_url(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        product = obj
 | 
				
			||||||
        return self.request.route_url("pending_products.view", uuid=product.uuid)
 | 
					        return self.request.route_url("pending_products.view", uuid=product.uuid)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ class SideshowMenuHandler(base.MenuHandler):
 | 
				
			||||||
    Sideshow menu handler
 | 
					    Sideshow menu handler
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_menus(self, request, **kwargs):
 | 
					    def make_menus(self, request):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            self.make_orders_menu(request),
 | 
					            self.make_orders_menu(request),
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ class SideshowMenuHandler(base.MenuHandler):
 | 
				
			||||||
            self.make_admin_menu(request),
 | 
					            self.make_admin_menu(request),
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_orders_menu(self, request, **kwargs):
 | 
					    def make_orders_menu(self, request):  # pylint: disable=unused-argument
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Generate the Orders menu.
 | 
					        Generate the Orders menu.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -91,7 +91,7 @@ class SideshowMenuHandler(base.MenuHandler):
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_customers_menu(self, request, **kwargs):
 | 
					    def make_customers_menu(self, request):  # pylint: disable=unused-argument
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Generate the Customers menu.
 | 
					        Generate the Customers menu.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -112,7 +112,7 @@ class SideshowMenuHandler(base.MenuHandler):
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_products_menu(self, request, **kwargs):
 | 
					    def make_products_menu(self, request):  # pylint: disable=unused-argument
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Generate the Products menu.
 | 
					        Generate the Products menu.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -133,7 +133,7 @@ class SideshowMenuHandler(base.MenuHandler):
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_batch_menu(self, request, **kwargs):
 | 
					    def make_batch_menu(self, request):  # pylint: disable=unused-argument
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Generate the Batch menu.
 | 
					        Generate the Batch menu.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -149,7 +149,7 @@ class SideshowMenuHandler(base.MenuHandler):
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_other_menu(self, request, **kwargs):
 | 
					    def make_other_menu(self, request):  # pylint: disable=unused-argument
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Generate the "Other" menu.
 | 
					        Generate the "Other" menu.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -159,7 +159,7 @@ class SideshowMenuHandler(base.MenuHandler):
 | 
				
			||||||
            "items": [],
 | 
					            "items": [],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_admin_menu(self, request, **kwargs):
 | 
					    def make_admin_menu(self, request, **kwargs):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        kwargs["include_people"] = True
 | 
					        kwargs["include_people"] = True
 | 
				
			||||||
        menu = super().make_admin_menu(request, **kwargs)
 | 
					        menu = super().make_admin_menu(request, **kwargs)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -43,6 +43,6 @@ fontawesome_js = Resource(libcache, "fontawesome-5.3.1-all.min.js")
 | 
				
			||||||
# bb_vue_fontawesome_js = Resource(libcache, 'vue-fontawesome-3.0.6.index.es.js')
 | 
					# bb_vue_fontawesome_js = Resource(libcache, 'vue-fontawesome-3.0.6.index.es.js')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    config.include("wuttaweb.static")
 | 
					    config.include("wuttaweb.static")
 | 
				
			||||||
    config.add_static_view("sideshow", "sideshow.web:static", cache_max_age=3600)
 | 
					    config.add_static_view("sideshow", "sideshow.web:static", cache_max_age=3600)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ Sideshow Views
 | 
				
			||||||
from wuttaweb.views import essential
 | 
					from wuttaweb.views import essential
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # core views for wuttaweb
 | 
					    # core views for wuttaweb
 | 
				
			||||||
    essential.defaults(
 | 
					    essential.defaults(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ from sideshow.batch.neworder import NewOrderBatchHandler
 | 
				
			||||||
from sideshow.web.forms.schema import LocalCustomerRef, PendingCustomerRef
 | 
					from sideshow.web.forms.schema import LocalCustomerRef, PendingCustomerRef
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NewOrderBatchView(BatchMasterView):
 | 
					class NewOrderBatchView(BatchMasterView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for :class:`~sideshow.db.model.batch.neworder.NewOrderBatch`.
 | 
					    Master view for :class:`~sideshow.db.model.batch.neworder.NewOrderBatch`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,13 +131,14 @@ class NewOrderBatchView(BatchMasterView):
 | 
				
			||||||
        super().__init__(request, context=context)
 | 
					        super().__init__(request, context=context)
 | 
				
			||||||
        self.order_handler = self.app.get_order_handler()
 | 
					        self.order_handler = self.app.get_order_handler()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_batch_handler(self):
 | 
					    def get_batch_handler(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        # TODO: call self.app.get_batch_handler()
 | 
					        # TODO: call self.app.get_batch_handler()
 | 
				
			||||||
        return NewOrderBatchHandler(self.config)
 | 
					        return NewOrderBatchHandler(self.config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # store_id
 | 
					        # store_id
 | 
				
			||||||
| 
						 | 
					@ -147,8 +148,9 @@ class NewOrderBatchView(BatchMasterView):
 | 
				
			||||||
        # total_price
 | 
					        # total_price
 | 
				
			||||||
        g.set_renderer("total_price", "currency")
 | 
					        g.set_renderer("total_price", "currency")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_form(self, f):
 | 
					    def configure_form(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        f = form
 | 
				
			||||||
        super().configure_form(f)
 | 
					        super().configure_form(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # store_id
 | 
					        # store_id
 | 
				
			||||||
| 
						 | 
					@ -164,10 +166,10 @@ class NewOrderBatchView(BatchMasterView):
 | 
				
			||||||
        # total_price
 | 
					        # total_price
 | 
				
			||||||
        f.set_node("total_price", WuttaMoney(self.request))
 | 
					        f.set_node("total_price", WuttaMoney(self.request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_row_grid(self, g):
 | 
					    def configure_row_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_row_grid(g)
 | 
					        super().configure_row_grid(g)
 | 
				
			||||||
        enum = self.app.enum
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # TODO
 | 
					        # TODO
 | 
				
			||||||
        # order_uom
 | 
					        # order_uom
 | 
				
			||||||
| 
						 | 
					@ -188,12 +190,13 @@ class NewOrderBatchView(BatchMasterView):
 | 
				
			||||||
        # total_price
 | 
					        # total_price
 | 
				
			||||||
        g.set_renderer("total_price", "currency")
 | 
					        g.set_renderer("total_price", "currency")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_xref_buttons(self, batch):
 | 
					    def get_xref_buttons(self, obj):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Adds "View this Order" button, if batch has been executed and
 | 
					        Adds "View this Order" button, if batch has been executed and
 | 
				
			||||||
        a corresponding :class:`~sideshow.db.model.orders.Order` can
 | 
					        a corresponding :class:`~sideshow.db.model.orders.Order` can
 | 
				
			||||||
        be located.
 | 
					        be located.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        batch = obj
 | 
				
			||||||
        buttons = super().get_xref_buttons(batch)
 | 
					        buttons = super().get_xref_buttons(batch)
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        session = self.Session()
 | 
					        session = self.Session()
 | 
				
			||||||
| 
						 | 
					@ -215,12 +218,14 @@ class NewOrderBatchView(BatchMasterView):
 | 
				
			||||||
        return buttons
 | 
					        return buttons
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def defaults(config, **kwargs):
 | 
					def defaults(config, **kwargs):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    base = globals()
 | 
					    base = globals()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NewOrderBatchView = kwargs.get("NewOrderBatchView", base["NewOrderBatchView"])
 | 
					    NewOrderBatchView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "NewOrderBatchView", base["NewOrderBatchView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    NewOrderBatchView.defaults(config)
 | 
					    NewOrderBatchView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    defaults(config)
 | 
					    defaults(config)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ class CommonView(base.CommonView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        admin = model.Role(name="Order Admin")
 | 
					        admin = model.Role(name="Order Admin")
 | 
				
			||||||
        admin.notes = (
 | 
					        admin.notes = (
 | 
				
			||||||
            "this role was auto-created; " "you can change or remove it as needed."
 | 
					            "this role was auto-created; you can change or remove it as needed."
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        session.add(admin)
 | 
					        session.add(admin)
 | 
				
			||||||
| 
						 | 
					@ -101,5 +101,5 @@ class CommonView(base.CommonView):
 | 
				
			||||||
            auth.grant_permission(admin, perm)
 | 
					            auth.grant_permission(admin, perm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    base.defaults(config, **{"CommonView": CommonView})
 | 
					    base.defaults(config, **{"CommonView": CommonView})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Sideshow -- Case/Special Order Tracker
 | 
					#  Sideshow -- Case/Special Order Tracker
 | 
				
			||||||
#  Copyright © 2024 Lance Edgar
 | 
					#  Copyright © 2024-2025 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Sideshow.
 | 
					#  This file is part of Sideshow.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ from wuttaweb.forms.schema import UserRef, WuttaEnum
 | 
				
			||||||
from sideshow.db.model import LocalCustomer, PendingCustomer
 | 
					from sideshow.db.model import LocalCustomer, PendingCustomer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LocalCustomerView(MasterView):
 | 
					class LocalCustomerView(MasterView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for
 | 
					    Master view for
 | 
				
			||||||
    :class:`~sideshow.db.model.customers.LocalCustomer`; route prefix
 | 
					    :class:`~sideshow.db.model.customers.LocalCustomer`; route prefix
 | 
				
			||||||
| 
						 | 
					@ -76,8 +76,9 @@ class LocalCustomerView(MasterView):
 | 
				
			||||||
        "new_order_batches",
 | 
					        "new_order_batches",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # links
 | 
					        # links
 | 
				
			||||||
| 
						 | 
					@ -87,8 +88,9 @@ class LocalCustomerView(MasterView):
 | 
				
			||||||
        g.set_link("phone_number")
 | 
					        g.set_link("phone_number")
 | 
				
			||||||
        g.set_link("email_address")
 | 
					        g.set_link("email_address")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_form(self, f):
 | 
					    def configure_form(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        f = form
 | 
				
			||||||
        super().configure_form(f)
 | 
					        super().configure_form(f)
 | 
				
			||||||
        customer = f.model_instance
 | 
					        customer = f.model_instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,10 +140,11 @@ class LocalCustomerView(MasterView):
 | 
				
			||||||
        grid.set_renderer("total_price", grid.render_currency)
 | 
					        grid.set_renderer("total_price", grid.render_currency)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("orders.view"):
 | 
					        if self.request.has_perm("orders.view"):
 | 
				
			||||||
            url = lambda order, i: self.request.route_url(
 | 
					
 | 
				
			||||||
                "orders.view", uuid=order.uuid
 | 
					            def view_url(order, i):  # pylint: disable=unused-argument
 | 
				
			||||||
            )
 | 
					                return self.request.route_url("orders.view", uuid=order.uuid)
 | 
				
			||||||
            grid.add_action("view", icon="eye", url=url)
 | 
					
 | 
				
			||||||
 | 
					            grid.add_action("view", icon="eye", url=view_url)
 | 
				
			||||||
            grid.set_link("order_id")
 | 
					            grid.set_link("order_id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return grid
 | 
					        return grid
 | 
				
			||||||
| 
						 | 
					@ -174,17 +177,17 @@ class LocalCustomerView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("neworder_batches.view"):
 | 
					        if self.request.has_perm("neworder_batches.view"):
 | 
				
			||||||
            url = lambda batch, i: self.request.route_url(
 | 
					
 | 
				
			||||||
                "neworder_batches.view", uuid=batch.uuid
 | 
					            def view_url(batch, i):  # pylint: disable=unused-argument
 | 
				
			||||||
            )
 | 
					                return self.request.route_url("neworder_batches.view", uuid=batch.uuid)
 | 
				
			||||||
            grid.add_action("view", icon="eye", url=url)
 | 
					
 | 
				
			||||||
 | 
					            grid.add_action("view", icon="eye", url=view_url)
 | 
				
			||||||
            grid.set_link("id")
 | 
					            grid.set_link("id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return grid
 | 
					        return grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def objectify(self, form):
 | 
					    def objectify(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        enum = self.app.enum
 | 
					 | 
				
			||||||
        customer = super().objectify(form)
 | 
					        customer = super().objectify(form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        customer.full_name = self.app.make_full_name(
 | 
					        customer.full_name = self.app.make_full_name(
 | 
				
			||||||
| 
						 | 
					@ -194,7 +197,7 @@ class LocalCustomerView(MasterView):
 | 
				
			||||||
        return customer
 | 
					        return customer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PendingCustomerView(MasterView):
 | 
					class PendingCustomerView(MasterView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for
 | 
					    Master view for
 | 
				
			||||||
    :class:`~sideshow.db.model.customers.PendingCustomer`; route
 | 
					    :class:`~sideshow.db.model.customers.PendingCustomer`; route
 | 
				
			||||||
| 
						 | 
					@ -246,8 +249,9 @@ class PendingCustomerView(MasterView):
 | 
				
			||||||
        "new_order_batches",
 | 
					        "new_order_batches",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -261,8 +265,9 @@ class PendingCustomerView(MasterView):
 | 
				
			||||||
        g.set_link("phone_number")
 | 
					        g.set_link("phone_number")
 | 
				
			||||||
        g.set_link("email_address")
 | 
					        g.set_link("email_address")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_form(self, f):
 | 
					    def configure_form(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        f = form
 | 
				
			||||||
        super().configure_form(f)
 | 
					        super().configure_form(f)
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        customer = f.model_instance
 | 
					        customer = f.model_instance
 | 
				
			||||||
| 
						 | 
					@ -329,10 +334,11 @@ class PendingCustomerView(MasterView):
 | 
				
			||||||
        grid.set_renderer("total_price", grid.render_currency)
 | 
					        grid.set_renderer("total_price", grid.render_currency)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("orders.view"):
 | 
					        if self.request.has_perm("orders.view"):
 | 
				
			||||||
            url = lambda order, i: self.request.route_url(
 | 
					
 | 
				
			||||||
                "orders.view", uuid=order.uuid
 | 
					            def view_url(order, i):  # pylint: disable=unused-argument
 | 
				
			||||||
            )
 | 
					                return self.request.route_url("orders.view", uuid=order.uuid)
 | 
				
			||||||
            grid.add_action("view", icon="eye", url=url)
 | 
					
 | 
				
			||||||
 | 
					            grid.add_action("view", icon="eye", url=view_url)
 | 
				
			||||||
            grid.set_link("order_id")
 | 
					            grid.set_link("order_id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return grid
 | 
					        return grid
 | 
				
			||||||
| 
						 | 
					@ -365,15 +371,16 @@ class PendingCustomerView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("neworder_batches.view"):
 | 
					        if self.request.has_perm("neworder_batches.view"):
 | 
				
			||||||
            url = lambda batch, i: self.request.route_url(
 | 
					
 | 
				
			||||||
                "neworder_batches.view", uuid=batch.uuid
 | 
					            def view_url(batch, i):  # pylint: disable=unused-argument
 | 
				
			||||||
            )
 | 
					                return self.request.route_url("neworder_batches.view", uuid=batch.uuid)
 | 
				
			||||||
            grid.add_action("view", icon="eye", url=url)
 | 
					
 | 
				
			||||||
 | 
					            grid.add_action("view", icon="eye", url=view_url)
 | 
				
			||||||
            grid.set_link("id")
 | 
					            grid.set_link("id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return grid
 | 
					        return grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def objectify(self, form):
 | 
					    def objectify(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        customer = super().objectify(form)
 | 
					        customer = super().objectify(form)
 | 
				
			||||||
| 
						 | 
					@ -384,14 +391,15 @@ class PendingCustomerView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return customer
 | 
					        return customer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def delete_instance(self, customer):
 | 
					    def delete_instance(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        customer = obj
 | 
				
			||||||
        model_title = self.get_model_title()
 | 
					        model_title = self.get_model_title()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # avoid deleting if still referenced by order(s)
 | 
					        # avoid deleting if still referenced by order(s)
 | 
				
			||||||
        for order in customer.orders:
 | 
					        if list(customer.orders):
 | 
				
			||||||
            self.request.session.flash(
 | 
					            self.request.session.flash(
 | 
				
			||||||
                f"Cannot delete {model_title} still attached " "to Order(s)", "warning"
 | 
					                f"Cannot delete {model_title} still attached to Order(s)", "warning"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            raise self.redirect(self.get_action_url("view", customer))
 | 
					            raise self.redirect(self.get_action_url("view", customer))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -409,15 +417,19 @@ class PendingCustomerView(MasterView):
 | 
				
			||||||
        super().delete_instance(customer)
 | 
					        super().delete_instance(customer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def defaults(config, **kwargs):
 | 
					def defaults(config, **kwargs):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    base = globals()
 | 
					    base = globals()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LocalCustomerView = kwargs.get("LocalCustomerView", base["LocalCustomerView"])
 | 
					    LocalCustomerView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "LocalCustomerView", base["LocalCustomerView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    LocalCustomerView.defaults(config)
 | 
					    LocalCustomerView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PendingCustomerView = kwargs.get("PendingCustomerView", base["PendingCustomerView"])
 | 
					    PendingCustomerView = (  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        kwargs.get("PendingCustomerView", base["PendingCustomerView"])
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    PendingCustomerView.defaults(config)
 | 
					    PendingCustomerView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    defaults(config)
 | 
					    defaults(config)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,30 +23,23 @@
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
Views for Orders
 | 
					Views for Orders
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					# pylint: disable=too-many-lines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import decimal
 | 
					import decimal
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import colander
 | 
					 | 
				
			||||||
import sqlalchemy as sa
 | 
					import sqlalchemy as sa
 | 
				
			||||||
from sqlalchemy import orm
 | 
					from sqlalchemy import orm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from webhelpers2.html import tags, HTML
 | 
					from webhelpers2.html import tags, HTML
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from wuttaweb.views import MasterView
 | 
					from wuttaweb.views import MasterView
 | 
				
			||||||
from wuttaweb.forms.schema import (
 | 
					from wuttaweb.forms.schema import UserRef, WuttaMoney, WuttaQuantity, WuttaDictEnum
 | 
				
			||||||
    UserRef,
 | 
					 | 
				
			||||||
    WuttaMoney,
 | 
					 | 
				
			||||||
    WuttaQuantity,
 | 
					 | 
				
			||||||
    WuttaEnum,
 | 
					 | 
				
			||||||
    WuttaDictEnum,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from wuttaweb.util import make_json_safe
 | 
					from wuttaweb.util import make_json_safe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from sideshow.db.model import Order, OrderItem
 | 
					from sideshow.db.model import Order, OrderItem
 | 
				
			||||||
from sideshow.batch.neworder import NewOrderBatchHandler
 | 
					 | 
				
			||||||
from sideshow.web.forms.schema import (
 | 
					from sideshow.web.forms.schema import (
 | 
				
			||||||
    OrderRef,
 | 
					    OrderRef,
 | 
				
			||||||
    LocalCustomerRef,
 | 
					    LocalCustomerRef,
 | 
				
			||||||
| 
						 | 
					@ -59,7 +52,7 @@ from sideshow.web.forms.schema import (
 | 
				
			||||||
log = logging.getLogger(__name__)
 | 
					log = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrderView(MasterView):
 | 
					class OrderView(MasterView):  # pylint: disable=too-many-public-methods
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for :class:`~sideshow.db.model.orders.Order`; route
 | 
					    Master view for :class:`~sideshow.db.model.orders.Order`; route
 | 
				
			||||||
    prefix is ``orders``.
 | 
					    prefix is ``orders``.
 | 
				
			||||||
| 
						 | 
					@ -172,8 +165,9 @@ class OrderView(MasterView):
 | 
				
			||||||
        self.order_handler = self.app.get_order_handler()
 | 
					        self.order_handler = self.app.get_order_handler()
 | 
				
			||||||
        self.batch_handler = self.app.get_batch_handler("neworder")
 | 
					        self.batch_handler = self.app.get_batch_handler("neworder")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # store_id
 | 
					        # store_id
 | 
				
			||||||
| 
						 | 
					@ -224,7 +218,6 @@ class OrderView(MasterView):
 | 
				
			||||||
        * :meth:`submit_order()`
 | 
					        * :meth:`submit_order()`
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					 | 
				
			||||||
        session = self.Session()
 | 
					        session = self.Session()
 | 
				
			||||||
        batch = self.get_current_batch()
 | 
					        batch = self.get_current_batch()
 | 
				
			||||||
        self.creating = True
 | 
					        self.creating = True
 | 
				
			||||||
| 
						 | 
					@ -264,7 +257,7 @@ class OrderView(MasterView):
 | 
				
			||||||
            if action in json_actions:
 | 
					            if action in json_actions:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    result = getattr(self, action)(batch, data)
 | 
					                    result = getattr(self, action)(batch, data)
 | 
				
			||||||
                except Exception as error:
 | 
					                except Exception as error:  # pylint: disable=broad-exception-caught
 | 
				
			||||||
                    log.warning("error calling json action for order", exc_info=True)
 | 
					                    log.warning("error calling json action for order", exc_info=True)
 | 
				
			||||||
                    result = {"error": self.app.render_error(error)}
 | 
					                    result = {"error": self.app.render_error(error)}
 | 
				
			||||||
                return self.json_response(result)
 | 
					                return self.json_response(result)
 | 
				
			||||||
| 
						 | 
					@ -292,7 +285,10 @@ class OrderView(MasterView):
 | 
				
			||||||
        if context["expose_store_id"]:
 | 
					        if context["expose_store_id"]:
 | 
				
			||||||
            stores = (
 | 
					            stores = (
 | 
				
			||||||
                session.query(model.Store)
 | 
					                session.query(model.Store)
 | 
				
			||||||
                .filter(model.Store.archived == False)
 | 
					                .filter(
 | 
				
			||||||
 | 
					                    model.Store.archived  # pylint: disable=singleton-comparison
 | 
				
			||||||
 | 
					                    == False
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                .order_by(model.Store.store_id)
 | 
					                .order_by(model.Store.store_id)
 | 
				
			||||||
                .all()
 | 
					                .all()
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -313,12 +309,10 @@ class OrderView(MasterView):
 | 
				
			||||||
            context["default_item_discount"] = self.app.render_quantity(
 | 
					            context["default_item_discount"] = self.app.render_quantity(
 | 
				
			||||||
                self.batch_handler.get_default_item_discount()
 | 
					                self.batch_handler.get_default_item_discount()
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            context["dept_item_discounts"] = dict(
 | 
					            context["dept_item_discounts"] = {
 | 
				
			||||||
                [
 | 
					                d["department_id"]: d["default_item_discount"]
 | 
				
			||||||
                    (d["department_id"], d["default_item_discount"])
 | 
					 | 
				
			||||||
                for d in self.get_dept_item_discounts()
 | 
					                for d in self.get_dept_item_discounts()
 | 
				
			||||||
                ]
 | 
					            }
 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return self.render_to_response("create", context)
 | 
					        return self.render_to_response("create", context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -346,7 +340,10 @@ class OrderView(MasterView):
 | 
				
			||||||
            batch = (
 | 
					            batch = (
 | 
				
			||||||
                session.query(model.NewOrderBatch)
 | 
					                session.query(model.NewOrderBatch)
 | 
				
			||||||
                .filter(model.NewOrderBatch.created_by == user)
 | 
					                .filter(model.NewOrderBatch.created_by == user)
 | 
				
			||||||
                .filter(model.NewOrderBatch.executed == None)
 | 
					                .filter(
 | 
				
			||||||
 | 
					                    model.NewOrderBatch.executed  # pylint: disable=singleton-comparison
 | 
				
			||||||
 | 
					                    == None
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                .one()
 | 
					                .one()
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -381,7 +378,6 @@ class OrderView(MasterView):
 | 
				
			||||||
            return handler.autocomplete_customers_local(
 | 
					            return handler.autocomplete_customers_local(
 | 
				
			||||||
                session, term, user=self.request.user
 | 
					                session, term, user=self.request.user
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
        return handler.autocomplete_customers_external(
 | 
					        return handler.autocomplete_customers_external(
 | 
				
			||||||
            session, term, user=self.request.user
 | 
					            session, term, user=self.request.user
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -409,12 +405,11 @@ class OrderView(MasterView):
 | 
				
			||||||
            return handler.autocomplete_products_local(
 | 
					            return handler.autocomplete_products_local(
 | 
				
			||||||
                session, term, user=self.request.user
 | 
					                session, term, user=self.request.user
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
        return handler.autocomplete_products_external(
 | 
					        return handler.autocomplete_products_external(
 | 
				
			||||||
            session, term, user=self.request.user
 | 
					            session, term, user=self.request.user
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_pending_product_required_fields(self):
 | 
					    def get_pending_product_required_fields(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        required = []
 | 
					        required = []
 | 
				
			||||||
        for field in self.PENDING_PRODUCT_ENTRY_FIELDS:
 | 
					        for field in self.PENDING_PRODUCT_ENTRY_FIELDS:
 | 
				
			||||||
| 
						 | 
					@ -488,9 +483,11 @@ class OrderView(MasterView):
 | 
				
			||||||
        * :meth:`cancel_order()`
 | 
					        * :meth:`cancel_order()`
 | 
				
			||||||
        * :meth:`submit_order()`
 | 
					        * :meth:`submit_order()`
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        session = self.Session()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # drop current batch
 | 
					        # drop current batch
 | 
				
			||||||
        self.batch_handler.do_delete(batch, self.request.user)
 | 
					        self.batch_handler.do_delete(batch, self.request.user)
 | 
				
			||||||
        self.Session.flush()
 | 
					        session.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # send back to "create order" which makes new batch
 | 
					        # send back to "create order" which makes new batch
 | 
				
			||||||
        route_prefix = self.get_route_prefix()
 | 
					        route_prefix = self.get_route_prefix()
 | 
				
			||||||
| 
						 | 
					@ -508,8 +505,10 @@ class OrderView(MasterView):
 | 
				
			||||||
        * :meth:`start_over()`
 | 
					        * :meth:`start_over()`
 | 
				
			||||||
        * :meth:`submit_order()`
 | 
					        * :meth:`submit_order()`
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        session = self.Session()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.batch_handler.do_delete(batch, self.request.user)
 | 
					        self.batch_handler.do_delete(batch, self.request.user)
 | 
				
			||||||
        self.Session.flush()
 | 
					        session.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # set flash msg just to be more obvious
 | 
					        # set flash msg just to be more obvious
 | 
				
			||||||
        self.request.session.flash("New order has been deleted.")
 | 
					        self.request.session.flash("New order has been deleted.")
 | 
				
			||||||
| 
						 | 
					@ -534,7 +533,7 @@ class OrderView(MasterView):
 | 
				
			||||||
        batch.store_id = store_id
 | 
					        batch.store_id = store_id
 | 
				
			||||||
        return self.get_context_customer(batch)
 | 
					        return self.get_context_customer(batch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context_customer(self, batch):
 | 
					    def get_context_customer(self, batch):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        context = {
 | 
					        context = {
 | 
				
			||||||
            "store_id": batch.store_id,
 | 
					            "store_id": batch.store_id,
 | 
				
			||||||
| 
						 | 
					@ -599,7 +598,7 @@ class OrderView(MasterView):
 | 
				
			||||||
        self.batch_handler.set_customer(batch, customer_id)
 | 
					        self.batch_handler.set_customer(batch, customer_id)
 | 
				
			||||||
        return self.get_context_customer(batch)
 | 
					        return self.get_context_customer(batch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def unassign_customer(self, batch, data):
 | 
					    def unassign_customer(self, batch, data):  # pylint: disable=unused-argument
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Clear the customer info for a batch.
 | 
					        Clear the customer info for a batch.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -633,7 +632,9 @@ class OrderView(MasterView):
 | 
				
			||||||
        self.batch_handler.set_customer(batch, data, user=self.request.user)
 | 
					        self.batch_handler.set_customer(batch, data, user=self.request.user)
 | 
				
			||||||
        return self.get_context_customer(batch)
 | 
					        return self.get_context_customer(batch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_product_info(self, batch, data):
 | 
					    def get_product_info(  # pylint: disable=unused-argument,too-many-branches
 | 
				
			||||||
 | 
					        self, batch, data
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Fetch data for a specific product.
 | 
					        Fetch data for a specific product.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -707,7 +708,7 @@ class OrderView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return data
 | 
					        return data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_past_products(self, batch, data):
 | 
					    def get_past_products(self, batch, data):  # pylint: disable=unused-argument
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Fetch past products for convenient re-ordering.
 | 
					        Fetch past products for convenient re-ordering.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -802,7 +803,7 @@ class OrderView(MasterView):
 | 
				
			||||||
        self.batch_handler.do_remove_row(row)
 | 
					        self.batch_handler.do_remove_row(row)
 | 
				
			||||||
        return {"batch": self.normalize_batch(batch)}
 | 
					        return {"batch": self.normalize_batch(batch)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def submit_order(self, batch, data):
 | 
					    def submit_order(self, batch, data):  # pylint: disable=unused-argument
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        This submits the user's current new order batch, hence
 | 
					        This submits the user's current new order batch, hence
 | 
				
			||||||
        executing the batch and creating the true order.
 | 
					        executing the batch and creating the true order.
 | 
				
			||||||
| 
						 | 
					@ -820,7 +821,7 @@ class OrderView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            order = self.batch_handler.do_execute(batch, user)
 | 
					            order = self.batch_handler.do_execute(batch, user)
 | 
				
			||||||
        except Exception as error:
 | 
					        except Exception as error:  # pylint: disable=broad-exception-caught
 | 
				
			||||||
            log.warning("failed to execute new order batch: %s", batch, exc_info=True)
 | 
					            log.warning("failed to execute new order batch: %s", batch, exc_info=True)
 | 
				
			||||||
            return {"error": self.app.render_error(error)}
 | 
					            return {"error": self.app.render_error(error)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -828,7 +829,7 @@ class OrderView(MasterView):
 | 
				
			||||||
            "next_url": self.get_action_url("view", order),
 | 
					            "next_url": self.get_action_url("view", order),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def normalize_batch(self, batch):
 | 
					    def normalize_batch(self, batch):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            "uuid": batch.uuid.hex,
 | 
					            "uuid": batch.uuid.hex,
 | 
				
			||||||
| 
						 | 
					@ -838,7 +839,7 @@ class OrderView(MasterView):
 | 
				
			||||||
            "status_text": batch.status_text,
 | 
					            "status_text": batch.status_text,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def normalize_row(self, row):
 | 
					    def normalize_row(self, row):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        data = {
 | 
					        data = {
 | 
				
			||||||
            "uuid": row.uuid.hex,
 | 
					            "uuid": row.uuid.hex,
 | 
				
			||||||
| 
						 | 
					@ -915,7 +916,6 @@ class OrderView(MasterView):
 | 
				
			||||||
                row.unit_price_sale
 | 
					                row.unit_price_sale
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        if row.sale_ends:
 | 
					        if row.sale_ends:
 | 
				
			||||||
            sale_ends = row.sale_ends
 | 
					 | 
				
			||||||
            data["sale_ends"] = str(row.sale_ends)
 | 
					            data["sale_ends"] = str(row.sale_ends)
 | 
				
			||||||
            data["sale_ends_display"] = self.app.render_date(row.sale_ends)
 | 
					            data["sale_ends_display"] = self.app.render_date(row.sale_ends)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -953,12 +953,14 @@ class OrderView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return data
 | 
					        return data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_instance_title(self, order):
 | 
					    def get_instance_title(self, instance):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        order = instance
 | 
				
			||||||
        return f"#{order.order_id} for {order.customer_name}"
 | 
					        return f"#{order.order_id} for {order.customer_name}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_form(self, f):
 | 
					    def configure_form(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        f = form
 | 
				
			||||||
        super().configure_form(f)
 | 
					        super().configure_form(f)
 | 
				
			||||||
        order = f.model_instance
 | 
					        order = f.model_instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -985,8 +987,9 @@ class OrderView(MasterView):
 | 
				
			||||||
        f.set_node("created_by", UserRef(self.request))
 | 
					        f.set_node("created_by", UserRef(self.request))
 | 
				
			||||||
        f.set_readonly("created_by")
 | 
					        f.set_readonly("created_by")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_xref_buttons(self, order):
 | 
					    def get_xref_buttons(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        order = obj
 | 
				
			||||||
        buttons = super().get_xref_buttons(order)
 | 
					        buttons = super().get_xref_buttons(order)
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        session = self.Session()
 | 
					        session = self.Session()
 | 
				
			||||||
| 
						 | 
					@ -1007,14 +1010,16 @@ class OrderView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return buttons
 | 
					        return buttons
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_row_grid_data(self, order):
 | 
					    def get_row_grid_data(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        order = obj
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        session = self.Session()
 | 
					        session = self.Session()
 | 
				
			||||||
        return session.query(model.OrderItem).filter(model.OrderItem.order == order)
 | 
					        return session.query(model.OrderItem).filter(model.OrderItem.order == order)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_row_grid(self, g):
 | 
					    def configure_row_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_row_grid(g)
 | 
					        super().configure_row_grid(g)
 | 
				
			||||||
        # enum = self.app.enum
 | 
					        # enum = self.app.enum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1051,22 +1056,28 @@ class OrderView(MasterView):
 | 
				
			||||||
        # TODO: upstream should set this automatically
 | 
					        # TODO: upstream should set this automatically
 | 
				
			||||||
        g.row_class = self.row_grid_row_class
 | 
					        g.row_class = self.row_grid_row_class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def row_grid_row_class(self, item, data, i):
 | 
					    def row_grid_row_class(  # pylint: disable=unused-argument,empty-docstring
 | 
				
			||||||
 | 
					        self, item, data, i
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        variant = self.order_handler.item_status_to_variant(item.status_code)
 | 
					        variant = self.order_handler.item_status_to_variant(item.status_code)
 | 
				
			||||||
        if variant:
 | 
					        if variant:
 | 
				
			||||||
            return f"has-background-{variant}"
 | 
					            return f"has-background-{variant}"
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def render_status_code(self, item, key, value):
 | 
					    def render_status_code(  # pylint: disable=unused-argument,empty-docstring
 | 
				
			||||||
 | 
					        self, item, key, value
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        return enum.ORDER_ITEM_STATUS[value]
 | 
					        return enum.ORDER_ITEM_STATUS[value]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_row_action_url_view(self, item, i):
 | 
					    def get_row_action_url_view(self, row, i):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        item = row
 | 
				
			||||||
        return self.request.route_url("order_items.view", uuid=item.uuid)
 | 
					        return self.request.route_url("order_items.view", uuid=item.uuid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_get_simple_settings(self):
 | 
					    def configure_get_simple_settings(self):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        settings = [
 | 
					        settings = [
 | 
				
			||||||
            # stores
 | 
					            # stores
 | 
				
			||||||
| 
						 | 
					@ -1111,7 +1122,9 @@ class OrderView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return settings
 | 
					        return settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_get_context(self, **kwargs):
 | 
					    def configure_get_context(  # pylint: disable=empty-docstring,arguments-differ
 | 
				
			||||||
 | 
					        self, **kwargs
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        context = super().configure_get_context(**kwargs)
 | 
					        context = super().configure_get_context(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1125,7 +1138,9 @@ class OrderView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_gather_settings(self, data, simple_settings=None):
 | 
					    def configure_gather_settings(
 | 
				
			||||||
 | 
					        self, data, simple_settings=None
 | 
				
			||||||
 | 
					    ):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        settings = super().configure_gather_settings(
 | 
					        settings = super().configure_gather_settings(
 | 
				
			||||||
            data, simple_settings=simple_settings
 | 
					            data, simple_settings=simple_settings
 | 
				
			||||||
| 
						 | 
					@ -1148,7 +1163,9 @@ class OrderView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return settings
 | 
					        return settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_remove_settings(self, **kwargs):
 | 
					    def configure_remove_settings(  # pylint: disable=empty-docstring,arguments-differ
 | 
				
			||||||
 | 
					        self, **kwargs
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        session = self.Session()
 | 
					        session = self.Session()
 | 
				
			||||||
| 
						 | 
					@ -1224,7 +1241,7 @@ class OrderView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrderItemView(MasterView):
 | 
					class OrderItemView(MasterView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for :class:`~sideshow.db.model.orders.OrderItem`;
 | 
					    Master view for :class:`~sideshow.db.model.orders.OrderItem`;
 | 
				
			||||||
    route prefix is ``order_items``.
 | 
					    route prefix is ``order_items``.
 | 
				
			||||||
| 
						 | 
					@ -1329,20 +1346,21 @@ class OrderItemView(MasterView):
 | 
				
			||||||
        super().__init__(request, context=context)
 | 
					        super().__init__(request, context=context)
 | 
				
			||||||
        self.order_handler = self.app.get_order_handler()
 | 
					        self.order_handler = self.app.get_order_handler()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_fallback_templates(self, template):
 | 
					    def get_fallback_templates(self, template):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        templates = super().get_fallback_templates(template)
 | 
					        templates = super().get_fallback_templates(template)
 | 
				
			||||||
        templates.insert(0, f"/order-items/{template}.mako")
 | 
					        templates.insert(0, f"/order-items/{template}.mako")
 | 
				
			||||||
        return templates
 | 
					        return templates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_query(self, session=None):
 | 
					    def get_query(self, session=None):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        query = super().get_query(session=session)
 | 
					        query = super().get_query(session=session)
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        return query.join(model.Order)
 | 
					        return query.join(model.Order)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        # enum = self.app.enum
 | 
					        # enum = self.app.enum
 | 
				
			||||||
| 
						 | 
					@ -1391,24 +1409,32 @@ class OrderItemView(MasterView):
 | 
				
			||||||
        # status_code
 | 
					        # status_code
 | 
				
			||||||
        g.set_renderer("status_code", self.render_status_code)
 | 
					        g.set_renderer("status_code", self.render_status_code)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def render_order_attr(self, item, key, value):
 | 
					    def render_order_attr(  # pylint: disable=unused-argument,empty-docstring
 | 
				
			||||||
 | 
					        self, item, key, value
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        order = item.order
 | 
					        order = item.order
 | 
				
			||||||
        return getattr(order, key)
 | 
					        return getattr(order, key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def render_status_code(self, item, key, value):
 | 
					    def render_status_code(  # pylint: disable=unused-argument,empty-docstring
 | 
				
			||||||
 | 
					        self, item, key, value
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        return enum.ORDER_ITEM_STATUS[value]
 | 
					        return enum.ORDER_ITEM_STATUS[value]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def grid_row_class(self, item, data, i):
 | 
					    def grid_row_class(  # pylint: disable=unused-argument,empty-docstring
 | 
				
			||||||
 | 
					        self, item, data, i
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        variant = self.order_handler.item_status_to_variant(item.status_code)
 | 
					        variant = self.order_handler.item_status_to_variant(item.status_code)
 | 
				
			||||||
        if variant:
 | 
					        if variant:
 | 
				
			||||||
            return f"has-background-{variant}"
 | 
					            return f"has-background-{variant}"
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_form(self, f):
 | 
					    def configure_form(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        f = form
 | 
				
			||||||
        super().configure_form(f)
 | 
					        super().configure_form(f)
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        item = f.model_instance
 | 
					        item = f.model_instance
 | 
				
			||||||
| 
						 | 
					@ -1455,7 +1481,7 @@ class OrderItemView(MasterView):
 | 
				
			||||||
        # paid_amount
 | 
					        # paid_amount
 | 
				
			||||||
        f.set_node("paid_amount", WuttaMoney(self.request))
 | 
					        f.set_node("paid_amount", WuttaMoney(self.request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_template_context(self, context):
 | 
					    def get_template_context(self, context):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        if self.viewing:
 | 
					        if self.viewing:
 | 
				
			||||||
            model = self.app.model
 | 
					            model = self.app.model
 | 
				
			||||||
| 
						 | 
					@ -1505,7 +1531,9 @@ class OrderItemView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def render_event_note(self, event, key, value):
 | 
					    def render_event_note(  # pylint: disable=unused-argument,empty-docstring
 | 
				
			||||||
 | 
					        self, event, key, value
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        if event.type_code == enum.ORDER_ITEM_EVENT_NOTE_ADDED:
 | 
					        if event.type_code == enum.ORDER_ITEM_EVENT_NOTE_ADDED:
 | 
				
			||||||
| 
						 | 
					@ -1517,8 +1545,9 @@ class OrderItemView(MasterView):
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        return value
 | 
					        return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_xref_buttons(self, item):
 | 
					    def get_xref_buttons(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        item = obj
 | 
				
			||||||
        buttons = super().get_xref_buttons(item)
 | 
					        buttons = super().get_xref_buttons(item)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("orders.view"):
 | 
					        if self.request.has_perm("orders.view"):
 | 
				
			||||||
| 
						 | 
					@ -1552,10 +1581,8 @@ class OrderItemView(MasterView):
 | 
				
			||||||
        View which changes status for an order item.  This is
 | 
					        View which changes status for an order item.  This is
 | 
				
			||||||
        POST-only; will redirect back to the item view.
 | 
					        POST-only; will redirect back to the item view.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        model = self.app.model
 | 
					 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        main_item = self.get_instance()
 | 
					        main_item = self.get_instance()
 | 
				
			||||||
        session = self.Session()
 | 
					 | 
				
			||||||
        redirect = self.redirect(self.get_action_url("view", main_item))
 | 
					        redirect = self.redirect(self.get_action_url("view", main_item))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        extra_note = self.request.POST.get("note")
 | 
					        extra_note = self.request.POST.get("note")
 | 
				
			||||||
| 
						 | 
					@ -1581,8 +1608,9 @@ class OrderItemView(MasterView):
 | 
				
			||||||
            if item.status_code != new_status_code:
 | 
					            if item.status_code != new_status_code:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # event: change status
 | 
					                # event: change status
 | 
				
			||||||
                note = 'status changed from "{}" to "{}"'.format(
 | 
					                note = (
 | 
				
			||||||
                    enum.ORDER_ITEM_STATUS[item.status_code], new_status_text
 | 
					                    f'status changed from "{enum.ORDER_ITEM_STATUS[item.status_code]}" '
 | 
				
			||||||
 | 
					                    f'to "{new_status_text}"'
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                item.add_event(
 | 
					                item.add_event(
 | 
				
			||||||
                    enum.ORDER_ITEM_EVENT_STATUS_CHANGE, self.request.user, note=note
 | 
					                    enum.ORDER_ITEM_EVENT_STATUS_CHANGE, self.request.user, note=note
 | 
				
			||||||
| 
						 | 
					@ -1644,7 +1672,7 @@ class OrderItemView(MasterView):
 | 
				
			||||||
        return items
 | 
					        return items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def defaults(cls, config):
 | 
					    def defaults(cls, config):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        cls._order_item_defaults(config)
 | 
					        cls._order_item_defaults(config)
 | 
				
			||||||
        cls._defaults(config)
 | 
					        cls._defaults(config)
 | 
				
			||||||
| 
						 | 
					@ -1702,7 +1730,7 @@ class OrderItemView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlacementView(OrderItemView):
 | 
					class PlacementView(OrderItemView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for the "placement" phase of
 | 
					    Master view for the "placement" phase of
 | 
				
			||||||
    :class:`~sideshow.db.model.orders.OrderItem`; route prefix is
 | 
					    :class:`~sideshow.db.model.orders.OrderItem`; route prefix is
 | 
				
			||||||
| 
						 | 
					@ -1744,15 +1772,16 @@ class PlacementView(OrderItemView):
 | 
				
			||||||
        "vendor_name": {"active": True},
 | 
					        "vendor_name": {"active": True},
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_query(self, session=None):
 | 
					    def get_query(self, session=None):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        query = super().get_query(session=session)
 | 
					        query = super().get_query(session=session)
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        return query.filter(model.OrderItem.status_code == enum.ORDER_ITEM_STATUS_READY)
 | 
					        return query.filter(model.OrderItem.status_code == enum.ORDER_ITEM_STATUS_READY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # checkable
 | 
					        # checkable
 | 
				
			||||||
| 
						 | 
					@ -1840,7 +1869,7 @@ class PlacementView(OrderItemView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ReceivingView(OrderItemView):
 | 
					class ReceivingView(OrderItemView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for the "receiving" phase of
 | 
					    Master view for the "receiving" phase of
 | 
				
			||||||
    :class:`~sideshow.db.model.orders.OrderItem`; route prefix is
 | 
					    :class:`~sideshow.db.model.orders.OrderItem`; route prefix is
 | 
				
			||||||
| 
						 | 
					@ -1882,7 +1911,7 @@ class ReceivingView(OrderItemView):
 | 
				
			||||||
        "vendor_name": {"active": True},
 | 
					        "vendor_name": {"active": True},
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_query(self, session=None):
 | 
					    def get_query(self, session=None):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        query = super().get_query(session=session)
 | 
					        query = super().get_query(session=session)
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
| 
						 | 
					@ -1891,8 +1920,9 @@ class ReceivingView(OrderItemView):
 | 
				
			||||||
            model.OrderItem.status_code == enum.ORDER_ITEM_STATUS_PLACED
 | 
					            model.OrderItem.status_code == enum.ORDER_ITEM_STATUS_PLACED
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # checkable
 | 
					        # checkable
 | 
				
			||||||
| 
						 | 
					@ -2040,7 +2070,7 @@ class ReceivingView(OrderItemView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ContactView(OrderItemView):
 | 
					class ContactView(OrderItemView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for the "contact" phase of
 | 
					    Master view for the "contact" phase of
 | 
				
			||||||
    :class:`~sideshow.db.model.orders.OrderItem`; route prefix is
 | 
					    :class:`~sideshow.db.model.orders.OrderItem`; route prefix is
 | 
				
			||||||
| 
						 | 
					@ -2063,7 +2093,7 @@ class ContactView(OrderItemView):
 | 
				
			||||||
    route_prefix = "order_items_contact"
 | 
					    route_prefix = "order_items_contact"
 | 
				
			||||||
    url_prefix = "/contact"
 | 
					    url_prefix = "/contact"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_query(self, session=None):
 | 
					    def get_query(self, session=None):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        query = super().get_query(session=session)
 | 
					        query = super().get_query(session=session)
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
| 
						 | 
					@ -2074,8 +2104,9 @@ class ContactView(OrderItemView):
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # checkable
 | 
					        # checkable
 | 
				
			||||||
| 
						 | 
					@ -2207,7 +2238,7 @@ class ContactView(OrderItemView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DeliveryView(OrderItemView):
 | 
					class DeliveryView(OrderItemView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for the "delivery" phase of
 | 
					    Master view for the "delivery" phase of
 | 
				
			||||||
    :class:`~sideshow.db.model.orders.OrderItem`; route prefix is
 | 
					    :class:`~sideshow.db.model.orders.OrderItem`; route prefix is
 | 
				
			||||||
| 
						 | 
					@ -2230,7 +2261,7 @@ class DeliveryView(OrderItemView):
 | 
				
			||||||
    route_prefix = "order_items_delivery"
 | 
					    route_prefix = "order_items_delivery"
 | 
				
			||||||
    url_prefix = "/delivery"
 | 
					    url_prefix = "/delivery"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_query(self, session=None):
 | 
					    def get_query(self, session=None):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        query = super().get_query(session=session)
 | 
					        query = super().get_query(session=session)
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
| 
						 | 
					@ -2241,8 +2272,9 @@ class DeliveryView(OrderItemView):
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # checkable
 | 
					        # checkable
 | 
				
			||||||
| 
						 | 
					@ -2372,27 +2404,39 @@ class DeliveryView(OrderItemView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def defaults(config, **kwargs):
 | 
					def defaults(config, **kwargs):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    base = globals()
 | 
					    base = globals()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    OrderView = kwargs.get("OrderView", base["OrderView"])
 | 
					    OrderView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "OrderView", base["OrderView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    OrderView.defaults(config)
 | 
					    OrderView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    OrderItemView = kwargs.get("OrderItemView", base["OrderItemView"])
 | 
					    OrderItemView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "OrderItemView", base["OrderItemView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    OrderItemView.defaults(config)
 | 
					    OrderItemView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PlacementView = kwargs.get("PlacementView", base["PlacementView"])
 | 
					    PlacementView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "PlacementView", base["PlacementView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    PlacementView.defaults(config)
 | 
					    PlacementView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ReceivingView = kwargs.get("ReceivingView", base["ReceivingView"])
 | 
					    ReceivingView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "ReceivingView", base["ReceivingView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    ReceivingView.defaults(config)
 | 
					    ReceivingView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ContactView = kwargs.get("ContactView", base["ContactView"])
 | 
					    ContactView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "ContactView", base["ContactView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    ContactView.defaults(config)
 | 
					    ContactView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DeliveryView = kwargs.get("DeliveryView", base["DeliveryView"])
 | 
					    DeliveryView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "DeliveryView", base["DeliveryView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    DeliveryView.defaults(config)
 | 
					    DeliveryView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    defaults(config)
 | 
					    defaults(config)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,13 +25,13 @@ Views for Products
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from wuttaweb.views import MasterView
 | 
					from wuttaweb.views import MasterView
 | 
				
			||||||
from wuttaweb.forms.schema import UserRef, WuttaEnum, WuttaMoney, WuttaQuantity
 | 
					from wuttaweb.forms.schema import UserRef, WuttaMoney, WuttaQuantity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from sideshow.enum import PendingProductStatus
 | 
					from sideshow.enum import PendingProductStatus
 | 
				
			||||||
from sideshow.db.model import LocalProduct, PendingProduct
 | 
					from sideshow.db.model import LocalProduct, PendingProduct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LocalProductView(MasterView):
 | 
					class LocalProductView(MasterView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for :class:`~sideshow.db.model.products.LocalProduct`;
 | 
					    Master view for :class:`~sideshow.db.model.products.LocalProduct`;
 | 
				
			||||||
    route prefix is ``local_products``.
 | 
					    route prefix is ``local_products``.
 | 
				
			||||||
| 
						 | 
					@ -88,8 +88,9 @@ class LocalProductView(MasterView):
 | 
				
			||||||
        "new_order_batches",
 | 
					        "new_order_batches",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # unit_cost
 | 
					        # unit_cost
 | 
				
			||||||
| 
						 | 
					@ -105,10 +106,10 @@ class LocalProductView(MasterView):
 | 
				
			||||||
        g.set_link("description")
 | 
					        g.set_link("description")
 | 
				
			||||||
        g.set_link("size")
 | 
					        g.set_link("size")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_form(self, f):
 | 
					    def configure_form(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        f = form
 | 
				
			||||||
        super().configure_form(f)
 | 
					        super().configure_form(f)
 | 
				
			||||||
        enum = self.app.enum
 | 
					 | 
				
			||||||
        product = f.model_instance
 | 
					        product = f.model_instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # external_id
 | 
					        # external_id
 | 
				
			||||||
| 
						 | 
					@ -155,7 +156,7 @@ class LocalProductView(MasterView):
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        route_prefix = self.get_route_prefix()
 | 
					        route_prefix = self.get_route_prefix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        orders = set([item.order for item in product.order_items])
 | 
					        orders = {item.order for item in product.order_items}
 | 
				
			||||||
        orders = sorted(orders, key=lambda order: order.order_id)
 | 
					        orders = sorted(orders, key=lambda order: order.order_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        grid = self.make_grid(
 | 
					        grid = self.make_grid(
 | 
				
			||||||
| 
						 | 
					@ -177,10 +178,11 @@ class LocalProductView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("orders.view"):
 | 
					        if self.request.has_perm("orders.view"):
 | 
				
			||||||
            url = lambda order, i: self.request.route_url(
 | 
					
 | 
				
			||||||
                "orders.view", uuid=order.uuid
 | 
					            def view_url(order, i):  # pylint: disable=unused-argument
 | 
				
			||||||
            )
 | 
					                return self.request.route_url("orders.view", uuid=order.uuid)
 | 
				
			||||||
            grid.add_action("view", icon="eye", url=url)
 | 
					
 | 
				
			||||||
 | 
					            grid.add_action("view", icon="eye", url=view_url)
 | 
				
			||||||
            grid.set_link("order_id")
 | 
					            grid.set_link("order_id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return grid
 | 
					        return grid
 | 
				
			||||||
| 
						 | 
					@ -192,7 +194,7 @@ class LocalProductView(MasterView):
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        route_prefix = self.get_route_prefix()
 | 
					        route_prefix = self.get_route_prefix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        batches = set([row.batch for row in product.new_order_batch_rows])
 | 
					        batches = {row.batch for row in product.new_order_batch_rows}
 | 
				
			||||||
        batches = sorted(batches, key=lambda batch: batch.id)
 | 
					        batches = sorted(batches, key=lambda batch: batch.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        grid = self.make_grid(
 | 
					        grid = self.make_grid(
 | 
				
			||||||
| 
						 | 
					@ -216,16 +218,17 @@ class LocalProductView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("neworder_batches.view"):
 | 
					        if self.request.has_perm("neworder_batches.view"):
 | 
				
			||||||
            url = lambda batch, i: self.request.route_url(
 | 
					
 | 
				
			||||||
                "neworder_batches.view", uuid=batch.uuid
 | 
					            def view_url(batch, i):  # pylint: disable=unused-argument
 | 
				
			||||||
            )
 | 
					                return self.request.route_url("neworder_batches.view", uuid=batch.uuid)
 | 
				
			||||||
            grid.add_action("view", icon="eye", url=url)
 | 
					
 | 
				
			||||||
 | 
					            grid.add_action("view", icon="eye", url=view_url)
 | 
				
			||||||
            grid.set_link("id")
 | 
					            grid.set_link("id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return grid
 | 
					        return grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PendingProductView(MasterView):
 | 
					class PendingProductView(MasterView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for
 | 
					    Master view for
 | 
				
			||||||
    :class:`~sideshow.db.model.products.PendingProduct`; route
 | 
					    :class:`~sideshow.db.model.products.PendingProduct`; route
 | 
				
			||||||
| 
						 | 
					@ -292,8 +295,9 @@ class PendingProductView(MasterView):
 | 
				
			||||||
        "new_order_batches",
 | 
					        "new_order_batches",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -313,16 +317,19 @@ class PendingProductView(MasterView):
 | 
				
			||||||
        g.set_link("description")
 | 
					        g.set_link("description")
 | 
				
			||||||
        g.set_link("size")
 | 
					        g.set_link("size")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def grid_row_class(self, product, data, i):
 | 
					    def grid_row_class(  # pylint: disable=unused-argument,empty-docstring
 | 
				
			||||||
 | 
					        self, product, data, i
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        if product.status == enum.PendingProductStatus.IGNORED:
 | 
					        if product.status == enum.PendingProductStatus.IGNORED:
 | 
				
			||||||
            return "has-background-warning"
 | 
					            return "has-background-warning"
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_form(self, f):
 | 
					    def configure_form(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        f = form
 | 
				
			||||||
        super().configure_form(f)
 | 
					        super().configure_form(f)
 | 
				
			||||||
        enum = self.app.enum
 | 
					 | 
				
			||||||
        product = f.model_instance
 | 
					        product = f.model_instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # product_id
 | 
					        # product_id
 | 
				
			||||||
| 
						 | 
					@ -369,7 +376,7 @@ class PendingProductView(MasterView):
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        route_prefix = self.get_route_prefix()
 | 
					        route_prefix = self.get_route_prefix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        orders = set([item.order for item in product.order_items])
 | 
					        orders = {item.order for item in product.order_items}
 | 
				
			||||||
        orders = sorted(orders, key=lambda order: order.order_id)
 | 
					        orders = sorted(orders, key=lambda order: order.order_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        grid = self.make_grid(
 | 
					        grid = self.make_grid(
 | 
				
			||||||
| 
						 | 
					@ -391,10 +398,11 @@ class PendingProductView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("orders.view"):
 | 
					        if self.request.has_perm("orders.view"):
 | 
				
			||||||
            url = lambda order, i: self.request.route_url(
 | 
					
 | 
				
			||||||
                "orders.view", uuid=order.uuid
 | 
					            def view_url(order, i):  # pylint: disable=unused-argument
 | 
				
			||||||
            )
 | 
					                return self.request.route_url("orders.view", uuid=order.uuid)
 | 
				
			||||||
            grid.add_action("view", icon="eye", url=url)
 | 
					
 | 
				
			||||||
 | 
					            grid.add_action("view", icon="eye", url=view_url)
 | 
				
			||||||
            grid.set_link("order_id")
 | 
					            grid.set_link("order_id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return grid
 | 
					        return grid
 | 
				
			||||||
| 
						 | 
					@ -406,7 +414,7 @@ class PendingProductView(MasterView):
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        route_prefix = self.get_route_prefix()
 | 
					        route_prefix = self.get_route_prefix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        batches = set([row.batch for row in product.new_order_batch_rows])
 | 
					        batches = {row.batch for row in product.new_order_batch_rows}
 | 
				
			||||||
        batches = sorted(batches, key=lambda batch: batch.id)
 | 
					        batches = sorted(batches, key=lambda batch: batch.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        grid = self.make_grid(
 | 
					        grid = self.make_grid(
 | 
				
			||||||
| 
						 | 
					@ -430,15 +438,16 @@ class PendingProductView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.request.has_perm("neworder_batches.view"):
 | 
					        if self.request.has_perm("neworder_batches.view"):
 | 
				
			||||||
            url = lambda batch, i: self.request.route_url(
 | 
					
 | 
				
			||||||
                "neworder_batches.view", uuid=batch.uuid
 | 
					            def view_url(batch, i):  # pylint: disable=unused-argument
 | 
				
			||||||
            )
 | 
					                return self.request.route_url("neworder_batches.view", uuid=batch.uuid)
 | 
				
			||||||
            grid.add_action("view", icon="eye", url=url)
 | 
					
 | 
				
			||||||
 | 
					            grid.add_action("view", icon="eye", url=view_url)
 | 
				
			||||||
            grid.set_link("id")
 | 
					            grid.set_link("id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return grid
 | 
					        return grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_template_context(self, context):
 | 
					    def get_template_context(self, context):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -452,8 +461,9 @@ class PendingProductView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def delete_instance(self, product):
 | 
					    def delete_instance(self, obj):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        product = obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # avoid deleting if still referenced by new order batch(es)
 | 
					        # avoid deleting if still referenced by new order batch(es)
 | 
				
			||||||
        for row in product.new_order_batch_rows:
 | 
					        for row in product.new_order_batch_rows:
 | 
				
			||||||
| 
						 | 
					@ -531,7 +541,7 @@ class PendingProductView(MasterView):
 | 
				
			||||||
        return self.redirect(self.get_action_url("view", product))
 | 
					        return self.redirect(self.get_action_url("view", product))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def defaults(cls, config):
 | 
					    def defaults(cls, config):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        cls._defaults(config)
 | 
					        cls._defaults(config)
 | 
				
			||||||
        cls._pending_product_defaults(config)
 | 
					        cls._pending_product_defaults(config)
 | 
				
			||||||
| 
						 | 
					@ -576,15 +586,19 @@ class PendingProductView(MasterView):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def defaults(config, **kwargs):
 | 
					def defaults(config, **kwargs):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    base = globals()
 | 
					    base = globals()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LocalProductView = kwargs.get("LocalProductView", base["LocalProductView"])
 | 
					    LocalProductView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "LocalProductView", base["LocalProductView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    LocalProductView.defaults(config)
 | 
					    LocalProductView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PendingProductView = kwargs.get("PendingProductView", base["PendingProductView"])
 | 
					    PendingProductView = (  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        kwargs.get("PendingProductView", base["PendingProductView"])
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    PendingProductView.defaults(config)
 | 
					    PendingProductView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    defaults(config)
 | 
					    defaults(config)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@ from wuttaweb.views import MasterView
 | 
				
			||||||
from sideshow.db.model import Store
 | 
					from sideshow.db.model import Store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StoreView(MasterView):
 | 
					class StoreView(MasterView):  # pylint: disable=abstract-method
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for
 | 
					    Master view for
 | 
				
			||||||
    :class:`~sideshow.db.model.stores.Store`; route prefix
 | 
					    :class:`~sideshow.db.model.stores.Store`; route prefix
 | 
				
			||||||
| 
						 | 
					@ -56,21 +56,26 @@ class StoreView(MasterView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sort_defaults = "store_id"
 | 
					    sort_defaults = "store_id"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, grid):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        g = grid
 | 
				
			||||||
        super().configure_grid(g)
 | 
					        super().configure_grid(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # links
 | 
					        # links
 | 
				
			||||||
        g.set_link("store_id")
 | 
					        g.set_link("store_id")
 | 
				
			||||||
        g.set_link("name")
 | 
					        g.set_link("name")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def grid_row_class(self, store, data, i):
 | 
					    def grid_row_class(  # pylint: disable=unused-argument,empty-docstring
 | 
				
			||||||
 | 
					        self, store, data, i
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        if store.archived:
 | 
					        if store.archived:
 | 
				
			||||||
            return "has-background-warning"
 | 
					            return "has-background-warning"
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_form(self, f):
 | 
					    def configure_form(self, form):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
 | 
					        f = form
 | 
				
			||||||
        super().configure_form(f)
 | 
					        super().configure_form(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # store_id
 | 
					        # store_id
 | 
				
			||||||
| 
						 | 
					@ -79,7 +84,7 @@ class StoreView(MasterView):
 | 
				
			||||||
        # name
 | 
					        # name
 | 
				
			||||||
        f.set_validator("name", self.unique_name)
 | 
					        f.set_validator("name", self.unique_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def unique_store_id(self, node, value):
 | 
					    def unique_store_id(self, node, value):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        session = self.Session()
 | 
					        session = self.Session()
 | 
				
			||||||
| 
						 | 
					@ -93,7 +98,7 @@ class StoreView(MasterView):
 | 
				
			||||||
        if query.count():
 | 
					        if query.count():
 | 
				
			||||||
            node.raise_invalid("Store ID must be unique")
 | 
					            node.raise_invalid("Store ID must be unique")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def unique_name(self, node, value):
 | 
					    def unique_name(self, node, value):  # pylint: disable=empty-docstring
 | 
				
			||||||
        """ """
 | 
					        """ """
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        session = self.Session()
 | 
					        session = self.Session()
 | 
				
			||||||
| 
						 | 
					@ -108,12 +113,14 @@ class StoreView(MasterView):
 | 
				
			||||||
            node.raise_invalid("Name must be unique")
 | 
					            node.raise_invalid("Name must be unique")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def defaults(config, **kwargs):
 | 
					def defaults(config, **kwargs):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    base = globals()
 | 
					    base = globals()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    StoreView = kwargs.get("StoreView", base["StoreView"])
 | 
					    StoreView = kwargs.get(  # pylint: disable=redefined-outer-name,invalid-name
 | 
				
			||||||
 | 
					        "StoreView", base["StoreView"]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    StoreView.defaults(config)
 | 
					    StoreView.defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def includeme(config):
 | 
					def includeme(config):  # pylint: disable=missing-function-docstring
 | 
				
			||||||
    defaults(config)
 | 
					    defaults(config)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,7 @@ class TestLocalCustomerView(WebTestCase):
 | 
				
			||||||
            self.assertIn("new_order_batches", form)
 | 
					            self.assertIn("new_order_batches", form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_make_orders_grid(self):
 | 
					    def test_make_orders_grid(self):
 | 
				
			||||||
 | 
					        self.pyramid_config.add_route("orders.view", "/orders/{uuid}/view")
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        view = self.make_view()
 | 
					        view = self.make_view()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,7 +80,13 @@ class TestLocalCustomerView(WebTestCase):
 | 
				
			||||||
            self.assertEqual(len(grid.actions), 1)
 | 
					            self.assertEqual(len(grid.actions), 1)
 | 
				
			||||||
            self.assertEqual(grid.actions[0].key, "view")
 | 
					            self.assertEqual(grid.actions[0].key, "view")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # render grid for coverage generating url
 | 
				
			||||||
 | 
					        grid.render_vue_template()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_make_new_order_batches_grid(self):
 | 
					    def test_make_new_order_batches_grid(self):
 | 
				
			||||||
 | 
					        self.pyramid_config.add_route(
 | 
				
			||||||
 | 
					            "neworder_batches.view", "/batch/neworder/{uuid}/view"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        handler = NewOrderBatchHandler(self.config)
 | 
					        handler = NewOrderBatchHandler(self.config)
 | 
				
			||||||
        view = self.make_view()
 | 
					        view = self.make_view()
 | 
				
			||||||
| 
						 | 
					@ -104,6 +111,9 @@ class TestLocalCustomerView(WebTestCase):
 | 
				
			||||||
            self.assertEqual(len(grid.actions), 1)
 | 
					            self.assertEqual(len(grid.actions), 1)
 | 
				
			||||||
            self.assertEqual(grid.actions[0].key, "view")
 | 
					            self.assertEqual(grid.actions[0].key, "view")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # render grid for coverage generating url
 | 
				
			||||||
 | 
					        grid.render_vue_template()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_objectify(self):
 | 
					    def test_objectify(self):
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        view = self.make_view()
 | 
					        view = self.make_view()
 | 
				
			||||||
| 
						 | 
					@ -178,6 +188,7 @@ class TestPendingCustomerView(WebTestCase):
 | 
				
			||||||
            self.assertIn("new_order_batches", form)
 | 
					            self.assertIn("new_order_batches", form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_make_orders_grid(self):
 | 
					    def test_make_orders_grid(self):
 | 
				
			||||||
 | 
					        self.pyramid_config.add_route("orders.view", "/orders/{uuid}/view")
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        view = self.make_view()
 | 
					        view = self.make_view()
 | 
				
			||||||
| 
						 | 
					@ -202,7 +213,13 @@ class TestPendingCustomerView(WebTestCase):
 | 
				
			||||||
            self.assertEqual(len(grid.actions), 1)
 | 
					            self.assertEqual(len(grid.actions), 1)
 | 
				
			||||||
            self.assertEqual(grid.actions[0].key, "view")
 | 
					            self.assertEqual(grid.actions[0].key, "view")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # render grid for coverage generating url
 | 
				
			||||||
 | 
					        grid.render_vue_template()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_make_new_order_batches_grid(self):
 | 
					    def test_make_new_order_batches_grid(self):
 | 
				
			||||||
 | 
					        self.pyramid_config.add_route(
 | 
				
			||||||
 | 
					            "neworder_batches.view", "/batch/neworder/{uuid}/view"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        handler = NewOrderBatchHandler(self.config)
 | 
					        handler = NewOrderBatchHandler(self.config)
 | 
				
			||||||
| 
						 | 
					@ -230,6 +247,9 @@ class TestPendingCustomerView(WebTestCase):
 | 
				
			||||||
            self.assertEqual(len(grid.actions), 1)
 | 
					            self.assertEqual(len(grid.actions), 1)
 | 
				
			||||||
            self.assertEqual(grid.actions[0].key, "view")
 | 
					            self.assertEqual(grid.actions[0].key, "view")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # render grid for coverage generating url
 | 
				
			||||||
 | 
					        grid.render_vue_template()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_objectify(self):
 | 
					    def test_objectify(self):
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,7 @@ class TestLocalProductView(WebTestCase):
 | 
				
			||||||
            self.assertIn("local_products.view.orders", form.grid_vue_context)
 | 
					            self.assertIn("local_products.view.orders", form.grid_vue_context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_make_orders_grid(self):
 | 
					    def test_make_orders_grid(self):
 | 
				
			||||||
 | 
					        self.pyramid_config.add_route("orders.view", "/orders/{uuid}/view")
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        view = self.make_view()
 | 
					        view = self.make_view()
 | 
				
			||||||
| 
						 | 
					@ -89,7 +90,13 @@ class TestLocalProductView(WebTestCase):
 | 
				
			||||||
            self.assertEqual(len(grid.actions), 1)
 | 
					            self.assertEqual(len(grid.actions), 1)
 | 
				
			||||||
            self.assertEqual(grid.actions[0].key, "view")
 | 
					            self.assertEqual(grid.actions[0].key, "view")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # render grid for coverage generating url
 | 
				
			||||||
 | 
					        grid.render_vue_template()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_make_new_order_batches_grid(self):
 | 
					    def test_make_new_order_batches_grid(self):
 | 
				
			||||||
 | 
					        self.pyramid_config.add_route(
 | 
				
			||||||
 | 
					            "neworder_batches.view", "/batch/neworder/{uuid}/view"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        handler = NewOrderBatchHandler(self.config)
 | 
					        handler = NewOrderBatchHandler(self.config)
 | 
				
			||||||
| 
						 | 
					@ -117,6 +124,9 @@ class TestLocalProductView(WebTestCase):
 | 
				
			||||||
            self.assertEqual(len(grid.actions), 1)
 | 
					            self.assertEqual(len(grid.actions), 1)
 | 
				
			||||||
            self.assertEqual(grid.actions[0].key, "view")
 | 
					            self.assertEqual(grid.actions[0].key, "view")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # render grid for coverage generating url
 | 
				
			||||||
 | 
					        grid.render_vue_template()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestPendingProductView(WebTestCase):
 | 
					class TestPendingProductView(WebTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,6 +188,7 @@ class TestPendingProductView(WebTestCase):
 | 
				
			||||||
            self.assertIn("created_by", form)
 | 
					            self.assertIn("created_by", form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_make_orders_grid(self):
 | 
					    def test_make_orders_grid(self):
 | 
				
			||||||
 | 
					        self.pyramid_config.add_route("orders.view", "/orders/{uuid}/view")
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        view = self.make_view()
 | 
					        view = self.make_view()
 | 
				
			||||||
| 
						 | 
					@ -209,7 +220,13 @@ class TestPendingProductView(WebTestCase):
 | 
				
			||||||
            self.assertEqual(len(grid.actions), 1)
 | 
					            self.assertEqual(len(grid.actions), 1)
 | 
				
			||||||
            self.assertEqual(grid.actions[0].key, "view")
 | 
					            self.assertEqual(grid.actions[0].key, "view")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # render grid for coverage generating url
 | 
				
			||||||
 | 
					        grid.render_vue_template()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_make_new_order_batches_grid(self):
 | 
					    def test_make_new_order_batches_grid(self):
 | 
				
			||||||
 | 
					        self.pyramid_config.add_route(
 | 
				
			||||||
 | 
					            "neworder_batches.view", "/batch/neworder/{uuid}/view"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        handler = NewOrderBatchHandler(self.config)
 | 
					        handler = NewOrderBatchHandler(self.config)
 | 
				
			||||||
| 
						 | 
					@ -239,6 +256,9 @@ class TestPendingProductView(WebTestCase):
 | 
				
			||||||
            self.assertEqual(len(grid.actions), 1)
 | 
					            self.assertEqual(len(grid.actions), 1)
 | 
				
			||||||
            self.assertEqual(grid.actions[0].key, "view")
 | 
					            self.assertEqual(grid.actions[0].key, "view")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # render grid for coverage generating url
 | 
				
			||||||
 | 
					        grid.render_vue_template()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_template_context(self):
 | 
					    def test_get_template_context(self):
 | 
				
			||||||
        enum = self.app.enum
 | 
					        enum = self.app.enum
 | 
				
			||||||
        model = self.app.model
 | 
					        model = self.app.model
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue