Coverage for src/sideshow/web/views/batch/neworder.py: 0%

55 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-26 13:16 -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): 

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 get_batch_handler(self): 

130 """ """ 

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

132 return NewOrderBatchHandler(self.config) 

133 

134 def configure_grid(self, g): 

135 """ """ 

136 super().configure_grid(g) 

137 

138 # total_price 

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

140 

141 def configure_form(self, f): 

142 """ """ 

143 super().configure_form(f) 

144 

145 # local_customer 

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

147 

148 # pending_customer 

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

150 

151 # total_price 

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

153 

154 def configure_row_grid(self, g): 

155 """ """ 

156 super().configure_row_grid(g) 

157 enum = self.app.enum 

158 

159 # TODO 

160 # order_uom 

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

162 

163 # unit_price_quoted 

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

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

166 

167 # case_price_quoted 

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

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

170 

171 # discount_percent 

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

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

174 

175 # total_price 

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

177 

178 def get_xref_buttons(self, batch): 

179 """ 

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

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

182 be located. 

183 """ 

184 buttons = super().get_xref_buttons(batch) 

185 model = self.app.model 

186 session = self.Session() 

187 

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

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

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

191 .first() 

192 if order: 

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

194 buttons.append( 

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

196 

197 return buttons 

198 

199 

200def defaults(config, **kwargs): 

201 base = globals() 

202 

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

204 NewOrderBatchView.defaults(config) 

205 

206 

207def includeme(config): 

208 defaults(config)