@@ -12,6 +12,7 @@ class TestSaleDropshippingFlows(TestMrpSubcontractingCommon):
12
12
def setUpClass (cls ):
13
13
super ().setUpClass ()
14
14
15
+ cls .supplier = cls .env ["res.partner" ].create ({"name" : "Supplier" })
15
16
cls .customer = cls .env ["res.partner" ].create ({"name" : "Customer" })
16
17
cls .dropship_route = cls .env .ref ('stock_dropshipping.route_drop_shipping' )
17
18
@@ -71,3 +72,181 @@ def test_dropship_with_different_suppliers(self):
71
72
# Cancel the second one
72
73
sale_order .picking_ids [1 ].action_cancel ()
73
74
self .assertEqual (sale_order .order_line .qty_delivered , 1 )
75
+
76
+ def test_return_kit_and_delivered_qty (self ):
77
+ """
78
+ Sell a kit thanks to the dropshipping route, return it then deliver it again
79
+ The delivered quantity should be correctly computed
80
+ """
81
+ compo , kit = self .env ['product.product' ].create ([{
82
+ 'name' : n ,
83
+ 'type' : 'consu' ,
84
+ 'route_ids' : [(6 , 0 , [self .dropship_route .id ])],
85
+ 'seller_ids' : [(0 , 0 , {'name' : self .supplier .id })],
86
+ } for n in ['Compo' , 'Kit' ]])
87
+
88
+ self .env ['mrp.bom' ].create ({
89
+ 'product_tmpl_id' : kit .product_tmpl_id .id ,
90
+ 'product_qty' : 1 ,
91
+ 'type' : 'phantom' ,
92
+ 'bom_line_ids' : [
93
+ (0 , 0 , {'product_id' : compo .id , 'product_qty' : 1 }),
94
+ ],
95
+ })
96
+
97
+ sale_order = self .env ['sale.order' ].create ({
98
+ 'partner_id' : self .customer .id ,
99
+ 'picking_policy' : 'direct' ,
100
+ 'order_line' : [
101
+ (0 , 0 , {'name' : kit .name , 'product_id' : kit .id , 'product_uom_qty' : 1 }),
102
+ ],
103
+ })
104
+ sale_order .action_confirm ()
105
+ self .env ['purchase.order' ].search ([], order = 'id desc' , limit = 1 ).button_confirm ()
106
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 )
107
+
108
+ picking = sale_order .picking_ids
109
+ action = picking .button_validate ()
110
+ wizard = Form (self .env [action ['res_model' ]].with_context (action ['context' ])).save ()
111
+ wizard .process ()
112
+ self .assertEqual (sale_order .order_line .qty_delivered , 1.0 )
113
+
114
+ for case in ['return' , 'deliver again' ]:
115
+ delivered_before_case = 1.0 if case == 'return' else 0.0
116
+ delivered_after_case = 0.0 if case == 'return' else 1.0
117
+ return_form = Form (self .env ['stock.return.picking' ].with_context (active_ids = [picking .id ], active_id = picking .id , active_model = 'stock.picking' ))
118
+ return_wizard = return_form .save ()
119
+ action = return_wizard .create_returns ()
120
+ picking = self .env ['stock.picking' ].browse (action ['res_id' ])
121
+ self .assertEqual (sale_order .order_line .qty_delivered , delivered_before_case , "Incorrect delivered qty for case '%s'" % case )
122
+
123
+ action = picking .button_validate ()
124
+ wizard = Form (self .env [action ['res_model' ]].with_context (action ['context' ])).save ()
125
+ wizard .process ()
126
+ self .assertEqual (sale_order .order_line .qty_delivered , delivered_after_case , "Incorrect delivered qty for case '%s'" % case )
127
+
128
+ def test_partial_return_kit_and_delivered_qty (self ):
129
+ """
130
+ Suppose a kit with 4x the same dropshipped component
131
+ Suppose a complex delivery process:
132
+ - Deliver 2 (with backorder)
133
+ - Return 2
134
+ - Deliver 1 (with backorder)
135
+ - Deliver 1 (process "done")
136
+ - Deliver 1 (from the return)
137
+ - Deliver 1 (from the return)
138
+ The test checks the all-or-nothing policy of the delivered quantity
139
+ This quantity should be 1.0 after the last delivery
140
+ """
141
+ compo , kit = self .env ['product.product' ].create ([{
142
+ 'name' : n ,
143
+ 'type' : 'consu' ,
144
+ 'route_ids' : [(6 , 0 , [self .dropship_route .id ])],
145
+ 'seller_ids' : [(0 , 0 , {'name' : self .supplier .id })],
146
+ } for n in ['Compo' , 'Kit' ]])
147
+
148
+ self .env ['mrp.bom' ].create ({
149
+ 'product_tmpl_id' : kit .product_tmpl_id .id ,
150
+ 'product_qty' : 1 ,
151
+ 'type' : 'phantom' ,
152
+ 'bom_line_ids' : [
153
+ (0 , 0 , {'product_id' : compo .id , 'product_qty' : 4 }),
154
+ ],
155
+ })
156
+
157
+ sale_order = self .env ['sale.order' ].create ({
158
+ 'partner_id' : self .customer .id ,
159
+ 'picking_policy' : 'direct' ,
160
+ 'order_line' : [
161
+ (0 , 0 , {'name' : kit .name , 'product_id' : kit .id , 'product_uom_qty' : 1 }),
162
+ ],
163
+ })
164
+ sale_order .action_confirm ()
165
+ self .env ['purchase.order' ].search ([], order = 'id desc' , limit = 1 ).button_confirm ()
166
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 , "Delivered components: 0/4" )
167
+
168
+ picking01 = sale_order .picking_ids
169
+ picking01 .move_lines .quantity_done = 2
170
+ action = picking01 .button_validate ()
171
+ wizard = Form (self .env [action ['res_model' ]].with_context (action ['context' ])).save ()
172
+ wizard .process ()
173
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 , "Delivered components: 2/4" )
174
+
175
+ # Create a return of picking01 (with both components)
176
+ return_form = Form (self .env ['stock.return.picking' ].with_context (active_id = picking01 .id , active_model = 'stock.picking' ))
177
+ wizard = return_form .save ()
178
+ wizard .product_return_moves .write ({'quantity' : 2.0 })
179
+ res = wizard .create_returns ()
180
+ return01 = self .env ['stock.picking' ].browse (res ['res_id' ])
181
+
182
+ return01 .move_lines .quantity_done = 2
183
+ return01 .button_validate ()
184
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 , "Delivered components: 0/4" )
185
+
186
+ picking02 = picking01 .backorder_ids
187
+ picking02 .move_lines .quantity_done = 1
188
+ action = picking02 .button_validate ()
189
+ wizard = Form (self .env [action ['res_model' ]].with_context (action ['context' ])).save ()
190
+ wizard .process ()
191
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 , "Delivered components: 1/4" )
192
+
193
+ picking03 = picking02 .backorder_ids
194
+ picking03 .move_lines .quantity_done = 1
195
+ picking03 .button_validate ()
196
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 , "Delivered components: 2/4" )
197
+
198
+ # Create a return of return01 (with 1 component)
199
+ return_form = Form (self .env ['stock.return.picking' ].with_context (active_id = return01 .id , active_model = 'stock.picking' ))
200
+ wizard = return_form .save ()
201
+ wizard .product_return_moves .write ({'quantity' : 1.0 })
202
+ res = wizard .create_returns ()
203
+ picking04 = self .env ['stock.picking' ].browse (res ['res_id' ])
204
+
205
+ picking04 .move_lines .quantity_done = 1
206
+ picking04 .button_validate ()
207
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 , "Delivered components: 3/4" )
208
+
209
+ # Create a second return of return01 (with 1 component, the last one)
210
+ return_form = Form (self .env ['stock.return.picking' ].with_context (active_id = return01 .id , active_model = 'stock.picking' ))
211
+ wizard = return_form .save ()
212
+ wizard .product_return_moves .write ({'quantity' : 1.0 })
213
+ res = wizard .create_returns ()
214
+ picking04 = self .env ['stock.picking' ].browse (res ['res_id' ])
215
+
216
+ picking04 .move_lines .quantity_done = 1
217
+ picking04 .button_validate ()
218
+ self .assertEqual (sale_order .order_line .qty_delivered , 1 , "Delivered components: 4/4" )
219
+
220
+ def test_cancelled_picking_and_delivered_qty (self ):
221
+ """
222
+ The delivered quantity should be zero if all SM are cancelled
223
+ """
224
+ compo , kit = self .env ['product.product' ].create ([{
225
+ 'name' : n ,
226
+ 'type' : 'consu' ,
227
+ 'route_ids' : [(6 , 0 , [self .dropship_route .id ])],
228
+ 'seller_ids' : [(0 , 0 , {'name' : self .supplier .id })],
229
+ } for n in ['Compo' , 'Kit' ]])
230
+
231
+ self .env ['mrp.bom' ].create ({
232
+ 'product_tmpl_id' : kit .product_tmpl_id .id ,
233
+ 'product_qty' : 1 ,
234
+ 'type' : 'phantom' ,
235
+ 'bom_line_ids' : [
236
+ (0 , 0 , {'product_id' : compo .id , 'product_qty' : 1 }),
237
+ ],
238
+ })
239
+
240
+ sale_order = self .env ['sale.order' ].create ({
241
+ 'partner_id' : self .customer .id ,
242
+ 'picking_policy' : 'direct' ,
243
+ 'order_line' : [
244
+ (0 , 0 , {'name' : kit .name , 'product_id' : kit .id , 'product_uom_qty' : 1 }),
245
+ ],
246
+ })
247
+ sale_order .action_confirm ()
248
+ self .env ['purchase.order' ].search ([], order = 'id desc' , limit = 1 ).button_confirm ()
249
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 )
250
+
251
+ sale_order .picking_ids .action_cancel ()
252
+ self .assertEqual (sale_order .order_line .qty_delivered , 0.0 )
0 commit comments