Coverage for .tox/coverage/lib/python3.11/site-packages/sideshow/web/views/batch/neworder.py: 100%

62 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-16 07:16 -0500

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

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 model_class = NewOrderBatch 

56 model_title = "New Order Batch" 

57 model_title_plural = "New Order Batches" 

58 route_prefix = 'neworder_batches' 

59 url_prefix = '/batch/neworder' 

60 creatable = False 

61 editable = False 

62 

63 labels = { 

64 'store_id': "Store ID", 

65 'customer_id': "Customer ID", 

66 } 

67 

68 grid_columns = [ 

69 'id', 

70 'store_id', 

71 'customer_id', 

72 'customer_name', 

73 'phone_number', 

74 'email_address', 

75 'total_price', 

76 'row_count', 

77 'created', 

78 'created_by', 

79 'executed', 

80 ] 

81 

82 filter_defaults = { 

83 'executed': {'active': True, 'verb': 'is_null'}, 

84 } 

85 

86 form_fields = [ 

87 'id', 

88 'store_id', 

89 'customer_id', 

90 'local_customer', 

91 'pending_customer', 

92 'customer_name', 

93 'phone_number', 

94 'email_address', 

95 'total_price', 

96 'row_count', 

97 'status_code', 

98 'created', 

99 'created_by', 

100 'executed', 

101 'executed_by', 

102 ] 

103 

104 row_labels = { 

105 'product_scancode': "Scancode", 

106 'product_brand': "Brand", 

107 'product_description': "Description", 

108 'product_size': "Size", 

109 'order_uom': "Order UOM", 

110 } 

111 

112 row_grid_columns = [ 

113 'sequence', 

114 'product_scancode', 

115 'product_brand', 

116 'product_description', 

117 'product_size', 

118 'special_order', 

119 'unit_price_quoted', 

120 'case_size', 

121 'case_price_quoted', 

122 'order_qty', 

123 'order_uom', 

124 'discount_percent', 

125 'total_price', 

126 'status_code', 

127 ] 

128 

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

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

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

132 

133 def get_batch_handler(self): 

134 """ """ 

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

136 return NewOrderBatchHandler(self.config) 

137 

138 def configure_grid(self, g): 

139 """ """ 

140 super().configure_grid(g) 

141 

142 # store_id 

143 if not self.order_handler.expose_store_id(): 

144 g.remove('store_id') 

145 

146 # total_price 

147 g.set_renderer('total_price', 'currency') 

148 

149 def configure_form(self, f): 

150 """ """ 

151 super().configure_form(f) 

152 

153 # store_id 

154 if not self.order_handler.expose_store_id(): 

155 f.remove('store_id') 

156 

157 # local_customer 

158 f.set_node('local_customer', LocalCustomerRef(self.request)) 

159 

160 # pending_customer 

161 f.set_node('pending_customer', PendingCustomerRef(self.request)) 

162 

163 # total_price 

164 f.set_node('total_price', WuttaMoney(self.request)) 

165 

166 def configure_row_grid(self, g): 

167 """ """ 

168 super().configure_row_grid(g) 

169 enum = self.app.enum 

170 

171 # TODO 

172 # order_uom 

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

174 

175 # unit_price_quoted 

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

177 g.set_renderer('unit_price_quoted', 'currency') 

178 

179 # case_price_quoted 

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

181 g.set_renderer('case_price_quoted', 'currency') 

182 

183 # discount_percent 

184 g.set_renderer('discount_percent', 'percent') 

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

186 

187 # total_price 

188 g.set_renderer('total_price', 'currency') 

189 

190 def get_xref_buttons(self, batch): 

191 """ 

192 Adds "View this Order" button, if batch has been executed and 

193 a corresponding :class:`~sideshow.db.model.orders.Order` can 

194 be located. 

195 """ 

196 buttons = super().get_xref_buttons(batch) 

197 model = self.app.model 

198 session = self.Session() 

199 

200 if batch.executed and self.request.has_perm('orders.view'): 

201 order = session.query(model.Order)\ 

202 .filter(model.Order.order_id == batch.id)\ 

203 .first() 

204 if order: 

205 url = self.request.route_url('orders.view', uuid=order.uuid) 

206 buttons.append( 

207 self.make_button("View the Order", primary=True, icon_left='eye', url=url)) 

208 

209 return buttons 

210 

211 

212def defaults(config, **kwargs): 

213 base = globals() 

214 

215 NewOrderBatchView = kwargs.get('NewOrderBatchView', base['NewOrderBatchView']) 

216 NewOrderBatchView.defaults(config) 

217 

218 

219def includeme(config): 

220 defaults(config)