2
2
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
3
3
4
4
from odoo import api , fields
5
- from odoo .tests import common
5
+ from odoo .tests . common import TransactionCase
6
6
7
7
8
- class TestComponentOperation (common . SavepointCase ):
8
+ class TestComponentOperation (TransactionCase ):
9
9
@classmethod
10
10
def setUpClass (cls ):
11
11
super ().setUpClass ()
@@ -14,7 +14,6 @@ def setUpClass(cls):
14
14
cls .ProcurementGroup = cls .env ["procurement.group" ]
15
15
cls .MrpProduction = cls .env ["mrp.production" ]
16
16
cls .env .user .company_id .manufacturing_lead = 0
17
- cls .env .user .tz = False # Make sure there's no timezone in user
18
17
19
18
cls .picking_type = cls .env ["stock.picking.type" ].search (
20
19
[
@@ -30,7 +29,6 @@ def setUpClass(cls):
30
29
(6 , 0 , [cls .env .ref ("mrp.route_warehouse0_manufacture" ).id ])
31
30
],
32
31
"type" : "product" ,
33
- "produce_delay" : 0 ,
34
32
}
35
33
)
36
34
cls .product2 = cls .env ["product.product" ].create (
@@ -43,6 +41,7 @@ def setUpClass(cls):
43
41
{
44
42
"product_id" : cls .product1 .id ,
45
43
"product_tmpl_id" : cls .product1 .product_tmpl_id .id ,
44
+ "produce_delay" : 0 ,
46
45
"type" : "normal" ,
47
46
"bom_line_ids" : [
48
47
(0 , 0 , {"product_id" : cls .product2 .id , "product_qty" : 2 }),
@@ -56,7 +55,7 @@ def setUpClass(cls):
56
55
)
57
56
cls .warehouse .manufacture_steps = "pbm"
58
57
cls .ressuply_loc1 = cls .warehouse .lot_stock_id
59
- cls .source_location = cls .env . ref ( "stock.stock_location_stock" )
58
+ cls .manufacture_location = cls .warehouse . pbm_loc_id
60
59
cls .destination_location = cls .env .ref ("stock.stock_location_output" )
61
60
stock_location_locations_virtual = cls .env ["stock.location" ].create (
62
61
{"name" : "Virtual Locations" , "usage" : "view" , "posz" : 1 }
@@ -69,15 +68,15 @@ def setUpClass(cls):
69
68
"usage" : "inventory" ,
70
69
}
71
70
)
72
- cls .source_route = cls .env ["stock.location. route" ].create (
71
+ cls .source_route = cls .env ["stock.route" ].create (
73
72
{
74
73
"name" : "Source Route" ,
75
74
"mo_component_selectable" : True ,
76
75
"sequence" : 10 ,
77
76
}
78
77
)
79
78
80
- cls .destination_route = cls .env ["stock.location. route" ].create (
79
+ cls .destination_route = cls .env ["stock.route" ].create (
81
80
{
82
81
"name" : "Destination Route" ,
83
82
"mo_component_selectable" : True ,
@@ -90,7 +89,7 @@ def setUpClass(cls):
90
89
"name" : "Transfer" ,
91
90
"route_id" : cls .source_route .id ,
92
91
"location_src_id" : cls .ressuply_loc1 .id ,
93
- "location_id " : cls .source_location .id ,
92
+ "location_dest_id " : cls .manufacture_location .id ,
94
93
"action" : "pull" ,
95
94
"picking_type_id" : cls .warehouse .int_type_id .id ,
96
95
"procure_method" : "make_to_stock" ,
@@ -102,8 +101,8 @@ def setUpClass(cls):
102
101
{
103
102
"name" : "Transfer 2" ,
104
103
"route_id" : cls .destination_route .id ,
105
- "location_src_id" : cls .source_location .id ,
106
- "location_id " : cls .destination_location .id ,
104
+ "location_src_id" : cls .manufacture_location .id ,
105
+ "location_dest_id " : cls .destination_location .id ,
107
106
"action" : "pull" ,
108
107
"picking_type_id" : cls .warehouse .int_type_id .id ,
109
108
"procure_method" : "make_to_stock" ,
@@ -117,7 +116,7 @@ def setUpClass(cls):
117
116
"name" : "Operation Scrap and Replace" ,
118
117
"incoming_operation" : "replace" ,
119
118
"outgoing_operation" : "scrap" ,
120
- "source_location_id " : cls .source_location .id ,
119
+ "manufacture_location_id " : cls .manufacture_location .id ,
121
120
"source_route_id" : cls .source_route .id ,
122
121
"scrap_location_id" : cls .scrapped_location .id ,
123
122
}
@@ -128,7 +127,7 @@ def setUpClass(cls):
128
127
"name" : "Operation Scrap and Replace" ,
129
128
"incoming_operation" : "no" ,
130
129
"outgoing_operation" : "no" ,
131
- "source_location_id " : cls .source_location .id ,
130
+ "manufacture_location_id " : cls .manufacture_location .id ,
132
131
}
133
132
)
134
133
@@ -137,7 +136,7 @@ def setUpClass(cls):
137
136
"name" : "Operation Move" ,
138
137
"incoming_operation" : "replace" ,
139
138
"outgoing_operation" : "move" ,
140
- "source_location_id " : cls .source_location .id ,
139
+ "manufacture_location_id " : cls .manufacture_location .id ,
141
140
"source_route_id" : cls .source_route .id ,
142
141
"destination_location_id" : cls .destination_location .id ,
143
142
"destination_route_id" : cls .destination_route .id ,
@@ -149,17 +148,17 @@ def _do_picking(cls, picking):
149
148
picking .action_assign ()
150
149
date = fields .Datetime .now ()
151
150
picking .action_confirm ()
152
- picking .move_lines . quantity_done = picking . move_lines . product_uom_qty
151
+ picking .move_ids . picked = True
153
152
picking ._action_done ()
154
- for move in picking .move_lines :
153
+ for move in picking .move_ids :
155
154
move .date = date
156
155
157
156
def test_01_scrap_and_replace (self ):
158
157
nb_product_todo = 5
159
158
serials_p2 = []
160
159
for i in range (nb_product_todo ):
161
160
serials_p2 .append (
162
- self .env ["stock.production. lot" ].create (
161
+ self .env ["stock.lot" ].create (
163
162
{
164
163
"name" : f"lot_consumed_2_{ i } " ,
165
164
"product_id" : self .product3 .id ,
@@ -180,20 +179,21 @@ def test_01_scrap_and_replace(self):
180
179
"product_qty" : 2 ,
181
180
"product_uom_id" : self .product1 .uom_id .id ,
182
181
"date_deadline" : "2023-01-01 15:00:00" ,
183
- "date_planned_start " : "2023-01-01 15:00:00" ,
182
+ "date_start " : "2023-01-01 15:00:00" ,
184
183
}
185
184
)
186
- mo ._onchange_move_raw ()
187
- mo ._onchange_move_finished ()
188
185
mo .action_confirm ()
186
+ picking = mo .move_raw_ids .move_orig_ids .picking_id
187
+ picking .move_ids .write ({"picked" : True })
188
+ picking .button_validate ()
189
189
mo .action_assign ()
190
190
move_product_2 = mo .move_raw_ids .filtered (
191
191
lambda m : m .product_id == self .product2
192
192
)
193
193
raw_move_product_3 = mo .move_raw_ids .filtered (
194
194
lambda m : m .product_id == self .product3
195
195
)
196
- self .assertEqual (move_product_2 .move_line_ids .product_uom_qty , 4 )
196
+ self .assertEqual (move_product_2 .move_line_ids .quantity_product_uom , 4 )
197
197
self .assertEqual (len (raw_move_product_3 .move_line_ids ), 2 )
198
198
lot = raw_move_product_3 .move_line_ids [0 ].lot_id
199
199
wizard = self .env ["mrp.component.operate" ].create (
@@ -205,29 +205,28 @@ def test_01_scrap_and_replace(self):
205
205
}
206
206
)
207
207
self .assertEqual (wizard .product_qty , 1 )
208
+ old_pickings = mo .picking_ids
208
209
wizard .action_operate_component ()
209
- self . assertEqual ( len ( mo .picking_ids ), 1 )
210
+ new_pickings = mo .picking_ids - old_pickings
210
211
self .assertEqual (mo .scrap_ids .product_id , self .product3 )
211
212
self .assertEqual (mo .scrap_ids .lot_id , lot )
212
213
self .assertEqual (mo .scrap_ids .state , "done" )
213
214
self .assertEqual (len (raw_move_product_3 .move_line_ids ), 1 )
214
- self .assertEqual (len (raw_move_product_3 .move_orig_ids .move_line_ids ), 0 )
215
- self .assertEqual (mo .picking_ids .product_id , self .product3 )
216
- self ._do_picking (mo .picking_ids )
217
- self .assertEqual (mo .picking_ids .state , "done" )
215
+ self ._do_picking (new_pickings )
216
+ self .assertEqual (new_pickings .state , "done" )
218
217
self .assertEqual (
219
218
len (raw_move_product_3 .move_line_ids ),
220
219
2 ,
221
220
"Two lines, the operated one and the other one. (2 units required)" ,
222
221
)
223
- self .assertEqual (len (raw_move_product_3 .move_orig_ids .move_line_ids ), 1 )
222
+ self .assertEqual (len (raw_move_product_3 .move_orig_ids [ - 1 ] .move_line_ids ), 1 )
224
223
225
224
def test_02_move_and_replace (self ):
226
225
nb_product_todo = 5
227
226
serials_p2 = []
228
227
for i in range (nb_product_todo ):
229
228
serials_p2 .append (
230
- self .env ["stock.production. lot" ].create (
229
+ self .env ["stock.lot" ].create (
231
230
{
232
231
"name" : f"lot_consumed_2_{ i } " ,
233
232
"product_id" : self .product3 .id ,
@@ -248,12 +247,13 @@ def test_02_move_and_replace(self):
248
247
"product_qty" : 1 ,
249
248
"product_uom_id" : self .product1 .uom_id .id ,
250
249
"date_deadline" : "2023-01-01 15:00:00" ,
251
- "date_planned_start " : "2023-01-01 15:00:00" ,
250
+ "date_start " : "2023-01-01 15:00:00" ,
252
251
}
253
252
)
254
- mo ._onchange_move_raw ()
255
- mo ._onchange_move_finished ()
256
253
mo .action_confirm ()
254
+ picking = mo .move_raw_ids .move_orig_ids .picking_id
255
+ picking .move_ids .write ({"picked" : True })
256
+ picking .button_validate ()
257
257
mo .action_assign ()
258
258
self .assertEqual (len (mo .move_raw_ids ), 2 )
259
259
move_product_2 = mo .move_raw_ids .filtered (
@@ -262,10 +262,9 @@ def test_02_move_and_replace(self):
262
262
raw_move_product_3 = mo .move_raw_ids .filtered (
263
263
lambda m : m .product_id == self .product3
264
264
)
265
- self .assertEqual (move_product_2 .move_line_ids .product_uom_qty , 2 )
265
+ self .assertEqual (move_product_2 .move_line_ids .quantity_product_uom , 2 )
266
266
self .assertEqual (len (raw_move_product_3 .move_line_ids ), 1 )
267
267
lot = raw_move_product_3 .move_line_ids [0 ].lot_id
268
- self .assertFalse (raw_move_product_3 .move_orig_ids )
269
268
wizard = self .env ["mrp.component.operate" ].create (
270
269
{
271
270
"product_id" : self .product3 .id ,
@@ -275,10 +274,12 @@ def test_02_move_and_replace(self):
275
274
}
276
275
)
277
276
self .assertEqual (wizard .product_qty , 1 )
278
- self .assertEqual (len (mo .picking_ids ), 0 )
277
+ old_pickings = mo .picking_ids
278
+ self .assertEqual (len (old_pickings ), 1 )
279
279
wizard .action_operate_component ()
280
- self .assertEqual (len (mo .picking_ids ), 2 )
281
- moves_for_replacement = mo .mapped ("picking_ids.move_lines" )
280
+ self .assertEqual (len (mo .picking_ids ), 3 )
281
+ new_pickings = mo .picking_ids - old_pickings
282
+ moves_for_replacement = new_pickings .mapped ("move_ids" )
282
283
self .assertEqual (len (moves_for_replacement ), 2 )
283
284
for move in moves_for_replacement :
284
285
self .assertEqual (
@@ -290,16 +291,15 @@ def test_02_move_and_replace(self):
290
291
)
291
292
self .assertTrue (replacement_first_move )
292
293
replacement_second_move = moves_for_replacement .filtered (
293
- lambda m : m .location_dest_id == self .source_location
294
+ lambda m : m .location_dest_id == self .manufacture_location
294
295
)
295
296
self .assertTrue (replacement_second_move )
296
297
self .assertEqual (
297
298
len (raw_move_product_3 .move_line_ids ),
298
299
0 ,
299
300
"Reservation for product3 should have been cleared" ,
300
301
)
301
- self .assertEqual (raw_move_product_3 .move_orig_ids , replacement_second_move )
302
- self .assertEqual (len (replacement_second_move .move_line_ids ), 0 )
302
+ self .assertEqual (raw_move_product_3 .move_orig_ids [- 1 ], replacement_second_move )
303
303
self ._do_picking (replacement_first_move .picking_id )
304
304
self .assertEqual (replacement_first_move .state , "done" )
305
305
self .assertEqual (replacement_first_move .move_line_ids .lot_id , lot )
@@ -308,7 +308,6 @@ def test_02_move_and_replace(self):
308
308
0 ,
309
309
"raw move for product 3 still not reserved." ,
310
310
)
311
- self .assertEqual (len (replacement_second_move .move_line_ids ), 0 )
312
311
self ._do_picking (replacement_second_move .picking_id )
313
312
self .assertEqual (replacement_second_move .state , "done" )
314
313
self .assertEqual (replacement_first_move .product_id , self .product3 )
@@ -320,7 +319,7 @@ def test_03_nothing_and_nothing(self):
320
319
serials_p2 = []
321
320
for i in range (nb_product_todo ):
322
321
serials_p2 .append (
323
- self .env ["stock.production. lot" ].create (
322
+ self .env ["stock.lot" ].create (
324
323
{
325
324
"name" : f"lot_consumed_2_{ i } " ,
326
325
"product_id" : self .product3 .id ,
@@ -341,20 +340,21 @@ def test_03_nothing_and_nothing(self):
341
340
"product_qty" : 2 ,
342
341
"product_uom_id" : self .product1 .uom_id .id ,
343
342
"date_deadline" : "2023-01-01 15:00:00" ,
344
- "date_planned_start " : "2023-01-01 15:00:00" ,
343
+ "date_start " : "2023-01-01 15:00:00" ,
345
344
}
346
345
)
347
- mo ._onchange_move_raw ()
348
- mo ._onchange_move_finished ()
349
346
mo .action_confirm ()
347
+ picking = mo .move_raw_ids .move_orig_ids .picking_id
348
+ picking .move_ids .write ({"picked" : True })
349
+ picking .button_validate ()
350
350
mo .action_assign ()
351
351
move_product_2 = mo .move_raw_ids .filtered (
352
352
lambda m : m .product_id == self .product2
353
353
)
354
354
raw_move_product_3 = mo .move_raw_ids .filtered (
355
355
lambda m : m .product_id == self .product3
356
356
)
357
- self .assertEqual (move_product_2 .move_line_ids .product_uom_qty , 4 )
357
+ self .assertEqual (move_product_2 .move_line_ids .quantity_product_uom , 4 )
358
358
self .assertEqual (len (raw_move_product_3 .move_line_ids ), 2 )
359
359
wizard = self .env ["mrp.component.operate" ].create (
360
360
{
@@ -367,6 +367,5 @@ def test_03_nothing_and_nothing(self):
367
367
self .assertEqual (wizard .product_qty , 1 )
368
368
self .assertEqual (wizard .product_id , self .product3 )
369
369
wizard .action_operate_component ()
370
- self .assertEqual (len (mo .picking_ids ), 0 )
371
- self .assertEqual (move_product_2 .move_line_ids .product_uom_qty , 4 )
370
+ self .assertEqual (move_product_2 .move_line_ids .quantity_product_uom , 4 )
372
371
self .assertEqual (len (mo .move_raw_ids [1 ].move_line_ids ), 2 )
0 commit comments