Merge lp:~unifield-team/unifield-wm/uftp-326 into lp:unifield-wm
- uftp-326
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 2324 |
Proposed branch: | lp:~unifield-team/unifield-wm/uftp-326 |
Merge into: | lp:unifield-wm |
Diff against target: |
1006 lines (+796/-12) 14 files modified
.bzrignore (+1/-0) delivery_mechanism/wizard/enter_reason.py (+2/-3) msf_outgoing/msf_outgoing.py (+3/-1) msf_outgoing/wizard/incoming_shipment_processor.py (+3/-0) sale_override/sale.py (+1/-1) stock_override/stock.py (+7/-0) unifield_tests/master_data/020_partners.yml (+12/-0) unifield_tests/tests/connection.py (+1/-0) unifield_tests/tests/resourcing.py (+66/-6) unifield_tests/tests/test_uftp_324.py (+195/-0) unifield_tests/tests/test_uftp_326.py (+266/-0) unifield_tests/tests/test_utp_1007.py (+197/-0) unifield_tests/tests/unifield_test.py (+41/-0) unifield_tests/unifield.config (+1/-1) |
To merge this branch: | bzr merge lp:~unifield-team/unifield-wm/uftp-326 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+239955@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2014-10-09 06:56:59 +0000 |
3 | +++ .bzrignore 2014-10-29 08:35:37 +0000 |
4 | @@ -1,1 +1,2 @@ |
5 | unifield_tests/output.html |
6 | +unifield.config |
7 | |
8 | === modified file 'delivery_mechanism/wizard/enter_reason.py' |
9 | --- delivery_mechanism/wizard/enter_reason.py 2014-08-04 15:19:38 +0000 |
10 | +++ delivery_mechanism/wizard/enter_reason.py 2014-10-29 08:35:37 +0000 |
11 | @@ -76,9 +76,8 @@ |
12 | pol_qty[move.purchase_line_id.id] += move.product_qty |
13 | |
14 | # if full cancel (no resource), we updated corresponding out and correct po state |
15 | - if cancel_type == 'update_out': |
16 | - picking_obj.cancel_and_update_out(cr, uid, [obj.id], context=context) |
17 | - else: |
18 | + picking_obj.cancel_and_update_out(cr, uid, [obj.id], context=context) |
19 | + if cancel_type != 'update_out': |
20 | context['pol_qty'] = pol_qty |
21 | pol_obj.write(cr, uid, pol_ids, {'has_to_be_resourced': True}, context=context) |
22 | pol_obj.cancel_sol(cr, uid, pol_ids, context=context) |
23 | |
24 | === modified file 'msf_outgoing/msf_outgoing.py' |
25 | --- msf_outgoing/msf_outgoing.py 2014-09-26 13:09:16 +0000 |
26 | +++ msf_outgoing/msf_outgoing.py 2014-10-29 08:35:37 +0000 |
27 | @@ -4151,9 +4151,11 @@ |
28 | pick_state = move.picking_id.state |
29 | subtype_ok = pick_type == 'out' and (pick_subtype == 'standard' or (pick_subtype == 'picking' and pick_state == 'draft')) |
30 | |
31 | - if pick_type == 'in' and move.purchase_line_id and not pick_cancel: |
32 | + if pick_type == 'in' and move.purchase_line_id: |
33 | sol_ids = pol_obj.get_sol_ids_from_pol_ids(cr, uid, [move.purchase_line_id.id], context=context) |
34 | for sol in sol_obj.browse(cr, uid, sol_ids, context=context): |
35 | + if sol.order_id.procurement_request: |
36 | + continue |
37 | diff_qty = uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, sol.product_uom.id) |
38 | if move.has_to_be_resourced or move.picking_id.has_to_be_resourced: |
39 | sol_obj.add_resource_line(cr, uid, sol.id, False, diff_qty, context=context) |
40 | |
41 | === modified file 'msf_outgoing/wizard/incoming_shipment_processor.py' |
42 | --- msf_outgoing/wizard/incoming_shipment_processor.py 2014-09-29 15:30:49 +0000 |
43 | +++ msf_outgoing/wizard/incoming_shipment_processor.py 2014-10-29 08:35:37 +0000 |
44 | @@ -152,6 +152,9 @@ |
45 | picking_obj = self.pool.get('stock.picking') |
46 | data_obj = self.pool.get('ir.model.data') |
47 | |
48 | + if context is None: |
49 | + context = {} |
50 | + |
51 | if not ids: |
52 | raise osv.except_osv( |
53 | _('Error'), |
54 | |
55 | === modified file 'sale_override/sale.py' |
56 | --- sale_override/sale.py 2014-10-14 14:46:33 +0000 |
57 | +++ sale_override/sale.py 2014-10-29 08:35:37 +0000 |
58 | @@ -2300,7 +2300,7 @@ |
59 | proc_obj.write(cr, uid, [proc], {'product_qty': minus_qty}, context=context) |
60 | |
61 | so_to_cancel_id = False |
62 | - if so_obj._get_ready_to_cancel(cr, uid, order, context=context)[order]: |
63 | + if context.get('cancel_type', False) != 'update_out' and so_obj._get_ready_to_cancel(cr, uid, order, context=context)[order]: |
64 | so_to_cancel_id = order |
65 | else: |
66 | wf_service.trg_write(uid, 'sale.order', order, cr) |
67 | |
68 | === modified file 'stock_override/stock.py' |
69 | --- stock_override/stock.py 2014-09-22 14:41:45 +0000 |
70 | +++ stock_override/stock.py 2014-10-29 08:35:37 +0000 |
71 | @@ -581,6 +581,13 @@ |
72 | # Variables |
73 | wf_service = netsvc.LocalService("workflow") |
74 | |
75 | + if isinstance(ids, (int, long)): |
76 | + ids = [ids] |
77 | + |
78 | + if context is None: |
79 | + context = {} |
80 | + |
81 | + context['cancel_type'] = 'update_out' |
82 | res = super(stock_picking, self).action_cancel(cr, uid, ids, context=context) |
83 | |
84 | # Re-source the sale.order.line |
85 | |
86 | === modified file 'unifield_tests/master_data/020_partners.yml' |
87 | --- unifield_tests/master_data/020_partners.yml 2014-10-10 08:02:07 +0000 |
88 | +++ unifield_tests/master_data/020_partners.yml 2014-10-29 08:35:37 +0000 |
89 | @@ -53,6 +53,8 @@ |
90 | supplier: 1 |
91 | customer: 0 |
92 | partner_type: 'external' |
93 | + property_account_receivable: account_account_receivable_supplier0 |
94 | + property_account_payable: account_account_payable_supplier0 |
95 | - |
96 | Create an address for external supplier 1 |
97 | - |
98 | @@ -67,6 +69,8 @@ |
99 | supplier: 1 |
100 | customer: 0 |
101 | partner_type: 'external' |
102 | + property_account_receivable: account_account_receivable_supplier0 |
103 | + property_account_payable: account_account_payable_supplier0 |
104 | - |
105 | Create an address for external supplier 2 |
106 | - |
107 | @@ -81,6 +85,8 @@ |
108 | supplier: 1 |
109 | customer: 0 |
110 | partner_type: 'external' |
111 | + property_account_receivable: account_account_receivable_supplier0 |
112 | + property_account_payable: account_account_payable_supplier0 |
113 | - |
114 | Create an address for external supplier 3 |
115 | - |
116 | @@ -97,6 +103,8 @@ |
117 | customer: 1 |
118 | supplier: 0 |
119 | partner_type: 'external' |
120 | + property_account_receivable: account_account_receivable_supplier0 |
121 | + property_account_payable: account_account_payable_supplier0 |
122 | - |
123 | Create an address for external customer 1 |
124 | - |
125 | @@ -111,6 +119,8 @@ |
126 | customer: 1 |
127 | supplier: 0 |
128 | partner_type: 'external' |
129 | + property_account_receivable: account_account_receivable_supplier0 |
130 | + property_account_payable: account_account_payable_supplier0 |
131 | - |
132 | Create an address for external customer 2 |
133 | - |
134 | @@ -125,6 +135,8 @@ |
135 | customer: 1 |
136 | supplier: 0 |
137 | partner_type: 'external' |
138 | + property_account_receivable: account_account_receivable_supplier0 |
139 | + property_account_payable: account_account_payable_supplier0 |
140 | - |
141 | Create an address for external customer 3 |
142 | - |
143 | |
144 | === modified file 'unifield_tests/tests/connection.py' |
145 | --- unifield_tests/tests/connection.py 2014-03-18 13:19:21 +0000 |
146 | +++ unifield_tests/tests/connection.py 2014-10-29 08:35:37 +0000 |
147 | @@ -54,6 +54,7 @@ |
148 | # Login initialization |
149 | db_name = '%s%s' % (db_prefix, db_suffix) |
150 | self.login(uid, pwd, db_name) |
151 | + self.db_name = db_name |
152 | |
153 | if __name__ == '__main__': |
154 | c = XMLRPCConnection('HQ1C1P1') |
155 | |
156 | === modified file 'unifield_tests/tests/resourcing.py' |
157 | --- unifield_tests/tests/resourcing.py 2014-10-15 09:18:02 +0000 |
158 | +++ unifield_tests/tests/resourcing.py 2014-10-29 08:35:37 +0000 |
159 | @@ -53,7 +53,10 @@ |
160 | :return True |
161 | :rtype bool |
162 | """ |
163 | - pr = self.order_obj.browse(order_to_check).procurement_request |
164 | + order_obj = db.get('sale.order') |
165 | + proc_obj = db.get('procurement.order') |
166 | + |
167 | + pr = order_obj.browse(order_to_check).procurement_request |
168 | |
169 | new_order_id = None |
170 | if pr: |
171 | @@ -61,15 +64,15 @@ |
172 | else: |
173 | state = 'done' |
174 | |
175 | - order_state = self.order_obj.read(order_to_check, ['state'])['state'] |
176 | + order_state = order_obj.read(order_to_check, ['state'])['state'] |
177 | while order_state != state: |
178 | time.sleep(0.5) |
179 | - order_state = self.order_obj.read(order_to_check, ['state'])['state'] |
180 | + order_state = order_obj.read(order_to_check, ['state'])['state'] |
181 | |
182 | if pr: |
183 | new_order_id = order_to_check |
184 | else: |
185 | - new_order_ids = self.order_obj.search([ |
186 | + new_order_ids = order_obj.search([ |
187 | ('original_so_id_sale_order', '=', order_to_check) |
188 | ]) |
189 | |
190 | @@ -78,7 +81,7 @@ |
191 | if new_order_ids: |
192 | new_order_id = new_order_ids[0] |
193 | |
194 | - self.proc_obj.run_scheduler() |
195 | + proc_obj.run_scheduler() |
196 | |
197 | return new_order_id |
198 | |
199 | @@ -98,7 +101,6 @@ |
200 | |
201 | # Prepare values for the field order |
202 | partner_id = self.get_record(db, 'ext_customer_1') |
203 | - p_addr_id = self.get_record(db, 'ext_customer_1_addr') |
204 | order_type = 'regular' |
205 | |
206 | change_vals = self.order_obj.\ |
207 | @@ -378,4 +380,62 @@ |
208 | else: |
209 | return self._get_number_of_fo_valid_lines(db, order_id) |
210 | |
211 | + def create_analytic_distribution(self, db): |
212 | + """ |
213 | + Create an analytic distribution |
214 | + :param db: Connection on which the distribution must be created |
215 | + :return: The ID of distribution |
216 | + """ |
217 | + distrib_obj = db.get('analytic.distribution') |
218 | + cc_line_obj = db.get('cost.center.distribution.line') |
219 | + fp_line_obj = db.get('funding.pool.distribution.line') |
220 | + |
221 | + distrib_id = distrib_obj.create({ |
222 | + 'name': 'Distrib 2', |
223 | + }) |
224 | + |
225 | + cc_line1_id = cc_line_obj.create({ |
226 | + 'name': 'CC Line 1', |
227 | + 'amount': 0.0, |
228 | + 'percentage': 75.0, |
229 | + 'currency_id': self.get_record(db, 'EUR', module='base'), |
230 | + 'analytic_id': self.get_record(db, 'analytic_cc1'), |
231 | + 'distribution_id': distrib_id, |
232 | + 'destination_id': self.get_record(db, 'analytic_account_destination_operation', module='analytic_distribution'), |
233 | + }) |
234 | + |
235 | + cc_line2_id = cc_line_obj.create({ |
236 | + 'name': 'CC Line 2', |
237 | + 'amount': 0.0, |
238 | + 'percentage': 25.0, |
239 | + 'currency_id': self.get_record(db, 'EUR', module='base'), |
240 | + 'analytic_id': self.get_record(db, 'analytic_cc2'), |
241 | + 'distribution_id': distrib_id, |
242 | + 'destination_id': self.get_record(db, 'analytic_account_destination_operation', module='analytic_distribution'), |
243 | + }) |
244 | + |
245 | + fp_line1_id = fp_line_obj.create({ |
246 | + 'name': 'FP Line 1', |
247 | + 'amount': 0.0, |
248 | + 'percentage': 75.0, |
249 | + 'currency_id': self.get_record(db, 'EUR', module='base'), |
250 | + 'analytic_id': self.get_record(db, 'analytic_cc1'), |
251 | + 'distribution_id': distrib_id, |
252 | + 'cost_center_id': self.get_record(db, 'analytic_cc1'), |
253 | + 'destination_id': self.get_record(db, 'analytic_account_destination_operation', module='analytic_distribution'), |
254 | + }) |
255 | + |
256 | + fp_line2_id = fp_line_obj.create({ |
257 | + 'name': 'FP Line 2', |
258 | + 'amount': 0.0, |
259 | + 'percentage': 25.0, |
260 | + 'currency_id': self.get_record(db, 'EUR', module='base'), |
261 | + 'analytic_id': self.get_record(db, 'analytic_cc2'), |
262 | + 'distribution_id': distrib_id, |
263 | + 'cost_center_id': self.get_record(db, 'analytic_cc1'), |
264 | + 'destination_id': self.get_record(db, 'analytic_account_destination_operation', module='analytic_distribution'), |
265 | + }) |
266 | + |
267 | + return distrib_id |
268 | + |
269 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
270 | |
271 | === added file 'unifield_tests/tests/test_uftp_324.py' |
272 | --- unifield_tests/tests/test_uftp_324.py 1970-01-01 00:00:00 +0000 |
273 | +++ unifield_tests/tests/test_uftp_324.py 2014-10-29 08:35:37 +0000 |
274 | @@ -0,0 +1,195 @@ |
275 | +#!/usr/bin/env python |
276 | +# -*- coding: utf8 -*- |
277 | + |
278 | +__author__ = 'qt' |
279 | + |
280 | +from resourcing import ResourcingTest |
281 | + |
282 | +import time |
283 | + |
284 | + |
285 | +class UFTP324Test(ResourcingTest): |
286 | + |
287 | + def setUp(self): |
288 | + """ |
289 | + Create a PO at Project side to Coordo with |
290 | + two lines. |
291 | + :return: |
292 | + """ |
293 | + |
294 | + super(UFTP324Test, self).setUp() |
295 | + |
296 | + self.synchronize(self.c1) |
297 | + self.synchronize(self.p1) |
298 | + |
299 | + # C1 |
300 | + self.c_so_obj = self.c1.get('sale.order') |
301 | + self.c_sol_obj = self.c1.get('sale.order.line') |
302 | + self.c_po_obj = self.c1.get('purchase.order') |
303 | + self.c_pol_obj = self.c1.get('purchase.order.line') |
304 | + self.c_partner_obj = self.c1.get('res.partner') |
305 | + self.c_lc_obj = self.c1.get('sale.order.leave.close') |
306 | + self.c_so_cancel_obj = self.c1.get('sale.order.cancelation.wizard') |
307 | + |
308 | + # P1 |
309 | + self.p_so_obj = self.p1.get('sale.order') |
310 | + self.p_sol_obj = self.p1.get('sale.order.line') |
311 | + self.p_po_obj = self.p1.get('purchase.order') |
312 | + self.p_pol_obj = self.p1.get('purchase.order.line') |
313 | + self.p_partner_obj = self.p1.get('res.partner') |
314 | + self.p_lc_obj = self.p1.get('sale.order.leave.close') |
315 | + self.p_so_cancel_obj = self.p1.get('sale.order.cancelation.wizard') |
316 | + |
317 | + # Create a PO at P1 with two products to C1 |
318 | + # Prepare values for the field order |
319 | + prod_log1_id = self.get_record(self.p1, 'prod_log_1') |
320 | + prod_log2_id = self.get_record(self.p1, 'prod_log_2') |
321 | + uom_pce_id = self.get_record(self.p1, 'product_uom_unit', module='product') |
322 | + location_id = self.get_record(self.p1, 'stock_location_stock', module='stock') |
323 | + |
324 | + partner_name = self.get_db_partner_name(self.c1) |
325 | + partner_ids = self.p_partner_obj.search([('name', '=', partner_name)]) |
326 | + self.assert_( |
327 | + partner_ids, |
328 | + "No partner found for %s" % self.c1.db_name, |
329 | + ) |
330 | + |
331 | + distrib_id = self.create_analytic_distribution(self.p1) |
332 | + |
333 | + order_values = { |
334 | + 'order_type': 'regular', |
335 | + 'partner_id': partner_ids[0], |
336 | + 'rfq_ok': False, |
337 | + 'location_id': location_id, |
338 | + 'analytic_distribution_id': distrib_id, |
339 | + } |
340 | + |
341 | + change_vals = self.p_po_obj.\ |
342 | + onchange_partner_id(None, partner_ids[0], time.strftime('%Y-%m-%d')).get('value', {}) |
343 | + order_values.update(change_vals) |
344 | + |
345 | + self.p_po_id = self.p_po_obj.create(order_values) |
346 | + |
347 | + # Create order lines |
348 | + # First line |
349 | + line_values = { |
350 | + 'order_id': self.p_po_id, |
351 | + 'product_id': prod_log1_id, |
352 | + 'product_uom': uom_pce_id, |
353 | + 'product_qty': 10.0, |
354 | + 'price_unit': 10.00, |
355 | + 'type': 'make_to_order', |
356 | + } |
357 | + self.p_pol_obj.create(line_values) |
358 | + |
359 | + # Second line |
360 | + line_values.update({ |
361 | + 'product_id': prod_log2_id, |
362 | + 'product_uom_qty': 20.0, |
363 | + 'price_unit': 10.0, |
364 | + }) |
365 | + self.p_pol_obj.create(line_values) |
366 | + |
367 | + # Validate the sale order |
368 | + self.p1.exec_workflow('purchase.order', 'purchase_confirm', self.p_po_id) |
369 | + |
370 | + self.p_po_name = self.p_po_obj.read(self.p_po_id, ['name'])['name'] |
371 | + |
372 | + # Synchronize |
373 | + self.synchronize(self.p1) |
374 | + self.synchronize(self.c1) |
375 | + |
376 | + self.c_so_id = None |
377 | + |
378 | + c_so_ids = self.c_so_obj.search([('client_order_ref', 'like', self.p_po_name)]) |
379 | + for c_so_id in c_so_ids: |
380 | + self.assert_( |
381 | + self.c_so_obj.read(c_so_id, ['state'])['state'] == 'draft', |
382 | + "The FO at Coordo is not 'Draft'.", |
383 | + ) |
384 | + self.c_so_id = c_so_id |
385 | + |
386 | + # Validate the sale order |
387 | + self.c1.exec_workflow('sale.order', 'order_validated', self.c_so_id) |
388 | + |
389 | + # Source all lines on a Purchase Order to ext_supplier_1 |
390 | + line_ids = self.c_sol_obj.search([('order_id', '=', self.c_so_id)]) |
391 | + self.c_sol_obj.write(line_ids, { |
392 | + 'type': 'make_to_order', |
393 | + 'po_cft': 'po', |
394 | + 'supplier': self.get_record(self.c1, 'ext_supplier_1'), |
395 | + }) |
396 | + self.c_sol_obj.confirmLine(line_ids) |
397 | + |
398 | + # Run the scheduler |
399 | + self.c_so_id = self.run_auto_pos_creation(self.c1, order_to_check=self.c_so_id) |
400 | + |
401 | + line_ids = self.c_sol_obj.search([('order_id', '=', self.c_so_id)]) |
402 | + not_sourced = True |
403 | + while not_sourced: |
404 | + not_sourced = False |
405 | + for line in self.c_sol_obj.browse(line_ids): |
406 | + if line.procurement_id and line.procurement_id.state != 'running': |
407 | + not_sourced = True |
408 | + if not_sourced: |
409 | + time.sleep(1) |
410 | + |
411 | + po_ids = set() |
412 | + po_line_ids = [] |
413 | + for line in self.c_sol_obj.browse(line_ids): |
414 | + if line.procurement_id: |
415 | + po_line_ids.extend(self.c_pol_obj.search([ |
416 | + ('procurement_id', '=', line.procurement_id.id), |
417 | + ])) |
418 | + |
419 | + for po_line in self.c_pol_obj.read(po_line_ids, ['order_id']): |
420 | + po_ids.add(po_line['order_id'][0]) |
421 | + |
422 | + self.c_po_id = po_line['order_id'][0] |
423 | + |
424 | + def test_utp_324(self): |
425 | + """ |
426 | + Cancel the PO at coordo side, synchronize and check the state of the PO at |
427 | + project side. |
428 | + :return: |
429 | + """ |
430 | + wiz_model = 'purchase.order.cancel.wizard' |
431 | + c_wiz_obj = self.c1.get(wiz_model) |
432 | + c_lc_wiz_obj = self.c1.get('sale.order.leave.close') |
433 | + c_cancel_so_wiz_obj = self.c1.get('sale.order.cancelation.wizard') |
434 | + |
435 | + # Cancel PO at coordo side |
436 | + c_res = self.c_po_obj.purchase_cancel(self.c_po_id) |
437 | + # Validate cancellation |
438 | + w_res = c_wiz_obj.cancel_po(c_res.get('res_id')) |
439 | + # Close the FO |
440 | + w_line_ids = c_lc_wiz_obj.search([ |
441 | + ('wizard_id', '=', w_res.get('res_id')), |
442 | + ('order_id', '=', self.c_so_id), |
443 | + ]) |
444 | + |
445 | + |
446 | + # Choose close it |
447 | + c_lc_wiz_obj.write(w_line_ids, {'action': 'close'}) |
448 | + c_cancel_so_wiz_obj.close_fo(w_res.get('res_id')) |
449 | + |
450 | + self.synchronize(self.c1) |
451 | + self.synchronize(self.p1) |
452 | + |
453 | + # Check state of the PO at project side |
454 | + c_so_name = self.c_so_obj.read(self.c_so_id, ['name'])['name'] |
455 | + self.p_po_id = self.p_po_obj.search([('partner_ref', 'like', c_so_name)])[0] |
456 | + p_po_state = self.p_po_obj.read(self.p_po_id, ['state'])['state'] |
457 | + self.assert_( |
458 | + p_po_state == 'done', |
459 | + "The PO at project side is not closed", |
460 | + ) |
461 | + # Check number of lines in PO at project side |
462 | + p_po_line_ids = self.p_pol_obj.search([('order_id', '=', self.p_po_id)]) |
463 | + self.assert_( |
464 | + len(p_po_line_ids) == 0, |
465 | + "There is always lines in PO at project side" |
466 | + ) |
467 | + |
468 | +def get_test_class(): |
469 | + return UFTP324Test |
470 | \ No newline at end of file |
471 | |
472 | === added file 'unifield_tests/tests/test_uftp_326.py' |
473 | --- unifield_tests/tests/test_uftp_326.py 1970-01-01 00:00:00 +0000 |
474 | +++ unifield_tests/tests/test_uftp_326.py 2014-10-29 08:35:37 +0000 |
475 | @@ -0,0 +1,266 @@ |
476 | +#!/usr/bin/env python |
477 | +# -*- coding: utf8 -*- |
478 | + |
479 | +__author__ = 'qt' |
480 | + |
481 | +from resourcing import ResourcingTest |
482 | + |
483 | +import time |
484 | + |
485 | + |
486 | +class UFTP326Test(ResourcingTest): |
487 | + |
488 | + def setUp(self): |
489 | + """ |
490 | + Create a PO at Project side to Coordo with |
491 | + two lines. |
492 | + :return: |
493 | + """ |
494 | + super(UFTP326Test, self).setUp() |
495 | + |
496 | + self.synchronize(self.c1) |
497 | + self.synchronize(self.p1) |
498 | + |
499 | + # C1 |
500 | + self.c_so_obj = self.c1.get('sale.order') |
501 | + self.c_sol_obj = self.c1.get('sale.order.line') |
502 | + self.c_po_obj = self.c1.get('purchase.order') |
503 | + self.c_pol_obj = self.c1.get('purchase.order.line') |
504 | + self.c_partner_obj = self.c1.get('res.partner') |
505 | + self.c_lc_obj = self.c1.get('sale.order.leave.close') |
506 | + self.c_so_cancel_obj = self.c1.get('sale.order.cancelation.wizard') |
507 | + self.c_pick_obj = self.c1.get('stock.picking') |
508 | + self.c_enter_reason_obj = self.c1.get('enter.reason') |
509 | + |
510 | + # Prepare values for the field order |
511 | + prod_log1_id = self.get_record(self.c1, 'prod_log_1') |
512 | + prod_log2_id = self.get_record(self.c1, 'prod_log_2') |
513 | + uom_pce_id = self.get_record(self.c1, 'product_uom_unit', module='product') |
514 | + |
515 | + partner_name = self.get_db_partner_name(self.p1) |
516 | + partner_ids = self.c_partner_obj.search([('name', '=', partner_name)]) |
517 | + self.assert_( |
518 | + partner_ids, |
519 | + "No partner found for %s" % self.p1.db_name, |
520 | + ) |
521 | + |
522 | + distrib_id = self.create_analytic_distribution(self.c1) |
523 | + |
524 | + order_values = { |
525 | + 'order_type': 'regular', |
526 | + 'partner_id': partner_ids[0], |
527 | + 'procurement_request': False, |
528 | + 'analytic_distribution_id': distrib_id, |
529 | + } |
530 | + |
531 | + change_vals = self.c_so_obj.\ |
532 | + onchange_partner_id(None, partner_ids[0], 'regular').get('value', {}) |
533 | + order_values.update(change_vals) |
534 | + |
535 | + order_values['ready_to_ship_date'] = time.strftime('%Y-%m-%d') |
536 | + |
537 | + self.c_so_id = self.c_so_obj.create(order_values) |
538 | + |
539 | + # Create order lines |
540 | + # First line |
541 | + line_values = { |
542 | + 'order_id': self.c_so_id, |
543 | + 'product_id': prod_log1_id, |
544 | + 'product_uom': uom_pce_id, |
545 | + 'product_uom_qty': 10.0, |
546 | + 'type': 'make_to_order', |
547 | + } |
548 | + self.c_sol_obj.create(line_values) |
549 | + |
550 | + # Second line |
551 | + line_values.update({ |
552 | + 'product_id': prod_log2_id, |
553 | + 'product_uom_qty': 20.0, |
554 | + }) |
555 | + self.c_sol_obj.create(line_values) |
556 | + |
557 | + # Validate the sale order |
558 | + self.c1.exec_workflow('sale.order', 'order_validated', self.c_so_id) |
559 | + |
560 | + # Source all lines on a Purchase Order to ext_supplier_1 |
561 | + line_ids = self.c_sol_obj.search([('order_id', '=', self.c_so_id)]) |
562 | + self.c_sol_obj.write(line_ids, { |
563 | + 'po_cft': 'po', |
564 | + 'supplier': self.get_record(self.c1, 'ext_supplier_1'), |
565 | + }) |
566 | + self.c_sol_obj.confirmLine(line_ids) |
567 | + |
568 | + # Run the scheduler |
569 | + self.c_so_id = self.run_auto_pos_creation(self.c1, order_to_check=self.c_so_id) |
570 | + |
571 | + line_ids = self.c_sol_obj.search([('order_id', '=', self.c_so_id)]) |
572 | + not_sourced = True |
573 | + while not_sourced: |
574 | + not_sourced = False |
575 | + for line in self.c_sol_obj.browse(line_ids): |
576 | + if line.procurement_id and line.procurement_id.state != 'running': |
577 | + not_sourced = True |
578 | + if not_sourced: |
579 | + time.sleep(1) |
580 | + |
581 | + po_ids = set() |
582 | + po_line_ids = [] |
583 | + for line in self.c_sol_obj.browse(line_ids): |
584 | + if line.procurement_id: |
585 | + po_line_ids.extend(self.c_pol_obj.search([ |
586 | + ('procurement_id', '=', line.procurement_id.id), |
587 | + ])) |
588 | + |
589 | + for po_line in self.c_pol_obj.read(po_line_ids, ['order_id']): |
590 | + po_ids.add(po_line['order_id'][0]) |
591 | + |
592 | + self.c_po_id = po_ids and list(po_ids)[0] or False |
593 | + self.c_so_name = self.c_so_obj.read(self.c_so_id, ['name'])['name'] |
594 | + |
595 | + self.synchronize(self.c1) |
596 | + self.synchronize(self.p1) |
597 | + self.synchronize(self.c1) |
598 | + |
599 | + # P1 |
600 | + self.p_so_obj = self.p1.get('sale.order') |
601 | + self.p_sol_obj = self.p1.get('sale.order.line') |
602 | + self.p_po_obj = self.p1.get('purchase.order') |
603 | + self.p_pol_obj = self.p1.get('purchase.order.line') |
604 | + self.p_partner_obj = self.p1.get('res.partner') |
605 | + self.p_lc_obj = self.p1.get('sale.order.leave.close') |
606 | + self.p_so_cancel_obj = self.p1.get('sale.order.cancelation.wizard') |
607 | + |
608 | + self.p_po_id = None |
609 | + |
610 | + p_po_ids = self.p_po_obj.search([('partner_ref', 'like', self.c_so_name)]) |
611 | + for p_po_id in p_po_ids: |
612 | + self.assert_( |
613 | + self.p_po_obj.read(p_po_id, ['state'])['state'] == 'sourced', |
614 | + "The PO at Project is '%s' - Should be 'sourced'." % self.p_po_obj.read(p_po_id, ['state'])['state'], |
615 | + ) |
616 | + self.p_po_id = p_po_id |
617 | + |
618 | + def test_cancel_po_at_coordo(self): |
619 | + """ |
620 | + Cancel the PO at coordo side. |
621 | + Check if the PO at project side is canceled. |
622 | + :return: |
623 | + """ |
624 | + wiz_model = 'purchase.order.cancel.wizard' |
625 | + c_wiz_obj = self.c1.get(wiz_model) |
626 | + c_lc_wiz_obj = self.c1.get('sale.order.leave.close') |
627 | + c_cancel_so_wiz_obj = self.c1.get('sale.order.cancelation.wizard') |
628 | + |
629 | + # Cancel PO at coordo side |
630 | + c_res = self.c_po_obj.purchase_cancel(self.c_po_id) |
631 | + # Validate cancellation |
632 | + w_res = c_wiz_obj.cancel_po(c_res.get('res_id')) |
633 | + # Close the FO |
634 | + w_line_ids = c_lc_wiz_obj.search([ |
635 | + ('wizard_id', '=', w_res.get('res_id')), |
636 | + ('order_id', '=', self.c_so_id), |
637 | + ]) |
638 | + |
639 | + |
640 | + # Choose close it |
641 | + c_lc_wiz_obj.write(w_line_ids, {'action': 'close'}) |
642 | + c_cancel_so_wiz_obj.close_fo(w_res.get('res_id')) |
643 | + |
644 | + self.synchronize(self.c1) |
645 | + self.synchronize(self.p1) |
646 | + |
647 | + # Check state of the PO at project side |
648 | + p_po_state = self.p_po_obj.read(self.p_po_id, ['state'])['state'] |
649 | + self.assert_( |
650 | + p_po_state == 'done', |
651 | + "The PO at project side is not closed", |
652 | + ) |
653 | + # Check number of lines in PO at project side |
654 | + p_po_line_ids = self.p_pol_obj.search([('order_id', '=', self.p_po_id)]) |
655 | + self.assert_( |
656 | + len(p_po_line_ids) == 0, |
657 | + "There is always lines in PO at project side" |
658 | + ) |
659 | + |
660 | + def cancel_or_resource_in_at_coordo(self, resource=False): |
661 | + """ |
662 | + Cancel or Cancel & Resource the IN at coordo side. |
663 | + Check if the PO and the FO at coordo side are canceled. |
664 | + Check if the PO at project side is canceled. |
665 | + :return: |
666 | + """ |
667 | + # Validate and confirm the PO |
668 | + self._validate_po(self.c1, [self.c_po_id]) |
669 | + self._confirm_po(self.c1, [self.c_po_id]) |
670 | + |
671 | + # Get the IN associated to this PO |
672 | + c_in_ids = self.c_pick_obj.search([('purchase_id', '=', self.c_po_id), ('type', '=', 'in')]) |
673 | + c_out_ids = self.c_pick_obj.search([('sale_id', '=', self.c_so_id), ('type', '=', 'out')]) |
674 | + self.assert_( |
675 | + len(c_in_ids) == 1, |
676 | + "There are %s IN associated to PO - Should be 1" % len(c_in_ids), |
677 | + ) |
678 | + self.assert_( |
679 | + len(c_out_ids) == 1, |
680 | + "There are %s OUT/PICK associated to FO - Should be 1" % len(c_out_ids), |
681 | + ) |
682 | + |
683 | + # Cancel the IN |
684 | + wiz_id = self.c_enter_reason_obj.create({ |
685 | + 'picking_id': c_in_ids[0], |
686 | + 'change_reason': 'test_cancel_in_at_coordo', |
687 | + }) |
688 | + ctx = { |
689 | + 'active_ids': c_in_ids, |
690 | + } |
691 | + if not resource: |
692 | + ctx['cancel_type'] = 'update_out' |
693 | + |
694 | + self.c_enter_reason_obj.do_cancel([wiz_id], ctx) |
695 | + |
696 | + # Check IN and OUT states |
697 | + in_state = self.c_pick_obj.read(c_in_ids, ['state']) |
698 | + out_state = self.c_pick_obj.read(c_out_ids, ['state']) |
699 | + self.assert_( |
700 | + all([x['state'] == 'cancel' for x in in_state]), |
701 | + "All IN are not canceled", |
702 | + ) |
703 | + self.assert_( |
704 | + all([x['state'] == 'cancel' for x in out_state]), |
705 | + "All OUT/PICK are not canceled", |
706 | + ) |
707 | + |
708 | + # Check PO state |
709 | + po_state = self.c_po_obj.read(self.c_po_id, ['state'])['state'] |
710 | + self.assert_( |
711 | + po_state == 'done', |
712 | + "The PO state is '%s' - Should be 'done'" % po_state, |
713 | + ) |
714 | + |
715 | + # Check FO state |
716 | + fo_state = self.c_so_obj.read(self.c_so_id, ['state'])['state'] |
717 | + self.assert_( |
718 | + fo_state == 'done', |
719 | + "The FO state is '%s' - Should be 'done'" % fo_state, |
720 | + ) |
721 | + |
722 | + def test_cancel_in_at_coordo(self): |
723 | + """ |
724 | + Cancel the IN at coordo side. |
725 | + Check if the PO and the FO at coordo side are canceled. |
726 | + Check if the PO at project side is canceled. |
727 | + :return: |
728 | + """ |
729 | + self.cancel_or_resource_in_at_coordo() |
730 | + |
731 | + def test_resource_in_at_coordo(self): |
732 | + """ |
733 | + Cancel & Resource the IN at coordo side. |
734 | + Check if the PO and the FO at coordo side are canceled. |
735 | + Check if the PO at project side is canceled. |
736 | + :return: |
737 | + """ |
738 | + self.cancel_or_resource_in_at_coordo(resource=True) |
739 | + |
740 | +def get_test_class(): |
741 | + return UFTP326Test |
742 | |
743 | === added file 'unifield_tests/tests/test_utp_1007.py' |
744 | --- unifield_tests/tests/test_utp_1007.py 1970-01-01 00:00:00 +0000 |
745 | +++ unifield_tests/tests/test_utp_1007.py 2014-10-29 08:35:37 +0000 |
746 | @@ -0,0 +1,197 @@ |
747 | +#!/usr/bin/env python |
748 | +# -*- coding: utf8 -*- |
749 | + |
750 | +__author__ = 'qt' |
751 | + |
752 | +from resourcing import ResourcingTest |
753 | + |
754 | +import time |
755 | + |
756 | + |
757 | +class UTP1007Test(ResourcingTest): |
758 | + |
759 | + def setUp(self): |
760 | + """ |
761 | + Set the test as an IR test |
762 | + |
763 | + 1/ Create an IR with one line of 100 PCE |
764 | + 2/ Source the IR to external partner |
765 | + 3/ Validate and confirm the PO |
766 | + 4/ Receive 98 PCE |
767 | + 5/ Cancel and resource the backorder |
768 | + """ |
769 | + super(UTP1007Test, self).setUp() |
770 | + self.c_so_obj = self.c1.get('sale.order') |
771 | + self.c_sol_obj = self.c1.get('sale.order.line') |
772 | + self.c_po_obj = self.c1.get('purchase.order') |
773 | + self.c_pol_obj = self.c1.get('purchase.order.line') |
774 | + self.c_proc_obj = self.c1.get('stock.incoming.processor') |
775 | + self.c_proc_line_obj = self.c1.get('stock.move.in.processor') |
776 | + self.c_pick_obj = self.c1.get('stock.picking') |
777 | + self.c_enter_reason_obj = self.c1.get('enter.reason') |
778 | + |
779 | + # Prepare values for the internal request |
780 | + prod_log1_id = self.get_record(self.c1, 'prod_log_1') |
781 | + uom_pce_id = self.get_record(self.c1, 'product_uom_unit', module='product') |
782 | + distrib_id = self.create_analytic_distribution(self.c1) |
783 | + |
784 | + """ |
785 | + 1/ Create an IR with one line of 10 |
786 | + |
787 | + """ |
788 | + order_values = { |
789 | + 'procurement_request': True, |
790 | + 'location_requestor_id': self.get_record(self.c1, 'stock_location_stock', module='stock'), |
791 | + } |
792 | + |
793 | + self.c_so_id = self.c_so_obj.create(order_values) |
794 | + |
795 | + # Create order lines |
796 | + # First line |
797 | + line_values = { |
798 | + 'order_id': self.c_so_id, |
799 | + 'product_id': prod_log1_id, |
800 | + 'product_uom': uom_pce_id, |
801 | + 'product_uom_qty': 100.0, |
802 | + 'type': 'make_to_order', |
803 | + } |
804 | + self.c_sol_obj.create(line_values) |
805 | + |
806 | + # Validate the sale order |
807 | + self.c1.exec_workflow('sale.order', 'procurement_validate', self.c_so_id) |
808 | + |
809 | + """ |
810 | + 2/ Source the IR to an external partner |
811 | + """ |
812 | + line_ids = self.c_sol_obj.search([('order_id', '=', self.c_so_id)]) |
813 | + self.c_sol_obj.write(line_ids, { |
814 | + 'po_cft': 'po', |
815 | + 'supplier': self.get_record(self.c1, 'ext_supplier_1'), |
816 | + }) |
817 | + self.c_sol_obj.confirmLine(line_ids) |
818 | + |
819 | + # Run the scheduler |
820 | + self.c_so_id = self.run_auto_pos_creation(self.c1, order_to_check=self.c_so_id) |
821 | + |
822 | + line_ids = self.c_sol_obj.search([('order_id', '=', self.c_so_id)]) |
823 | + not_sourced = True |
824 | + while not_sourced: |
825 | + not_sourced = False |
826 | + for line in self.c_sol_obj.browse(line_ids): |
827 | + if line.procurement_id and line.procurement_id.state != 'running': |
828 | + not_sourced = True |
829 | + if not_sourced: |
830 | + time.sleep(1) |
831 | + |
832 | + po_ids = set() |
833 | + po_line_ids = [] |
834 | + for line in self.c_sol_obj.browse(line_ids): |
835 | + if line.procurement_id: |
836 | + po_line_ids.extend(self.c_pol_obj.search([ |
837 | + ('procurement_id', '=', line.procurement_id.id), |
838 | + ])) |
839 | + |
840 | + for po_line in self.c_pol_obj.read(po_line_ids, ['order_id']): |
841 | + po_ids.add(po_line['order_id'][0]) |
842 | + |
843 | + self.c_po_id = po_ids and list(po_ids)[0] or False |
844 | + self.c_so_name = self.c_so_obj.read(self.c_so_id, ['name'])['name'] |
845 | + |
846 | + """ |
847 | + 3/ Validate and confirm the PO |
848 | + """ |
849 | + self._validate_po(self.c1, [self.c_po_id]) |
850 | + self._confirm_po(self.c1, [self.c_po_id]) |
851 | + |
852 | + """ |
853 | + 4/ Receive 98 PCE |
854 | + """ |
855 | + # Get the IN associated to this PO |
856 | + c_in_ids = self.c_pick_obj.search([('purchase_id', '=', self.c_po_id), ('type', '=', 'in')]) |
857 | + self.assert_( |
858 | + len(c_in_ids) == 1, |
859 | + "There are %s IN associated to PO - Should be 1" % len(c_in_ids), |
860 | + ) |
861 | + |
862 | + self.c_in_id = c_in_ids[0] |
863 | + |
864 | + wiz_res = self.c_pick_obj.action_process(self.c_in_id) |
865 | + proc_line_ids = self.c_proc_line_obj.search([('wizard_id', '=', wiz_res['res_id'])]) |
866 | + self.c_proc_line_obj.write(proc_line_ids, {'quantity': 98.0}) |
867 | + bo_res = self.c_proc_obj.do_incoming_shipment([wiz_res['res_id']]) |
868 | + |
869 | + def test_cancel_bo(self): |
870 | + """ |
871 | + Cancel the backorder without resourcing and check the quantity in |
872 | + FO line |
873 | + """ |
874 | + # Cancel the back order |
875 | + wiz_id = self.c_enter_reason_obj.create({ |
876 | + 'picking_id': self.c_in_id, |
877 | + 'change_reason': 'test_cancel_bo', |
878 | + }) |
879 | + self.c_enter_reason_obj.do_cancel([wiz_id], { |
880 | + 'active_ids': [self.c_in_id], |
881 | + 'cancel_type': 'update_out', |
882 | + }) |
883 | + |
884 | + # Check IN state |
885 | + in_state = self.c_pick_obj.read(self.c_in_id, ['state'])['state'] |
886 | + self.assert_( |
887 | + in_state == 'cancel', |
888 | + "The BO is not canceled", |
889 | + ) |
890 | + |
891 | + # Check quantity on the original IR line |
892 | + sol_ids = self.c_sol_obj.search([('order_id', '=', self.c_so_id)]) |
893 | + sol_qty = self.c_sol_obj.read(sol_ids[0], ['product_uom_qty'])['product_uom_qty'] |
894 | + self.assert_( |
895 | + sol_qty == 100.0, |
896 | + "The quantity on original IR is %s - Should be 100.00" % sol_qty |
897 | + ) |
898 | + |
899 | + def test_resource_bo(self): |
900 | + """ |
901 | + Cancel & Resource the backorder without resourcing and check the |
902 | + quantity in FO line |
903 | + """ |
904 | + # Cancel the back order |
905 | + wiz_id = self.c_enter_reason_obj.create({ |
906 | + 'picking_id': self.c_in_id, |
907 | + 'change_reason': 'test_cancel_bo', |
908 | + }) |
909 | + self.c_enter_reason_obj.do_cancel([wiz_id], { |
910 | + 'active_ids': [self.c_in_id], |
911 | + 'cancel_type': '', |
912 | + }) |
913 | + |
914 | + # Check IN state |
915 | + in_state = self.c_pick_obj.read(self.c_in_id, ['state'])['state'] |
916 | + self.assert_( |
917 | + in_state == 'cancel', |
918 | + "The BO is not canceled", |
919 | + ) |
920 | + |
921 | + # Check quantity on the original IR line |
922 | + sol_ids = self.c_sol_obj.search([('order_id', '=', self.c_so_id)]) |
923 | + sol_qty = self.c_sol_obj.read(sol_ids[0], ['product_uom_qty'])['product_uom_qty'] |
924 | + self.assert_( |
925 | + sol_qty == 98.0, |
926 | + "The quantity on original IR is %s - Should be 98.00" % sol_qty |
927 | + ) |
928 | + |
929 | + # Check quantity on new IR line |
930 | + new_ir_ids = self.c_so_obj.search([('parent_order_name', '=', self.c_so_name), ('procurement_request', '=', True)]) |
931 | + self.assert_( |
932 | + len(new_ir_ids) == 1, |
933 | + "No new order created after resourcing", |
934 | + ) |
935 | + sol_ids = self.c_sol_obj.search([('order_id', '=', new_ir_ids[0])]) |
936 | + sol_qty = self.c_sol_obj.read(sol_ids[0], ['product_uom_qty'])['product_uom_qty'] |
937 | + self.assert_( |
938 | + sol_qty == 2.0, |
939 | + "The quantity on original IR is %s - Should be 2.00" % sol_qty |
940 | + ) |
941 | + |
942 | +def get_test_class(): |
943 | + return UTP1007Test |
944 | |
945 | === modified file 'unifield_tests/tests/unifield_test.py' |
946 | --- unifield_tests/tests/unifield_test.py 2014-10-14 11:44:42 +0000 |
947 | +++ unifield_tests/tests/unifield_test.py 2014-10-29 08:35:37 +0000 |
948 | @@ -141,4 +141,45 @@ |
949 | |
950 | return False |
951 | |
952 | + def synchronize(self, db=None): |
953 | + ''' |
954 | + Connect the 'db' database to the sync. server |
955 | + and run synchronization. |
956 | + If no database givent in parameters, sync. all |
957 | + databases. |
958 | + :param db: DB connection to synchronize (can be None |
959 | + or a list. |
960 | + :return: True |
961 | + ''' |
962 | + if not db: |
963 | + for db_conn in self.db: |
964 | + self.synchronize(db=db_conn) |
965 | + |
966 | + if db and isinstance(db, list): |
967 | + for db_conn in db: |
968 | + self.synchronize(db=db_conn) |
969 | + |
970 | + conn_obj = db.get('sync.client.sync_server_connection') |
971 | + sync_obj = db.get('sync.client.sync_manager') |
972 | + |
973 | + conn_ids = conn_obj.search([]) |
974 | + conn_obj.action_connect(conn_ids) |
975 | + sync_ids = sync_obj.search([]) |
976 | + sync_obj.sync(sync_ids) |
977 | + |
978 | + def get_db_partner_name(self, db): |
979 | + ''' |
980 | + Return the name of partner associated |
981 | + to the company of the database |
982 | + :param db: DB connection of which we |
983 | + get the partner. |
984 | + :return: Name of the partner associated |
985 | + to the company of the database |
986 | + ''' |
987 | + company_obj = db.get('res.company') |
988 | + |
989 | + company_ids = company_obj.search([]) |
990 | + return company_obj.browse(company_ids[0]).partner_id.name |
991 | + |
992 | + |
993 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
994 | |
995 | === modified file 'unifield_tests/unifield.config' |
996 | --- unifield_tests/unifield.config 2014-10-13 07:28:32 +0000 |
997 | +++ unifield_tests/unifield.config 2014-10-29 08:35:37 +0000 |
998 | @@ -3,7 +3,7 @@ |
999 | port: 8069 |
1000 | |
1001 | [DB] |
1002 | -db_prefix: unifield_test_ |
1003 | +db_prefix: uftp-326_ |
1004 | username: admin |
1005 | password: admin |
1006 | # If tempo_mkdb is True, it means you use mkdb from OpenERP to create DB. If not, you use tempo's one. |