Merge lp:~unifield-team/unifield-wm/us-311 into lp:unifield-wm
- us-311
- Merge into trunk
Proposed by
Quentin THEURET @Amaris
Status: | Merged |
---|---|
Merged at revision: | 2539 |
Proposed branch: | lp:~unifield-team/unifield-wm/us-311 |
Merge into: | lp:unifield-wm |
Diff against target: |
823 lines (+700/-11) 6 files modified
msf_outgoing/msf_outgoing.py (+3/-0) purchase_override/purchase.py (+2/-0) purchase_override/wizard/split_order_line.py (+9/-1) sale_override/sale.py (+4/-2) unifield_tests/tests/resourcing.py (+13/-8) unifield_tests/tests/test_us_311.py (+669/-0) |
To merge this branch: | bzr merge lp:~unifield-team/unifield-wm/us-311 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+261084@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 2537. By Quentin THEURET @Amaris
-
US-311 [FIX] Force check of state of the Internal request when the OUT is done
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'msf_outgoing/msf_outgoing.py' |
2 | --- msf_outgoing/msf_outgoing.py 2015-06-03 15:29:06 +0000 |
3 | +++ msf_outgoing/msf_outgoing.py 2015-06-04 14:18:29 +0000 |
4 | @@ -3199,6 +3199,9 @@ |
5 | delivered_pack = self.browse(cr, uid, delivered_pack_id, context=context) |
6 | res[picking.id] = {'delivered_picking': delivered_pack.id or False} |
7 | |
8 | + if picking.type == 'out' and picking.sale_id and picking.sale_id.procurement_request: |
9 | + wf_service.trg_write(uid, 'sale.order', picking.sale_id.id, cr) |
10 | + |
11 | return res |
12 | |
13 | @check_cp_rw |
14 | |
15 | === modified file 'purchase_override/purchase.py' |
16 | --- purchase_override/purchase.py 2015-05-29 15:29:07 +0000 |
17 | +++ purchase_override/purchase.py 2015-06-04 14:18:29 +0000 |
18 | @@ -1216,6 +1216,7 @@ |
19 | 'created_by_rfq_line': l.order_id.rfq_ok and l.id or False, |
20 | 'po_cft': l.order_id.rfq_ok and 'rfq' or 'po', |
21 | 'sync_sourced_origin': l.instance_sync_order_ref and l.instance_sync_order_ref.name or False, |
22 | + #'is_line_split': l.is_line_split, |
23 | 'name': '[%s] %s' % (l.product_id.default_code, l.product_id.name)} |
24 | |
25 | new_line_id = sol_obj.create(cr, uid, vals, context=context) |
26 | @@ -1444,6 +1445,7 @@ |
27 | 'nomen_sub_4': line.nomen_sub_4 and line.nomen_sub_4.id or False, |
28 | 'nomen_sub_5': line.nomen_sub_5 and line.nomen_sub_5.id or False, |
29 | 'confirmed_delivery_date': line_confirmed, |
30 | + #'is_line_split': line.is_line_split, |
31 | } |
32 | """ |
33 | UFTP-336: Update the analytic distribution at FO line when |
34 | |
35 | === modified file 'purchase_override/wizard/split_order_line.py' |
36 | --- purchase_override/wizard/split_order_line.py 2014-09-19 12:18:46 +0000 |
37 | +++ purchase_override/wizard/split_order_line.py 2015-06-04 14:18:29 +0000 |
38 | @@ -133,8 +133,16 @@ |
39 | 'so_back_update_dest_pol_id_sale_order_line': split.purchase_line_id.id, |
40 | } |
41 | new_so_line_id = so_line_obj.copy(cr, uid, split.corresponding_so_line_id_split_po_line_wizard.id, so_copy_data, context=dict(context, keepDateAndDistrib=True)) |
42 | + so_line_obj.write(cr, uid, new_so_line_id, { |
43 | + 'supplier': split.corresponding_so_line_id_split_po_line_wizard.supplier.id, |
44 | + 'type': 'make_to_order', |
45 | + 'is_line_split': True, |
46 | + }, context=context) |
47 | # change the initial qty on the initial FO line |
48 | - so_line_obj.write(cr, uid, split.corresponding_so_line_id_split_po_line_wizard.id, {'product_uom_qty': split.original_qty - split.new_line_qty, 'product_uos_qty': split.original_qty - split.new_line_qty}, context=dict(context, keepDateAndDistrib=True)) |
49 | + so_line_obj.write(cr, uid, split.corresponding_so_line_id_split_po_line_wizard.id, { |
50 | + 'product_uom_qty': split.original_qty - split.new_line_qty, |
51 | + 'product_uos_qty': split.original_qty - split.new_line_qty, |
52 | + }, context=dict(context, keepDateAndDistrib=True)) |
53 | # call the new procurement creation method |
54 | so_obj.action_ship_proc_create(cr, uid, [split.corresponding_so_id_split_po_line_wizard.id], context=context) |
55 | # run the procurement, the make_po function detects the link to original po |
56 | |
57 | === modified file 'sale_override/sale.py' |
58 | --- sale_override/sale.py 2015-05-29 15:29:07 +0000 |
59 | +++ sale_override/sale.py 2015-06-04 14:18:29 +0000 |
60 | @@ -2201,7 +2201,8 @@ |
61 | 'created_by_rfq_line': fields.many2one('purchase.order.line', string='Created by RfQ line'), |
62 | 'dpo_line_id': fields.many2one('purchase.order.line', string='DPO line'), |
63 | 'sync_sourced_origin': fields.char(string='Sync. Origin', size=256), |
64 | - 'cancel_split_ok': fields.boolean( |
65 | + 'cancel_split_ok': fields.float( |
66 | + digits=(16,2), |
67 | string='Cancel split', |
68 | help='If the line has been canceled/removed on the splitted FO', |
69 | ), |
70 | @@ -2313,7 +2314,8 @@ |
71 | pick_obj.validate(cr, uid, [pick.id]) |
72 | |
73 | if line.original_line_id: |
74 | - self.write(cr, uid, [line.original_line_id.id], {'cancel_split_ok': True}, context=context) |
75 | + cancel_split_qty = line.original_line_id.cancel_split_ok + line.product_uom_qty |
76 | + self.write(cr, uid, [line.original_line_id.id], {'cancel_split_ok': cancel_split_qty}, context=context) |
77 | |
78 | # UFTP-82: |
79 | # do not delete cancelled IR line from PO cancelled |
80 | |
81 | === modified file 'unifield_tests/tests/resourcing.py' |
82 | --- unifield_tests/tests/resourcing.py 2015-03-17 09:46:54 +0000 |
83 | +++ unifield_tests/tests/resourcing.py 2015-06-04 14:18:29 +0000 |
84 | @@ -293,23 +293,26 @@ |
85 | :param po_ids: List of ID of purchase.order to validate |
86 | :return The list of ID of purchase.order validated |
87 | """ |
88 | + po_obj = db.get('purchase.order') |
89 | + pol_obj = db.get('purchase.order.line') |
90 | + |
91 | # Add an analytic distribution on PO lines that have no |
92 | - no_ana_line_ids = self.pol_obj.search([ |
93 | + no_ana_line_ids = pol_obj.search([ |
94 | ('order_id', 'in', po_ids), |
95 | ('analytic_distribution_id', '=', False), |
96 | ]) |
97 | - self.pol_obj.write(no_ana_line_ids, { |
98 | + pol_obj.write(no_ana_line_ids, { |
99 | 'analytic_distribution_id': self.get_record(db, 'distrib_1'), |
100 | }) |
101 | |
102 | # Check if the PO is draft |
103 | for po_id in po_ids: |
104 | - po_state = self.po_obj.read(po_id, ['state'])['state'] |
105 | + po_state = po_obj.read(po_id, ['state'])['state'] |
106 | self.assert_(po_state == 'draft', msg=""" |
107 | The state of the generated PO is %s - Should be 'draft'""" % po_state) |
108 | # Validate the PO |
109 | db.exec_workflow('purchase.order', 'purchase_confirm', po_id) |
110 | - po_state = self.po_obj.browse(po_id).state |
111 | + po_state = po_obj.browse(po_id).state |
112 | self.assert_(po_state == 'confirmed', msg=""" |
113 | The state of the generated PO is %s - Should be 'confirmed'""" % po_state) |
114 | |
115 | @@ -325,16 +328,18 @@ |
116 | :param dcd: Delivery confirmed date to set |
117 | :return: The list of ID of purchase.order confirmed |
118 | """ |
119 | + po_obj = db.get('purchase.order') |
120 | + |
121 | if not dcd: |
122 | dcd = time.strftime('%Y-%m-%d') |
123 | |
124 | - self.po_obj.write(po_ids, {'delivery_confirmed_date': dcd}) |
125 | + po_obj.write(po_ids, {'delivery_confirmed_date': dcd}) |
126 | |
127 | for po_id in po_ids: |
128 | """ |
129 | 1/ Check if the PO are in 'confirmed' state |
130 | """ |
131 | - po_state = self.po_obj.read(po_id, ['state'])['state'] |
132 | + po_state = po_obj.read(po_id, ['state'])['state'] |
133 | self.assert_( |
134 | po_state == 'confirmed', |
135 | "The state of the generated PO is %s - Should be 'confirmed'" % po_state, |
136 | @@ -342,11 +347,11 @@ |
137 | """ |
138 | 2/ Confirm the PO |
139 | """ |
140 | - self.po_obj.confirm_button([po_id]) |
141 | + po_obj.confirm_button([po_id]) |
142 | """ |
143 | 3/ Check if all PO are now in 'approved' state |
144 | """ |
145 | - po_state = self.po_obj.read(po_id, ['state'])['state'] |
146 | + po_state = po_obj.read(po_id, ['state'])['state'] |
147 | self.assert_( |
148 | po_state == 'approved', |
149 | "The state of the generated PO is %s - Should be 'approved'" % po_state, |
150 | |
151 | === added file 'unifield_tests/tests/test_us_311.py' |
152 | --- unifield_tests/tests/test_us_311.py 1970-01-01 00:00:00 +0000 |
153 | +++ unifield_tests/tests/test_us_311.py 2015-06-04 14:18:29 +0000 |
154 | @@ -0,0 +1,669 @@ |
155 | +#!/usr/bin/env python |
156 | +# -*- coding: utf8 -*- |
157 | + |
158 | +__author__ = 'qt' |
159 | + |
160 | +from resourcing import ResourcingTest |
161 | + |
162 | + |
163 | +class US311Test(ResourcingTest): |
164 | + |
165 | + def setUp(self): |
166 | + """ |
167 | + 1/ Create an IR with two lines at project: |
168 | + * One with 18 PCE of product 1 |
169 | + * One with 25 PCE of product 2 |
170 | + 2/ Validate the IR |
171 | + 3/ Source all lines to the coordo |
172 | + 4/ Validate the PO |
173 | + 5/ Sync. |
174 | + 6/ At coordo, validate the FO |
175 | + 7/ Source the two lines to an external supplier |
176 | + 8/ On the generated PO, split the line of 25 PCE to two lines: |
177 | + * One line with 15 PCE |
178 | + * One line with 10 PCE |
179 | + """ |
180 | + super(US311Test, self).setUp() |
181 | + # Project objects mapper |
182 | + self.p_so_obj = self.p1.get('sale.order') |
183 | + self.p_sol_obj = self.p1.get('sale.order.line') |
184 | + self.p_po_obj = self.p1.get('purchase.order') |
185 | + self.p_pol_obj = self.p1.get('purchase.order.line') |
186 | + self.p_pick_obj = self.p1.get('stock.picking') |
187 | + self.p_move_obj = self.p1.get('stock.move') |
188 | + self.p_partner_obj = self.p1.get('res.partner') |
189 | + # Coordo objects mapper |
190 | + self.c_so_obj = self.c1.get('sale.order') |
191 | + self.c_sol_obj = self.c1.get('sale.order.line') |
192 | + self.c_po_obj = self.c1.get('purchase.order') |
193 | + self.c_pol_obj = self.c1.get('purchase.order.line') |
194 | + self.c_pick_obj = self.c1.get('stock.picking') |
195 | + self.c_move_obj = self.c1.get('stock.move') |
196 | + self.c_partner_obj = self.c1.get('res.partner') |
197 | + |
198 | + # Products |
199 | + self.p_prd1_id = self.get_record(self.p1, 'prod_log_1') |
200 | + self.p_prd2_id = self.get_record(self.p1, 'prod_log_2') |
201 | + self.p_prd3_id = self.get_record(self.p1, 'prod_log_3') |
202 | + self.c_prd1_id = self.get_record(self.c1, 'prod_log_1') |
203 | + self.c_prd2_id = self.get_record(self.c1, 'prod_log_2') |
204 | + self.c_prd3_id = self.get_record(self.c1, 'prod_log_3') |
205 | + |
206 | + # Get Project and Coordo partners |
207 | + project_name = self.get_db_partner_name(self.p1) |
208 | + coordo_name = self.get_db_partner_name(self.c1) |
209 | + c_proj_ids = self.c_partner_obj.search([('name', '=', project_name)]) |
210 | + p_coordo_ids = self.p_partner_obj.search([('name', '=', coordo_name)]) |
211 | + |
212 | + self.assert_( |
213 | + c_proj_ids, |
214 | + "No project partner found in Coordination", |
215 | + ) |
216 | + self.assert_( |
217 | + p_coordo_ids, |
218 | + "No coordination partner found in Project", |
219 | + ) |
220 | + self.c_prj_id = c_proj_ids[0] |
221 | + self.p_crd_id = p_coordo_ids[0] |
222 | + |
223 | + # Prepare values for IR |
224 | + uom_pce_id = self.get_record(self.p1, 'product_uom_unit', module='product') |
225 | + distrib_id = self.create_analytic_distribution(self.p1) |
226 | + |
227 | + """ |
228 | + 1/ Create an IR with two lines at project: |
229 | + * One with 18 PCE of product 1 |
230 | + * One with 25 PCE of product 2 |
231 | + """ |
232 | + ir_values = { |
233 | + 'procurement_request': True, |
234 | + 'location_requestor_id': self.get_record(self.p1, 'external_cu'), |
235 | + } |
236 | + self.p_ir_id = self.p_so_obj.create(ir_values) |
237 | + l1_values = { |
238 | + 'order_id': self.p_ir_id, |
239 | + 'product_id': self.p_prd1_id, |
240 | + 'product_uom': uom_pce_id, |
241 | + 'product_uom_qty': 18.00, |
242 | + 'type': 'make_to_order', |
243 | + 'price_unit': 1.00, |
244 | + } |
245 | + self.p_irl1_id = self.p_sol_obj.create(l1_values) |
246 | + |
247 | + l2_values = l1_values.copy() |
248 | + l2_values.update({ |
249 | + 'product_id': self.p_prd2_id, |
250 | + 'product_uom_qty': 25.00, |
251 | + }) |
252 | + self.p_irl2_id = self.p_sol_obj.create(l2_values) |
253 | + |
254 | + """ |
255 | + 2/ Validate the IR |
256 | + """ |
257 | + self.p1.exec_workflow('sale.order', 'procurement_validate', self.p_ir_id) |
258 | + |
259 | + """ |
260 | + 3/ Source all lines to the coordo |
261 | + """ |
262 | + self.p_sol_obj.write([self.p_irl1_id, self.p_irl2_id], { |
263 | + 'po_cft': 'po', |
264 | + 'supplier': self.p_crd_id, |
265 | + }) |
266 | + self.p_sol_obj.confirmLine([self.p_irl1_id, self.p_irl2_id]) |
267 | + |
268 | + # Run the scheduler |
269 | + self.p_ir_id = self.run_auto_pos_creation(self.p1, order_to_check=self.p_ir_id) |
270 | + line_ids = self.p_sol_obj.search([('order_id', '=', self.p_ir_id)]) |
271 | + not_sourced = True |
272 | + while not_sourced: |
273 | + not_sourced = False |
274 | + for line in self.p_sol_obj.browse(line_ids): |
275 | + if line.procurement_id.state != 'running': |
276 | + not_source = True |
277 | + if not_sourced: |
278 | + time.sleep(1) |
279 | + |
280 | + po_ids = set() |
281 | + po_line_ids = [] |
282 | + for line in self.p_sol_obj.browse(line_ids): |
283 | + po_line_ids.extend(self.p_pol_obj.search([ |
284 | + ('procurement_id', '=', line.procurement_id.id), |
285 | + ])) |
286 | + |
287 | + for po_line in self.p_pol_obj.read(po_line_ids, ['order_id']): |
288 | + po_ids.add(po_line['order_id'][0]) |
289 | + |
290 | + self.p_po_id = po_ids and list(po_ids)[0] or False |
291 | + self.p_po_name = self.p_po_obj.read(self.p_po_id, ['name'])['name'] |
292 | + |
293 | + """ |
294 | + 4/ Validate the PO |
295 | + """ |
296 | + self._validate_po(self.p1, [self.p_po_id]) |
297 | + |
298 | + """ |
299 | + 5/ Sync. |
300 | + """ |
301 | + self.synchronize(self.p1) |
302 | + self.synchronize(self.c1) |
303 | + |
304 | + """ |
305 | + 6/ At coordo, validate the FO |
306 | + """ |
307 | + self.c_fo_id = None |
308 | + self.c_fo_ids = self.c_so_obj.search([('client_order_ref', 'like', self.p_po_name)]) |
309 | + for c_fo_id in self.c_fo_ids: |
310 | + self.assert_( |
311 | + self.c_so_obj.read(c_fo_id, ['state'])['state'] == 'draft', |
312 | + "The FO at Coordo is not 'Draft'.", |
313 | + ) |
314 | + self.c_fo_id = c_fo_id |
315 | + |
316 | + # Validate the Field order |
317 | + self.c1.exec_workflow('sale.order', 'order_validated', self.c_fo_id) |
318 | + |
319 | + """ |
320 | + 7/ Source the two lines to an external supplier |
321 | + """ |
322 | + line_ids = self.c_sol_obj.search([('order_id', '=', self.c_fo_id)]) |
323 | + self.c_sol_obj.write(line_ids, { |
324 | + 'type': 'make_to_order', |
325 | + 'po_cft': 'po', |
326 | + 'supplier': self.get_record(self.c1, 'ext_supplier_1'), |
327 | + }) |
328 | + self.c_sol_obj.confirmLine(line_ids) |
329 | + |
330 | + # Get the generated PO |
331 | + self.c_fo_id = self.run_auto_pos_creation(self.c1, order_to_check=self.c_fo_id) |
332 | + line_ids = self.c_sol_obj.search([('order_id', '=', self.c_fo_id)]) |
333 | + po_ids = set() |
334 | + po_line_ids = [] |
335 | + self.c_pol_18 = None |
336 | + self.c_pol_25 = None |
337 | + self.c_pol_10 = None |
338 | + self.c_pol_15 = None |
339 | + for line in self.c_sol_obj.browse(line_ids): |
340 | + if line.procurement_id: |
341 | + po_line_ids.extend(self.c_pol_obj.search([ |
342 | + ('procurement_id', '=', line.procurement_id.id), |
343 | + ])) |
344 | + for po_line in self.c_pol_obj.read(po_line_ids, ['order_id', 'product_qty']): |
345 | + po_ids.add(po_line['order_id'][0]) |
346 | + self.c_po_id = po_line['order_id'][0] |
347 | + if po_line['product_qty'] == 18.00: |
348 | + self.c_pol_18 = po_line['id'] |
349 | + elif po_line['product_qty'] == 25.00: |
350 | + self.c_pol_25 = po_line['id'] |
351 | + |
352 | + self.assert_( |
353 | + self.c_pol_18, |
354 | + "Line with 18 PCE not found on PO", |
355 | + ) |
356 | + self.assert_( |
357 | + self.c_pol_25, |
358 | + "Line with 25 PCE not found on PO", |
359 | + ) |
360 | + |
361 | + """ |
362 | + 8/ On the generated PO, split the line of 25 PCE to two lines: |
363 | + * One line with 15 PCE |
364 | + * One line with 10 PCE |
365 | + """ |
366 | + split_obj = self.c1.get('split.purchase.order.line.wizard') |
367 | + split_id = split_obj.create({ |
368 | + 'purchase_line_id': self.c_pol_25, |
369 | + 'original_qty': 25.00, |
370 | + 'old_line_qty': 10.00, |
371 | + 'new_line_qty': 15.00, |
372 | + }) |
373 | + split_obj.split_line([split_id]) |
374 | + |
375 | + line_ids = self.c_pol_obj.search([('order_id', 'in', list(po_ids))]) |
376 | + for pol in self.c_pol_obj.browse(line_ids): |
377 | + if pol.product_qty == 18.00: |
378 | + self.c_pol_18 = pol.id |
379 | + elif pol.product_qty == 10.00: |
380 | + self.c_pol_10 = pol.id |
381 | + elif pol.product_qty == 15.00: |
382 | + self.c_pol_15 = pol.id |
383 | + |
384 | + self.assert_( |
385 | + self.c_pol_18 and self.c_pol_10 and self.c_pol_15, |
386 | + "Not all needed PO lines are found", |
387 | + ) |
388 | + |
389 | + def tearDown(self): |
390 | + """ |
391 | + """ |
392 | + super(US311Test, self).tearDown() |
393 | + |
394 | + def run_flow(self): |
395 | + """ |
396 | + Confirm the PO, then process the IN and the P/P/S at Coordo |
397 | + Sync |
398 | + """ |
399 | + # Validate the PO |
400 | + self._validate_po(self.c1, [self.c_po_id]) |
401 | + |
402 | + # Confirm the PO |
403 | + self._confirm_po(self.c1, [self.c_po_id]) |
404 | + |
405 | + # Process the IN |
406 | + c_in_ids = self.c_pick_obj.search([('purchase_id', '=', self.c_po_id), ('type', '=', 'in')]) |
407 | + self.assert_( |
408 | + len(c_in_ids) == 1, |
409 | + "There are %s IN association to PO - Should be 1" % len(c_in_ids), |
410 | + ) |
411 | + proc_obj = self.c1.get('stock.incoming.processor') |
412 | + proc_res = self.c_pick_obj.action_process(c_in_ids) |
413 | + proc_id = proc_res.get('res_id') |
414 | + proc_obj.copy_all([proc_id]) |
415 | + proc_obj.do_incoming_shipment([proc_id]) |
416 | + |
417 | + # Process P/P/S |
418 | + c_out_ids = self.c_pick_obj.search([('sale_id', '=', self.c_fo_id), ('type', '=', 'out'), ('state', '=', 'assigned')]) |
419 | + self.assert_( |
420 | + len(c_out_ids) == 1, |
421 | + "There are %s OUT/PICK associated to FO - Should be 1" % len(c_out_ids), |
422 | + ) |
423 | + out_proc_obj = self.c1.get('outgoing.delivery.processor') |
424 | + conv_res = self.c_pick_obj.convert_to_standard(c_out_ids) |
425 | + out_id = conv_res.get('res_id') |
426 | + proc_res = self.c_pick_obj.action_process([out_id]) |
427 | + out_proc_obj.copy_all([proc_res.get('res_id')]) |
428 | + out_proc_obj.do_partial([proc_res.get('res_id')]) |
429 | + |
430 | + self.synchronize(self.c1) |
431 | + self.synchronize(self.p1) |
432 | + |
433 | + def close_flow(self): |
434 | + """ |
435 | + Process the IN and the OUT at project |
436 | + """ |
437 | + # Process the IN |
438 | + proc_obj = self.p1.get('stock.incoming.processor') |
439 | + for in_id in self.p_in_ids: |
440 | + proc_res = self.p_pick_obj.action_process([in_id]) |
441 | + proc_id = proc_res.get('res_id') |
442 | + proc_obj.copy_all([proc_id]) |
443 | + proc_obj.do_incoming_shipment([proc_id]) |
444 | + |
445 | + # Process the OUT |
446 | + out_proc_obj = self.p1.get('outgoing.delivery.processor') |
447 | + for out_id in self.out_ids: |
448 | + proc_res = self.p_pick_obj.action_process([out_id]) |
449 | + out_proc_obj.copy_all([proc_res.get('res_id')]) |
450 | + out_proc_obj.do_partial([proc_res.get('res_id')]) |
451 | + |
452 | + self.assert_( |
453 | + self.p_so_obj.browse(self.p_ir_id).state == 'done', |
454 | + "The Internal request is not Closed", |
455 | + ) |
456 | + |
457 | + def test_cancel_new_splitted_line(self): |
458 | + """ |
459 | + Cancel the new line after the split, confirm the PO, process the IN and the P/P/S |
460 | + at coordo, then sync. |
461 | + At project, check the number of lines in OUT. |
462 | + Process the IN and the OUT. |
463 | + """ |
464 | + # Cancel the PO line |
465 | + res = self.c_pol_obj.ask_unlink(self.c_pol_15) |
466 | + self.assert_( |
467 | + res.get('res_id', False) and res.get('res_model', False) == 'purchase.order.line.unlink.wizard', |
468 | + "There is no wizard displayed when cancel a PO line that sources a FO/IR line", |
469 | + ) |
470 | + w_res = self.c1.get('purchase.order.line.unlink.wizard').just_cancel(res.get('res_id')) |
471 | + |
472 | + self.run_flow() |
473 | + |
474 | + # Check IR quantities |
475 | + prd1_qty = 0.00 |
476 | + prd2_qty = 0.00 |
477 | + for line in self.p_so_obj.browse(self.p_ir_id).order_line: |
478 | + if line.state == 'done': |
479 | + continue |
480 | + if line.product_id.id == self.p_prd1_id: |
481 | + prd1_qty += line.product_uom_qty |
482 | + elif line.product_id.id == self.p_prd2_id: |
483 | + prd2_qty += line.product_uom_qty |
484 | + |
485 | + self.assert_( |
486 | + prd1_qty == 18.00 and prd2_qty == 10.00, |
487 | + "The quantities on IR moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
488 | + ) |
489 | + |
490 | + # Check IN quantities |
491 | + prd1_qty = 0.00 |
492 | + prd2_qty = 0.00 |
493 | + ir_name = self.p_so_obj.read(self.p_ir_id, ['name'])['name'] |
494 | + self.p_in_ids = self.p_pick_obj.search([ |
495 | + ('type', '=', 'in'), |
496 | + ('origin', 'like', ir_name), |
497 | + ]) |
498 | + for pick in self.p_pick_obj.browse(self.p_in_ids): |
499 | + for move in pick.move_lines: |
500 | + if move.product_id.id == self.p_prd1_id: |
501 | + prd1_qty += move.product_qty |
502 | + elif move.product_id.id == self.p_prd2_id: |
503 | + prd2_qty += move.product_qty |
504 | + |
505 | + self.assert_( |
506 | + prd1_qty == 18.00 and prd2_qty == 10.00, |
507 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
508 | + ) |
509 | + |
510 | + # Check OUT quantities |
511 | + prd1_qty = 0.00 |
512 | + prd2_qty = 0.00 |
513 | + self.out_ids = self.p_pick_obj.search([('sale_id', '=', self.p_ir_id), ('type', '=', 'out')]) |
514 | + for pick in self.p_pick_obj.browse(self.out_ids): |
515 | + for move in pick.move_lines: |
516 | + if move.product_id.id == self.p_prd1_id: |
517 | + prd1_qty += move.product_qty |
518 | + elif move.product_id.id == self.p_prd2_id: |
519 | + prd2_qty += move.product_qty |
520 | + |
521 | + self.assert_( |
522 | + prd1_qty == 18.00 and prd2_qty == 10.00, |
523 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
524 | + ) |
525 | + |
526 | + self.close_flow() |
527 | + |
528 | + def test_cancel_all_splitted_lines(self): |
529 | + """ |
530 | + Cancel the splitted line, confirm the PO, process the IN and the P/P/S |
531 | + at coordo, then sync. |
532 | + At project, check the number of lines in OUT. |
533 | + Process the IN and the OUT. |
534 | + """ |
535 | + # Cancel the PO lines |
536 | + res = self.c_pol_obj.ask_unlink(self.c_pol_10) |
537 | + self.assert_( |
538 | + res.get('res_id', False) and res.get('res_model', False) == 'purchase.order.line.unlink.wizard', |
539 | + "There is no wizard displayed when cancel a PO line that sources a FO/IR line", |
540 | + ) |
541 | + w_res = self.c1.get('purchase.order.line.unlink.wizard').just_cancel(res.get('res_id')) |
542 | + res = self.c_pol_obj.ask_unlink(self.c_pol_15) |
543 | + self.assert_( |
544 | + res.get('res_id', False) and res.get('res_model', False) == 'purchase.order.line.unlink.wizard', |
545 | + "There is no wizard displayed when cancel a PO line that sources a FO/IR line", |
546 | + ) |
547 | + w_res = self.c1.get('purchase.order.line.unlink.wizard').just_cancel(res.get('res_id')) |
548 | + |
549 | + self.run_flow() |
550 | + |
551 | + # Check IR quantities |
552 | + prd1_qty = 0.00 |
553 | + prd2_qty = 0.00 |
554 | + for line in self.p_so_obj.browse(self.p_ir_id).order_line: |
555 | + if line.state == 'done': |
556 | + continue |
557 | + if line.product_id.id == self.p_prd1_id: |
558 | + prd1_qty += line.product_uom_qty |
559 | + elif line.product_id.id == self.p_prd2_id: |
560 | + prd2_qty += line.product_uom_qty |
561 | + |
562 | + self.assert_( |
563 | + prd1_qty == 18.00 and prd2_qty == 0.00, |
564 | + "The quantities on IR moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
565 | + ) |
566 | + |
567 | + # Check IN quantities |
568 | + prd1_qty = 0.00 |
569 | + prd2_qty = 0.00 |
570 | + ir_name = self.p_so_obj.read(self.p_ir_id, ['name'])['name'] |
571 | + self.p_in_ids = self.p_pick_obj.search([ |
572 | + ('type', '=', 'in'), |
573 | + ('origin', 'like', ir_name), |
574 | + ]) |
575 | + for pick in self.p_pick_obj.browse(self.p_in_ids): |
576 | + for move in pick.move_lines: |
577 | + if move.product_id.id == self.p_prd1_id: |
578 | + prd1_qty += move.product_qty |
579 | + elif move.product_id.id == self.p_prd2_id: |
580 | + prd2_qty += move.product_qty |
581 | + |
582 | + self.assert_( |
583 | + prd1_qty == 18.00 and prd2_qty == 0.00, |
584 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
585 | + ) |
586 | + |
587 | + # Check OUT quantities |
588 | + prd1_qty = 0.00 |
589 | + prd2_qty = 0.00 |
590 | + self.out_ids = self.p_pick_obj.search([('sale_id', '=', self.p_ir_id), ('type', '=', 'out')]) |
591 | + for pick in self.p_pick_obj.browse(self.out_ids): |
592 | + for move in pick.move_lines: |
593 | + if move.product_id.id == self.p_prd1_id: |
594 | + prd1_qty += move.product_qty |
595 | + elif move.product_id.id == self.p_prd2_id: |
596 | + prd2_qty += move.product_qty |
597 | + |
598 | + self.assert_( |
599 | + prd1_qty == 18.00 and prd2_qty == 0.00, |
600 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
601 | + ) |
602 | + |
603 | + self.close_flow() |
604 | + |
605 | + def test_cancel_original_splitted_line_more_on_new_line(self): |
606 | + """ |
607 | + Cancel the splitted line, confirm the PO, process the IN and the P/P/S |
608 | + at coordo, then sync. |
609 | + At project, check the number of lines in OUT. |
610 | + Process the IN and the OUT. |
611 | + """ |
612 | + # Add quantities on new line |
613 | + self.c_pol_obj.write(self.c_pol_15, {'product_qty': 50.0}) |
614 | + # Cancel the PO line |
615 | + res = self.c_pol_obj.ask_unlink(self.c_pol_10) |
616 | + self.assert_( |
617 | + res.get('res_id', False) and res.get('res_model', False) == 'purchase.order.line.unlink.wizard', |
618 | + "There is no wizard displayed when cancel a PO line that sources a FO/IR line", |
619 | + ) |
620 | + w_res = self.c1.get('purchase.order.line.unlink.wizard').just_cancel(res.get('res_id')) |
621 | + |
622 | + self.run_flow() |
623 | + |
624 | + # Check IR quantities |
625 | + prd1_qty = 0.00 |
626 | + prd2_qty = 0.00 |
627 | + for line in self.p_so_obj.browse(self.p_ir_id).order_line: |
628 | + if line.state == 'done': |
629 | + continue |
630 | + if line.product_id.id == self.p_prd1_id: |
631 | + prd1_qty += line.product_uom_qty |
632 | + elif line.product_id.id == self.p_prd2_id: |
633 | + prd2_qty += line.product_uom_qty |
634 | + |
635 | + self.assert_( |
636 | + prd1_qty == 18.00 and prd2_qty == 50.00, |
637 | + "The quantities on IR moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
638 | + ) |
639 | + |
640 | + # Check IN quantities |
641 | + prd1_qty = 0.00 |
642 | + prd2_qty = 0.00 |
643 | + ir_name = self.p_so_obj.read(self.p_ir_id, ['name'])['name'] |
644 | + self.p_in_ids = self.p_pick_obj.search([ |
645 | + ('type', '=', 'in'), |
646 | + ('origin', 'like', ir_name), |
647 | + ]) |
648 | + for pick in self.p_pick_obj.browse(self.p_in_ids): |
649 | + for move in pick.move_lines: |
650 | + if move.product_id.id == self.p_prd1_id: |
651 | + prd1_qty += move.product_qty |
652 | + elif move.product_id.id == self.p_prd2_id: |
653 | + prd2_qty += move.product_qty |
654 | + |
655 | + self.assert_( |
656 | + prd1_qty == 18.00 and prd2_qty == 50.00, |
657 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
658 | + ) |
659 | + |
660 | + # Check OUT quantities |
661 | + prd1_qty = 0.00 |
662 | + prd2_qty = 0.00 |
663 | + self.out_ids = self.p_pick_obj.search([('sale_id', '=', self.p_ir_id), ('type', '=', 'out')]) |
664 | + for pick in self.p_pick_obj.browse(self.out_ids): |
665 | + for move in pick.move_lines: |
666 | + if move.product_id.id == self.p_prd1_id: |
667 | + prd1_qty += move.product_qty |
668 | + elif move.product_id.id == self.p_prd2_id: |
669 | + prd2_qty += move.product_qty |
670 | + |
671 | + self.assert_( |
672 | + prd1_qty == 18.00 and prd2_qty == 50.00, |
673 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
674 | + ) |
675 | + |
676 | + self.close_flow() |
677 | + |
678 | + def test_cancel_original_splitted_line(self): |
679 | + """ |
680 | + Cancel the splitted line, confirm the PO, process the IN and the P/P/S |
681 | + at coordo, then sync. |
682 | + At project, check the number of lines in OUT. |
683 | + Process the IN and the OUT. |
684 | + """ |
685 | + # Cancel the PO line |
686 | + res = self.c_pol_obj.ask_unlink(self.c_pol_10) |
687 | + self.assert_( |
688 | + res.get('res_id', False) and res.get('res_model', False) == 'purchase.order.line.unlink.wizard', |
689 | + "There is no wizard displayed when cancel a PO line that sources a FO/IR line", |
690 | + ) |
691 | + w_res = self.c1.get('purchase.order.line.unlink.wizard').just_cancel(res.get('res_id')) |
692 | + |
693 | + self.run_flow() |
694 | + |
695 | + # Check IR quantities |
696 | + prd1_qty = 0.00 |
697 | + prd2_qty = 0.00 |
698 | + for line in self.p_so_obj.browse(self.p_ir_id).order_line: |
699 | + if line.state == 'done': |
700 | + continue |
701 | + if line.product_id.id == self.p_prd1_id: |
702 | + prd1_qty += line.product_uom_qty |
703 | + elif line.product_id.id == self.p_prd2_id: |
704 | + prd2_qty += line.product_uom_qty |
705 | + |
706 | + self.assert_( |
707 | + prd1_qty == 18.00 and prd2_qty == 15.00, |
708 | + "The quantities on IR moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
709 | + ) |
710 | + |
711 | + # Check IN quantities |
712 | + prd1_qty = 0.00 |
713 | + prd2_qty = 0.00 |
714 | + ir_name = self.p_so_obj.read(self.p_ir_id, ['name'])['name'] |
715 | + self.p_in_ids = self.p_pick_obj.search([ |
716 | + ('type', '=', 'in'), |
717 | + ('origin', 'like', ir_name), |
718 | + ]) |
719 | + for pick in self.p_pick_obj.browse(self.p_in_ids): |
720 | + for move in pick.move_lines: |
721 | + if move.product_id.id == self.p_prd1_id: |
722 | + prd1_qty += move.product_qty |
723 | + elif move.product_id.id == self.p_prd2_id: |
724 | + prd2_qty += move.product_qty |
725 | + |
726 | + self.assert_( |
727 | + prd1_qty == 18.00 and prd2_qty == 15.00, |
728 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
729 | + ) |
730 | + |
731 | + # Check OUT quantities |
732 | + prd1_qty = 0.00 |
733 | + prd2_qty = 0.00 |
734 | + self.out_ids = self.p_pick_obj.search([('sale_id', '=', self.p_ir_id), ('type', '=', 'out')]) |
735 | + for pick in self.p_pick_obj.browse(self.out_ids): |
736 | + for move in pick.move_lines: |
737 | + if move.product_id.id == self.p_prd1_id: |
738 | + prd1_qty += move.product_qty |
739 | + elif move.product_id.id == self.p_prd2_id: |
740 | + prd2_qty += move.product_qty |
741 | + |
742 | + self.assert_( |
743 | + prd1_qty == 18.00 and prd2_qty == 15.00, |
744 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s)" % (prd1_qty, prd2_qty), |
745 | + ) |
746 | + |
747 | + self.close_flow() |
748 | + |
749 | + def test_change_product_on_splitted_line(self): |
750 | + """ |
751 | + Change the product of the splitted line, confirm the PO, process the |
752 | + IN and the P/P/S at coordo, then sync. |
753 | + At project, check the product of lines in OUT. |
754 | + Process the IN and the OUT. |
755 | + """ |
756 | + # Change the product of the splitted line |
757 | + self.c_pol_obj.write(self.c_pol_10, {'product_id': self.c_prd3_id}) |
758 | + |
759 | + self.run_flow() |
760 | + |
761 | + # Check IR quantities |
762 | + prd1_qty = 0.00 |
763 | + prd2_qty = 0.00 |
764 | + prd3_qty = 0.00 |
765 | + for line in self.p_so_obj.browse(self.p_ir_id).order_line: |
766 | + if line.product_id.id == self.p_prd1_id: |
767 | + prd1_qty += line.product_uom_qty |
768 | + elif line.product_id.id == self.p_prd2_id: |
769 | + prd2_qty += line.product_uom_qty |
770 | + elif line.product_id.id == self.p_prd3_id: |
771 | + prd3_qty += line.product_uom_qty |
772 | + |
773 | + self.assert_( |
774 | + prd1_qty == 18.00 and prd2_qty == 15.00 and prd3_qty == 10.00, |
775 | + "The quantities on IR moves are not good. (PRD1: %s - PRD2: %s - PRD3: %s)" % (prd1_qty, prd2_qty, prd3_qty), |
776 | + ) |
777 | + |
778 | + # Check IN quantities |
779 | + prd1_qty = 0.00 |
780 | + prd2_qty = 0.00 |
781 | + prd3_qty = 0.00 |
782 | + ir_name = self.p_so_obj.read(self.p_ir_id, ['name'])['name'] |
783 | + self.p_in_ids = self.p_pick_obj.search([ |
784 | + ('type', '=', 'in'), |
785 | + ('origin', 'like', ir_name), |
786 | + ]) |
787 | + for pick in self.p_pick_obj.browse(self.p_in_ids): |
788 | + for move in pick.move_lines: |
789 | + if move.product_id.id == self.p_prd1_id: |
790 | + prd1_qty += move.product_qty |
791 | + elif move.product_id.id == self.p_prd2_id: |
792 | + prd2_qty += move.product_qty |
793 | + elif move.product_id.id == self.p_prd3_id: |
794 | + prd3_qty += move.product_qty |
795 | + |
796 | + self.assert_( |
797 | + prd1_qty == 18.00 and prd2_qty == 15.00 and prd3_qty == 10.00, |
798 | + "The quantities on IN moves are not good. (PRD1: %s - PRD2: %s - PRD3: %s)" % (prd1_qty, prd2_qty, prd3_qty), |
799 | + ) |
800 | + |
801 | + # Check OUT quantities |
802 | + prd1_qty = 0.00 |
803 | + prd2_qty = 0.00 |
804 | + prd3_qty = 0.00 |
805 | + self.out_ids = self.p_pick_obj.search([('sale_id', '=', self.p_ir_id), ('type', '=', 'out')]) |
806 | + for pick in self.p_pick_obj.browse(self.out_ids): |
807 | + for move in pick.move_lines: |
808 | + if move.product_id.id == self.p_prd1_id: |
809 | + prd1_qty += move.product_qty |
810 | + elif move.product_id.id == self.p_prd2_id: |
811 | + prd2_qty += move.product_qty |
812 | + elif move.product_id.id == self.p_prd3_id: |
813 | + prd3_qty += move.product_qty |
814 | + |
815 | + self.assert_( |
816 | + prd1_qty == 18.00 and prd2_qty == 15.00 and prd3_qty == 10.00, |
817 | + "The quantities on OUT moves are not good. (PRD1: %s - PRD2: %s - PRD3: %s)" % (prd1_qty, prd2_qty, prd3_qty), |
818 | + ) |
819 | + |
820 | + self.close_flow() |
821 | + |
822 | +def get_test_class(): |
823 | + return US311Test |