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

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""" 

26 

27from wuttaweb.views.batch import BatchMasterView 

28from wuttaweb.forms.schema import WuttaMoney 

29 

30from sideshow.db.model import NewOrderBatch 

31from sideshow.batch.neworder import NewOrderBatchHandler 

32from sideshow.web.forms.schema import LocalCustomerRef, PendingCustomerRef 

33 

34 

35class NewOrderBatchView(BatchMasterView): # pylint: disable=abstract-method 

36 """ 

37 Master view for :class:`~sideshow.db.model.batch.neworder.NewOrderBatch`. 

38 

39 Route prefix is ``neworder_batches``. 

40 

41 Notable URLs provided by this class: 

42 

43 * ``/batch/neworder/`` 

44 * ``/batch/neworder/XXX`` 

45 * ``/batch/neworder/XXX/delete`` 

46 

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. 

50 

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 """ 

55 

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 

63 

64 labels = { 

65 "store_id": "Store ID", 

66 "customer_id": "Customer ID", 

67 } 

68 

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 ] 

82 

83 filter_defaults = { 

84 "executed": {"active": True, "verb": "is_null"}, 

85 } 

86 

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 

106 

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 } 

114 

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 ] 

131 

132 def __init__(self, request, context=None): 

133 super().__init__(request, context=context) 

134 self.order_handler = self.app.get_order_handler() 

135 

136 def get_batch_handler(self): # pylint: disable=empty-docstring 

137 """ """ 

138 # TODO: call self.app.get_batch_handler() 

139 return NewOrderBatchHandler(self.config) 

140 

141 def configure_grid(self, grid): # pylint: disable=empty-docstring 

142 """ """ 

143 g = grid 

144 super().configure_grid(g) 

145 

146 # store_id 

147 if not self.order_handler.expose_store_id(): 

148 g.remove("store_id") 

149 

150 # total_price 

151 g.set_renderer("total_price", "currency") 

152 

153 def configure_form(self, form): # pylint: disable=empty-docstring 

154 """ """ 

155 f = form 

156 super().configure_form(f) 

157 

158 # store_id 

159 if not self.order_handler.expose_store_id(): 

160 f.remove("store_id") 

161 

162 # local_customer 

163 f.set_node("local_customer", LocalCustomerRef(self.request)) 

164 

165 # pending_customer 

166 f.set_node("pending_customer", PendingCustomerRef(self.request)) 

167 

168 # total_price 

169 f.set_node("total_price", WuttaMoney(self.request)) 

170 

171 def configure_row_grid(self, grid): # pylint: disable=empty-docstring 

172 """ """ 

173 g = grid 

174 super().configure_row_grid(g) 

175 

176 # TODO 

177 # order_uom 

178 # g.set_renderer('order_uom', self.grid_render_enum, enum=enum.ORDER_UOM) 

179 

180 # unit_price_quoted 

181 g.set_label("unit_price_quoted", "Unit Price", column_only=True) 

182 g.set_renderer("unit_price_quoted", "currency") 

183 

184 # case_price_quoted 

185 g.set_label("case_price_quoted", "Case Price", column_only=True) 

186 g.set_renderer("case_price_quoted", "currency") 

187 

188 # discount_percent 

189 g.set_renderer("discount_percent", "percent") 

190 g.set_label("discount_percent", "Disc. %", column_only=True) 

191 

192 # total_price 

193 g.set_renderer("total_price", "currency") 

194 

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() 

205 

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 ) 

219 

220 return buttons 

221 

222 

223def defaults(config, **kwargs): # pylint: disable=missing-function-docstring 

224 base = globals() 

225 

226 NewOrderBatchView = kwargs.get( # pylint: disable=redefined-outer-name,invalid-name 

227 "NewOrderBatchView", base["NewOrderBatchView"] 

228 ) 

229 NewOrderBatchView.defaults(config) 

230 

231 

232def includeme(config): # pylint: disable=missing-function-docstring 

233 defaults(config)