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