Coverage for .tox / coverage / lib / python3.11 / site-packages / sideshow / web / views / batch / neworder.py: 100%
65 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-15 17:10 -0600
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-15 17:10 -0600
1# -*- coding: utf-8; -*-
2################################################################################
3#
4# Sideshow -- Case/Special Order Tracker
5# Copyright © 2024-2025 Lance Edgar
6#
7# This file is part of Sideshow.
8#
9# Sideshow is free software: you can redistribute it and/or modify it
10# under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# Sideshow is distributed in the hope that it will be useful, but
15# WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17# General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with Sideshow. If not, see <http://www.gnu.org/licenses/>.
21#
22################################################################################
23"""
24Views for New Order Batch
25"""
27from wuttaweb.views.batch import BatchMasterView
28from wuttaweb.forms.schema import WuttaMoney
30from sideshow.db.model import NewOrderBatch
31from sideshow.batch.neworder import NewOrderBatchHandler
32from sideshow.web.forms.schema import LocalCustomerRef, PendingCustomerRef
35class NewOrderBatchView(BatchMasterView): # pylint: disable=abstract-method
36 """
37 Master view for :class:`~sideshow.db.model.batch.neworder.NewOrderBatch`.
39 Route prefix is ``neworder_batches``.
41 Notable URLs provided by this class:
43 * ``/batch/neworder/``
44 * ``/batch/neworder/XXX``
45 * ``/batch/neworder/XXX/delete``
47 The purpose of this class is to expose "raw" batch data, e.g. for
48 troubleshooting purposes by the admin. Ideally it is not very
49 useful.
51 Note that the "create" and "edit" views are not exposed here,
52 since those should be handled by
53 :class:`~sideshow.web.views.orders.OrderView` instead.
54 """
56 model_class = NewOrderBatch
57 model_title = "New Order Batch"
58 model_title_plural = "New Order Batches"
59 route_prefix = "neworder_batches"
60 url_prefix = "/batch/neworder"
61 creatable = False
62 editable = False
64 labels = {
65 "store_id": "Store ID",
66 "customer_id": "Customer ID",
67 }
69 grid_columns = [
70 "id",
71 "store_id",
72 "customer_id",
73 "customer_name",
74 "phone_number",
75 "email_address",
76 "total_price",
77 "row_count",
78 "created",
79 "created_by",
80 "executed",
81 ]
83 filter_defaults = {
84 "executed": {"active": True, "verb": "is_null"},
85 }
87 # pylint: disable=duplicate-code
88 form_fields = [
89 "id",
90 "store_id",
91 "customer_id",
92 "local_customer",
93 "pending_customer",
94 "customer_name",
95 "phone_number",
96 "email_address",
97 "total_price",
98 "row_count",
99 "status_code",
100 "created",
101 "created_by",
102 "executed",
103 "executed_by",
104 ]
105 # pylint: enable=duplicate-code
107 row_labels = {
108 "product_scancode": "Scancode",
109 "product_brand": "Brand",
110 "product_description": "Description",
111 "product_size": "Size",
112 "order_uom": "Order UOM",
113 }
115 row_grid_columns = [
116 "sequence",
117 "product_scancode",
118 "product_brand",
119 "product_description",
120 "product_size",
121 "special_order",
122 "unit_price_quoted",
123 "case_size",
124 "case_price_quoted",
125 "order_qty",
126 "order_uom",
127 "discount_percent",
128 "total_price",
129 "status_code",
130 ]
132 def __init__(self, request, context=None):
133 super().__init__(request, context=context)
134 self.order_handler = self.app.get_order_handler()
136 def get_batch_handler(self): # pylint: disable=empty-docstring
137 """ """
138 # TODO: call self.app.get_batch_handler()
139 return NewOrderBatchHandler(self.config)
141 def configure_grid(self, grid): # pylint: disable=empty-docstring
142 """ """
143 g = grid
144 super().configure_grid(g)
146 # store_id
147 if not self.order_handler.expose_store_id():
148 g.remove("store_id")
150 # total_price
151 g.set_renderer("total_price", "currency")
153 def configure_form(self, form): # pylint: disable=empty-docstring
154 """ """
155 f = form
156 super().configure_form(f)
158 # store_id
159 if not self.order_handler.expose_store_id():
160 f.remove("store_id")
162 # local_customer
163 f.set_node("local_customer", LocalCustomerRef(self.request))
165 # pending_customer
166 f.set_node("pending_customer", PendingCustomerRef(self.request))
168 # total_price
169 f.set_node("total_price", WuttaMoney(self.request))
171 def configure_row_grid(self, grid): # pylint: disable=empty-docstring
172 """ """
173 g = grid
174 super().configure_row_grid(g)
176 # TODO
177 # order_uom
178 # g.set_renderer('order_uom', self.grid_render_enum, enum=enum.ORDER_UOM)
180 # unit_price_quoted
181 g.set_label("unit_price_quoted", "Unit Price", column_only=True)
182 g.set_renderer("unit_price_quoted", "currency")
184 # case_price_quoted
185 g.set_label("case_price_quoted", "Case Price", column_only=True)
186 g.set_renderer("case_price_quoted", "currency")
188 # discount_percent
189 g.set_renderer("discount_percent", "percent")
190 g.set_label("discount_percent", "Disc. %", column_only=True)
192 # total_price
193 g.set_renderer("total_price", "currency")
195 def get_xref_buttons(self, obj):
196 """
197 Adds "View this Order" button, if batch has been executed and
198 a corresponding :class:`~sideshow.db.model.orders.Order` can
199 be located.
200 """
201 batch = obj
202 buttons = super().get_xref_buttons(batch)
203 model = self.app.model
204 session = self.Session()
206 if batch.executed and self.request.has_perm("orders.view"):
207 order = (
208 session.query(model.Order)
209 .filter(model.Order.order_id == batch.id)
210 .first()
211 )
212 if order:
213 url = self.request.route_url("orders.view", uuid=order.uuid)
214 buttons.append(
215 self.make_button(
216 "View the Order", primary=True, icon_left="eye", url=url
217 )
218 )
220 return buttons
223def defaults(config, **kwargs): # pylint: disable=missing-function-docstring
224 base = globals()
226 NewOrderBatchView = kwargs.get( # pylint: disable=redefined-outer-name,invalid-name
227 "NewOrderBatchView", base["NewOrderBatchView"]
228 )
229 NewOrderBatchView.defaults(config)
232def includeme(config): # pylint: disable=missing-function-docstring
233 defaults(config)