From d342adbee8c533a53b32ad16bf207fb509321f8b Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Wed, 7 Aug 2013 11:58:11 +0200 Subject: [PATCH 01/44] [FIX]stock_inventory_test: fix stock inventory test bzr revid: csn@openerp.com-20130807095811-jz95nfuguigwv90j --- addons/stock/stock.py | 1 + addons/stock/test/inventory.yml | 75 +++++++++++++++++---------------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 5bd89fdd44c..eb4cb46b0d5 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1566,6 +1566,7 @@ class stock_inventory(osv.osv): for inv in self.browse(cr, uid, ids, context=context): if not inv.move_ids: self.action_check(cr, uid, [inv.id], context=context) + inv.refresh() move_obj.action_done(cr, uid, [x.id for x in inv.move_ids], context=context) self.write(cr, uid, [inv.id], {'state': 'done', 'date_done': time.strftime('%Y-%m-%d %H:%M:%S')}, context=context) return True diff --git a/addons/stock/test/inventory.yml b/addons/stock/test/inventory.yml index 3a9d4a4c5db..d5376e82348 100644 --- a/addons/stock/test/inventory.yml +++ b/addons/stock/test/inventory.yml @@ -1,24 +1,38 @@ - - I create an inventory of 10 products + I create an inventory - !record {model: stock.inventory, id: inventory_test0}: name: Test - inventory_line_id: - - product_id: product.product_product_3 - product_qty: 10 - location_id: stock.stock_location_14 - - I post this inventory + I create the wizard to confirm the inventory +- + !record {model: stock.fill.inventory, id: inventory_test0_wizard}: + set_stock_zero: False +- + I fill this inventory +- + !python {model: stock.inventory.line}: | + context = {'active_ids': [ref('inventory_test0')]} + self.pool.get('stock.fill.inventory').fill_inventory(cr, uid, [ref('inventory_test0_wizard')], context=context) +- + I create an inventory line with 10 product +- + !record {model: stock.inventory.line, id: inventory_testline0}: + inventory_id: stock.inventory_test0 + product_id: product.product_product_3 + product_qty: 10 + location_id: stock.stock_location_14 +- + I confirm this inventory - !python {model: stock.inventory}: | - self.action_confirm(cr, uid, [ref('inventory_test0')], context=context) self.action_done(cr, uid, [ref('inventory_test0')], context=context) - I check that this inventory has a stock.move and a quant - !python {model: stock.inventory}: | inv = self.browse(cr, uid, ref('inventory_test0'), context=context) - assert len(inv.move_ids) == 1, "No move created for the inventory." + assert len(inv.move_ids) >= 1, "No move created for the inventory." assert len(inv.move_ids[0].quant_ids) >= 1, "No quant created for this inventory" - I check that the quantity on hand is 10 on the location and it's parent. @@ -38,21 +52,30 @@ product = self.browse(cr, uid, ref('product.product_product_3'), context=context) assert product.qty_available==0, 'Expecting 0 products, got %.2f on location stock_location_components!' % (product.qty_available,) - - I create an inventory of 20 products + I create another inventory - !record {model: stock.inventory, id: inventory_test1}: name: Test - inventory_line_id: - - product_id: product.product_product_3 - product_qty: 20 - location_id: stock.stock_location_14 - - I post this new inventory + I fill this new inventory +- + !python {model: stock.inventory}: | + context = {'active_ids': [ref('inventory_test1')]} + self.pool.get('stock.fill.inventory').fill_inventory(cr, uid, [ref('inventory_test0_wizard')], context=context) + self.action_done(cr, uid, [ref('inventory_test1')], context=context) +- + I create an inventory line with 20 product on this new inventory +- + !record {model: stock.inventory.line, id: inventory_testline0}: + inventory_id: stock.inventory_test1 + product_id: product.product_product_3 + product_qty: 20 + location_id: stock.stock_location_14 +- + I confirm this inventory - !python {model: stock.inventory}: | - self.action_confirm(cr, uid, [ref('inventory_test1')], context=context) self.action_done(cr, uid, [ref('inventory_test1')], context=context) - - I check that the quantity on hand is 20 on the location and it's parent. - @@ -60,24 +83,4 @@ context['location'] = ref('stock.stock_location_14') product = self.browse(cr, uid, ref('product.product_product_3'), context=context) assert product.qty_available==20, 'Expecting 20 products, got %.2f on location stock_location_14!' % (product.qty_available,) -- - !record {model: stock.inventory, id: inventory_test2}: - name: Test - inventory_line_id: - - product_id: product.product_product_3 - product_qty: 18 - location_id: stock.stock_location_14 -- - I post this new inventory -- - !python {model: stock.inventory}: | - self.action_confirm(cr, uid, [ref('inventory_test2')], context=context) - self.action_done(cr, uid, [ref('inventory_test2')], context=context) -- - I check that the quantity on hand is 18 on the location and it's parent. -- - !python {model: product.product}: | - context['location'] = ref('stock.stock_location_14') - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) - assert product.qty_available==18, 'Expecting 18 products, got %.2f on location stock_location_14!' % (product.qty_available,) From 5a4f0fec0c1613fc438e3464bc2c4fdbff3358ec Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Wed, 7 Aug 2013 12:08:49 +0200 Subject: [PATCH 02/44] [FIX]remove extra line bzr revid: csn@openerp.com-20130807100849-bnkyo20suoky18gc --- addons/stock/test/inventory.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/stock/test/inventory.yml b/addons/stock/test/inventory.yml index d5376e82348..9fc2fc32b10 100644 --- a/addons/stock/test/inventory.yml +++ b/addons/stock/test/inventory.yml @@ -62,7 +62,6 @@ !python {model: stock.inventory}: | context = {'active_ids': [ref('inventory_test1')]} self.pool.get('stock.fill.inventory').fill_inventory(cr, uid, [ref('inventory_test0_wizard')], context=context) - self.action_done(cr, uid, [ref('inventory_test1')], context=context) - I create an inventory line with 20 product on this new inventory - From c729a2529fc0e2e70ea8842724ca96f990397907 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Thu, 29 Aug 2013 15:28:33 +0530 Subject: [PATCH 03/44] [IMP]improve shipment yml and stock procrule yml bzr revid: sgo@tinyerp.com-20130829095833-iph2zy1f89wvic2i --- addons/stock/__openerp__.py | 1 + addons/stock/test/procrule.yml | 48 +++++++++++++++----- addons/stock/test/shipment.yml | 82 +++++++++++++++------------------- 3 files changed, 74 insertions(+), 57 deletions(-) diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 57019053481..fb3983ff319 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -91,6 +91,7 @@ Dashboard / Reports for Warehouse Management will include: 'test': [ 'test/inventory.yml', 'test/move.yml', + 'test/procrule.yml', # 'test/shipment.yml', ], 'installable': True, diff --git a/addons/stock/test/procrule.yml b/addons/stock/test/procrule.yml index d1762ae4806..cf9e28d350f 100644 --- a/addons/stock/test/procrule.yml +++ b/addons/stock/test/procrule.yml @@ -1,22 +1,46 @@ - Create new global procurement rule from Stock -> Output - - !record {model: procurement.rule, ref:} - location_id: stock - location_dest_id: output + !record {model: procurement.rule, id: global_proc_rule}: + name: Stock -> output + action: move + picking_type_id: stock.picking_type_out + location_src_id: stock.stock_location_stock + location_id: stock.stock_location_output - Create Delivery Order from Output -> Customer - - !record {model: stock.picking, ref:} + !record {model: stock.picking, id: pick_output}: + name: Delivery order for procurement + partner_id: base.res_partner_2 + picking_type_id: stock.picking_type_out + move_lines: + - product_id: product.product_product_3 + product_uom_qty: 10.00 + location_id: stock.stock_location_output + location_dest_id: stock.stock_location_customers - - Confirm delivery order + Confirm delivery order. - - + !python {model: stock.picking}: | + self.action_confirm(cr, uid, [ref('pick_output')]) +- + Create procurement in output related to this delivery order. +- + !record {model: procurement.order, id: proc_order_stock_output}: + product_id: product.product_product_3 + product_qty: 10.00 + rule_id: global_proc_rule + location_id: stock.stock_location_output + name: Procurement for stock to output +- + I run scheduler. +- + !python {model: procurement.order}: | + self.run_scheduler(cr, uid) - - Check procurement was created in output (as there is the global procurement rule) related to this delivery order + Check a picking was created from stock to output. - - -- - Check a picking was created from stock to output -- - + !python {model: stock.move }: | + move_id = self.search(cr, uid, [('product_id', '=', ref('product.product_product_3')),('location_id', '=', ref('stock.stock_location_stock')),('location_dest_id', '=', ref('stock.stock_location_output'))]) + assert len(move_id) == 1 diff --git a/addons/stock/test/shipment.yml b/addons/stock/test/shipment.yml index 70f9b14c57a..2616bd2d1c0 100644 --- a/addons/stock/test/shipment.yml +++ b/addons/stock/test/shipment.yml @@ -1,7 +1,8 @@ - I confirm outgoing shipment of 130 kgm Ice-cream. - - !workflow {model: stock.picking, action: button_confirm, ref: outgoing_shipment} + !python {model: stock.picking}: | + self.action_confirm(cr, uid, [ref("outgoing_shipment")]) - I check shipment details after confirmed. - @@ -10,77 +11,73 @@ assert shipment.state == "confirmed", "Shipment should be confirmed." for move_line in shipment.move_lines: assert move_line.state == "confirmed", "Move should be confirmed." - - Now I check vitual stock of Ice-cream after confirmed outgoing shipment. - !python {model: product.product}: | product = self.browse(cr, uid, ref('product_icecream'), context=context) product.virtual_available == -30, "Vitual stock is not updated." - - I confirm incomming shipment of 50 kgm Ice-cream. - - !workflow {model: stock.picking, action: button_confirm, ref: incomming_shipment} + !python {model: stock.picking}: | + self.action_confirm(cr, uid, [ref("incomming_shipment")]) - I receive 40kgm Ice-cream so I make backorder of incomming shipment for 40 kgm. - - !python {model: stock.partial.picking}: | + !python {model: stock.picking}: | + pick = self.browse(cr, uid, ref("incomming_shipment"), context=context) + self.pool.get('stock.pack.operation').create(cr, uid, { + 'picking_id': pick.id, + 'product_id': ref('product_icecream'), + 'product_uom_id': ref('product.product_uom_kgm'), + 'product_qty': 40 + }) context.update({'active_model': 'stock.picking', 'active_id': ref('incomming_shipment'), 'active_ids': [ref('incomming_shipment')]}) + pick.do_partial(context=context) - - !record {model: stock.partial.picking, id: partial_incomming}: - move_ids: - - quantity: 40 - product_id: product_icecream - product_uom: product.product_uom_kgm - move_id: incomming_shipment_icecream - location_id: location_convenience_shop - location_dest_id: location_refrigerator -- - !python {model: stock.partial.picking }: | - self.do_partial(cr, uid, [ref('partial_incomming')], context=context) -- - I check backorder shipment after received partial shipment. + I check backorder shipment after received partial shipment and check remaining shipment. - !python {model: stock.picking}: | shipment = self.browse(cr, uid, ref("incomming_shipment")) - backorder = shipment.backorder_id - assert backorder, "Backorder should be created after partial shipment." - assert backorder.state == 'done', "Backorder should be close after received." + for move_line in shipment.move_lines: + assert move_line.product_qty == 40, "Qty in shipment does not correspond." + assert move_line.state == 'done', "Move line of shipment should be closed." + backorder_id = self.search(cr, uid, [('backorder_id', '=', ref("incomming_shipment"))],context=context) + backorder = self.browse(cr, uid, backorder_id)[0] for move_line in backorder.move_lines: - assert move_line.product_qty == 40, "Qty in backorder does not correspond." - assert move_line.state == 'done', "Move line of backorder should be closed." + assert move_line.product_qty == 10, "Qty in backorder does not correspond." + assert move_line.state == 'draft', "Move line of backorder should be draft." + context.update({'active_model': 'stock.picking', 'active_id': backorder_id[0], 'active_ids': backorder_id}) + self.action_confirm(cr, uid, backorder_id, context=context) + self.do_partial(cr, uid, backorder_id, context=context) - I receive another 10kgm Ice-cream. - - !record {model: stock.partial.picking, id: partial_incomming}: - move_ids: - - quantity: 10 - product_id: product_icecream - product_uom: product.product_uom_kgm - move_id: incomming_shipment_icecream - location_id: location_convenience_shop - location_dest_id: location_refrigerator -- - !python {model: stock.partial.picking }: | - self.do_partial(cr, uid, [ref('partial_incomming')], context=context) - + !python {model: stock.picking}: | + pick = self.browse(cr, uid, ref("incomming_shipment")) + self.pool.get('stock.pack.operation').create(cr, uid, { + 'picking_id': pick.id, + 'product_id': ref('product_icecream'), + 'product_uom_id': ref('product.product_uom_kgm'), + 'product_qty': 10 + }) + context.update({'active_model': 'stock.picking', 'active_id': ref('incomming_shipment'), 'active_ids': [ref('incomming_shipment')]}) + pick.do_partial(context=context) - I check incomming shipment after received. - !python {model: stock.picking}: | - shipment = self.browse(cr, uid, ref("incomming_shipment")) + shipment = self.browse(cr, uid, self.search(cr, uid, [('backorder_id', '=', ref("incomming_shipment"))]))[0] assert shipment.state == 'done', "shipment should be close after received." for move_line in shipment.move_lines: assert move_line.product_qty == 10, "Qty does not correspond." assert move_line.product_id.virtual_available == 20, "Virtual stock does not correspond." assert move_line.state == 'done', "Move line should be closed." - - I return last incomming shipment for 10 kgm Ice-cream. - !record {model: stock.return.picking, id: return_incomming}: - invoice_state: none - !python {model: stock.return.picking }: | # this work without giving the id of the picking to return, magically, thanks to the context @@ -92,13 +89,8 @@ # the cancel is not on the return, but on the incomming shipment (which now has a quantity of 10, thanks to the # backorder). This situation is a little weird as we returned a move that we finally cancelled... As result, only # 30Kg from the original 50Kg will be counted in the stock (50 - 10 (cancelled quantity) - 10 (returned quantity)) - self.action_cancel(cr, uid, [ref("incomming_shipment")], context=context) -- - I make invoice of backorder of incomming shipment. -- - !python {model: stock.invoice.onshipping}: | - shipment = self.pool.get('stock.picking').browse(cr, uid, ref("incomming_shipment")) - context.update({'active_model': 'stock.picking', 'active_id': shipment.backorder_id.id, 'active_ids': [shipment.backorder_id.id]}) + pick_id = self.search(cr, uid, [('backorder_id', '=', ref("incomming_shipment"))],context=context) + self.action_cancel(cr, uid, pick_id, context=context) - I check available stock after received incomming shipping. (removed invoicing here) - From a7201bd53ad845b245728d616864d1d11a716b60 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Thu, 29 Aug 2013 15:42:50 +0530 Subject: [PATCH 04/44] [IMP]shipment.yml make it work again bzr revid: sgo@tinyerp.com-20130829101250-36b9ctdi9x3errbo --- addons/stock/__openerp__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index fb3983ff319..10e8ccc65e1 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -89,10 +89,10 @@ Dashboard / Reports for Warehouse Management will include: 'res_config_view.xml', ], 'test': [ - 'test/inventory.yml', +# 'test/inventory.yml', 'test/move.yml', 'test/procrule.yml', -# 'test/shipment.yml', + 'test/shipment.yml', ], 'installable': True, 'application': True, From 6ea0eec46998418ace51748df9f9dfbf5100aa02 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Thu, 29 Aug 2013 18:00:42 +0530 Subject: [PATCH 05/44] [IMP] remove stock.partial.picking errors and improve picking_type_id bzr revid: rma@tinyerp.com-20130829123042-3a9q4xs3gdajgm6f --- addons/purchase/test/fifo_price.yml | 109 ++++++++++++++-------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/addons/purchase/test/fifo_price.yml b/addons/purchase/test/fifo_price.yml index e6488bcc141..258d523815e 100644 --- a/addons/purchase/test/fifo_price.yml +++ b/addons/purchase/test/fifo_price.yml @@ -53,10 +53,9 @@ - Process the reception of purchase order 1 and set date - - !python {model: stock.partial.picking}: | - pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo1")).picking_ids - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + picking_obj = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo1")).picking_ids[0] + picking_obj.do_partial(context=context) - Check the standard price of the product (fifo icecream) - @@ -69,10 +68,9 @@ - Process the reception of purchase order 2 - - !python {model: stock.partial.picking}: | - pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo2")).picking_ids - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + picking_obj = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo2")).picking_ids[0] + picking_obj.do_partial(context=context) - A purchase order towards the Chicago shop TODO code for receiving - @@ -96,7 +94,7 @@ Let us send some goods - !record {model: stock.picking, id: outgoing_fifo_shipment}: - type: out + picking_type_id: stock.picking_type_out - Picking needs movement from stock - @@ -105,7 +103,9 @@ product_id: product_fifo_icecream product_uom: product.product_uom_kgm product_qty: 20.0 - type: out + location_id: stock.stock_location_stock + location_dest_id: stock.stock_location_customers + picking_type_id: stock.picking_type_out - I assign this outgoing shipment - @@ -114,9 +114,9 @@ - Process the delivery of the outgoing shipment - - !python {model: stock.partial.picking}: | - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [ref("outgoing_fifo_shipment")], 'default_type':'out'}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + pick_obj = self.pool.get('stock.picking').browse(cr, uid, ref("outgoing_fifo_shipment")) + pick_obj.do_partial(context=context) - Check product standard price changed to 65.0 - @@ -126,7 +126,7 @@ Do a delivery of an extra 500 g (delivery order) - !record {model: stock.picking, id: outgoing_fifo_shipment_uom}: - type: out + picking_type_id: stock.picking_type_out - Picking needs movement from stock - @@ -134,8 +134,10 @@ picking_id: outgoing_fifo_shipment_uom product_id: product_fifo_icecream product_uom: product.product_uom_gram + location_id: stock.stock_location_stock + location_dest_id: stock.stock_location_customers product_qty: 500.0 - type: out + picking_type_id: stock.picking_type_out - I assign this outgoing shipment - @@ -144,9 +146,9 @@ - Process the delivery of the outgoing shipment - - !python {model: stock.partial.picking}: | - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [ref("outgoing_fifo_shipment_uom")], 'default_type':'out'}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + pick_obj = self.pool.get('stock.picking').browse(cr, uid, ref("outgoing_fifo_shipment_uom")) + pick_obj.do_partial(context=context) - Check product price changed to 80.0 - @@ -201,15 +203,14 @@ - Process the reception of purchase order with usd - - !python {model: stock.partial.picking}: | - pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo_usd")).picking_ids - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + pick_obj = self.pool.get('stock.picking').browse(cr, uid, ref("purchase_order_fifo_usd")) + pick_obj.do_partial(context=context) - We create delivery order of 49.5 kg - !record {model: stock.picking, id: outgoing_fifo_shipment_cur}: - type: out + picking_type_id: stock.picking_type_out - Picking needs movement from stock - @@ -218,7 +219,9 @@ product_id: product_fifo_icecream product_uom: product.product_uom_kgm product_qty: 49.5 - type: out + location_id: stock.stock_location_stock + location_dest_id: stock.stock_location_customers + picking_type_id: stock.picking_type_out - I assign this outgoing shipment - @@ -227,9 +230,9 @@ - Process the delivery of the outgoing shipment - - !python {model: stock.partial.picking}: | - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [ref("outgoing_fifo_shipment_cur")], 'default_type':'out'}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + picking_obj = self.pool.get('stock.picking').browse(cr, uid, ref("outgoing_fifo_shipment_cur")) + picking_obj.do_partial(context=context) - Check rounded price is 102 euro - @@ -239,7 +242,7 @@ Do a delivery of an extra 10 kg - !record {model: stock.picking, id: outgoing_fifo_shipment_ret}: - type: out + picking_type_id: stock.picking_type_out - Picking needs movement from stock - @@ -248,7 +251,9 @@ product_id: product_fifo_icecream product_uom: product.product_uom_kgm product_qty: 10.0 - type: out + location_id: stock.stock_location_stock + location_dest_id: stock.stock_location_customers + picking_type_id: stock.picking_type_out - I assign this outgoing shipment - @@ -257,9 +262,9 @@ - Process the delivery of the outgoing shipment - - !python {model: stock.partial.picking}: | - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [ref("outgoing_fifo_shipment_ret")], 'default_type':'out'}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + picking_obj = self.pool.get('stock.picking').browse(cr, uid, ref("outgoing_fifo_shipment_ret")) + picking_obj.do_partial(context=context) - Check rounded price is 150.0 / 1.2834 - @@ -269,7 +274,7 @@ Let us create some outs to get negative stock. Create outpicking. We create delivery order of 200 kg, but will pick only 100 kg - !record {model: stock.picking, id: outgoing_fifo_shipment_neg}: - type: out + picking_type_id: stock.picking_type_out - Picking needs movement from stock - @@ -278,12 +283,14 @@ product_id: product_fifo_icecream product_uom: product.product_uom_kgm product_qty: 200.0 - type: out + location_id: stock.stock_location_stock + location_dest_id: stock.stock_location_customers + picking_type_id: stock.picking_type_out - Let us create another out of 400 kg, but will pick only 50 kg - !record {model: stock.picking, id: outgoing_fifo_shipment_neg2}: - type: out + picking_type_id: stock.picking_type_out - Picking needs movement from stock - @@ -292,19 +299,17 @@ product_id: product_fifo_icecream product_uom: product.product_uom_kgm product_qty: 400.0 - type: out + location_id: stock.stock_location_stock + location_dest_id: stock.stock_location_customers + picking_type_id: stock.picking_type_out - Process the delivery of the outgoing shipments - - !python {model: stock.partial.picking}: | - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [ref("outgoing_fifo_shipment_neg")], 'default_type':'out'}) - line = self.browse(cr, uid, partial_id, context=context).move_ids[0] - self.pool.get("stock.partial.picking.line").write(cr, uid, [line.id], {'quantity':100}) - self.do_partial(cr, uid, [partial_id]) - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [ref("outgoing_fifo_shipment_neg2")], 'default_type':'out'}) - line = self.browse(cr, uid, partial_id, context=context).move_ids[0] - self.pool.get("stock.partial.picking.line").write(cr, uid, [line.id], {'quantity':50}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + picking_obj = self.browse(cr, uid, ref("outgoing_fifo_shipment_neg")) + picking_obj.do_partial(context=context) + picking_obj1 = self.browse(cr, uid, ref("outgoing_fifo_shipment_neg2")) + picking_obj1.do_partial(context=context) - Receive purchase order with 50 kg FIFO Ice Cream at 50 euro/kg - @@ -325,10 +330,9 @@ - Process the reception of purchase order 1 - - !python {model: stock.partial.picking}: | - pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo_neg")).picking_ids - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + picking_obj = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo_neg")).picking_ids[0] + picking_obj.do_partial(context=context) - Assert price on product is still the old price as the out move has not been received fully yet - @@ -354,10 +358,9 @@ - Process the reception of purchase order 2 - - !python {model: stock.partial.picking}: | - pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo_neg2")).picking_ids - partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]}) - self.do_partial(cr, uid, [partial_id]) + !python {model: stock.picking}: | + picking_obj = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo_neg2")).picking_ids[0] + picking_obj.do_partial(context=context) - The price of the product should have changed back to 65.0 - From 6d7f4b4f08897b8ebcf715956b6b86946b8350a7 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Thu, 29 Aug 2013 18:30:56 +0530 Subject: [PATCH 06/44] [IMP]imp bzr revid: sgo@tinyerp.com-20130829130056-pnregl7x7dj8llh1 --- addons/stock/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 10e8ccc65e1..95f82a92ac3 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -89,7 +89,7 @@ Dashboard / Reports for Warehouse Management will include: 'res_config_view.xml', ], 'test': [ -# 'test/inventory.yml', + 'test/inventory.yml', 'test/move.yml', 'test/procrule.yml', 'test/shipment.yml', From 81cb96eb9290f3e890620fd1506d4f88c3a0fd8b Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Thu, 29 Aug 2013 18:04:33 +0200 Subject: [PATCH 07/44] [IMP] Change to followed route bzr revid: jco@openerp.com-20130829160433-71wo5rgowv61dhhj --- addons/stock_location/stock_location.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock_location/stock_location.py b/addons/stock_location/stock_location.py index 77d1a67149a..2cdffdad785 100644 --- a/addons/stock_location/stock_location.py +++ b/addons/stock_location/stock_location.py @@ -155,7 +155,7 @@ class procurement_rule(osv.osv): class procurement_order(osv.osv): _inherit = 'procurement.order' _columns = { - 'route_ids': fields.many2many('stock.location.route', 'stock_location_route_procurement', 'procurement_id', 'route_id', 'Destination route', help="Preferred route to be followed by the procurement order"), + 'route_ids': fields.many2many('stock.location.route', 'stock_location_route_procurement', 'procurement_id', 'route_id', 'Followed Route', help="Preferred route to be followed by the procurement order"), } def _run_move_create(self, cr, uid, procurement, context=None): From 5f03ac0ad30d94c59d5bb037be4f0024a379ac94 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Fri, 30 Aug 2013 11:39:00 +0530 Subject: [PATCH 08/44] [MERGE]merge packing.yml jpr's branch manually bzr revid: sgo@tinyerp.com-20130830060900-zwsnsrbuvtsev5wi --- addons/stock/__openerp__.py | 5 +- addons/stock/test/packing.yml | 141 +++++++++++++++++++++++++++++----- 2 files changed, 125 insertions(+), 21 deletions(-) diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 95f82a92ac3..5ba9238ee8c 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -89,10 +89,11 @@ Dashboard / Reports for Warehouse Management will include: 'res_config_view.xml', ], 'test': [ - 'test/inventory.yml', +# 'test/inventory.yml', 'test/move.yml', 'test/procrule.yml', - 'test/shipment.yml', + 'test/shipment.yml', + 'test/packing.yml', ], 'installable': True, 'application': True, diff --git a/addons/stock/test/packing.yml b/addons/stock/test/packing.yml index 64f772268f4..f642c363eb6 100644 --- a/addons/stock/test/packing.yml +++ b/addons/stock/test/packing.yml @@ -1,68 +1,171 @@ -- +- Create a new stockable product - - !record {model: product.product, id: packingtest}: - name: nice product + !record {model: product.product, id: product1}: + name: Nice product + type: product + categ_id: product.product_category_1 + list_price: 100.0 + standard_price: 70.0 + seller_ids: + - delay: 1 + name: base.res_partner_2 + min_qty: 2.0 + qty: 5.0 + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit - Create an incoming picking for this product of 300 PCE from suppliers to stock - - !record{model: stock.picking}: | + !record {model: stock.picking, id: pick1}: + name: Incoming picking + partner_id: base.res_partner_2 + picking_type_id: picking_type_in + move_lines: + - product_id: product1 + product_uom_qty: 300.00 + location_id: stock_location_suppliers + location_dest_id: stock_location_stock - Confirm and assign picking and prepare partial - - !python {model: stock.picking, id:}: | - self.action_confirm(cr, uid, ref()) + !python {model: stock.picking}: | + self.action_confirm(cr, uid, [ref('pick1')], context=context) + self.do_prepare_partial(cr, uid, [ref('pick1')], context=context) - Put 120 pieces on Pallet 1 (package), 120 pieces on Pallet 2 with lot A and 60 pieces on Pallet 3 - - !python {model: stock.picking, id:} | + !python {model: stock.picking}: | #Change quantity of first to 120 and create 2 others quant operations + record = self.browse(cr, uid, ref('pick1'), context=context) + stock_pack = self.pool.get('stock.pack.operation') + stock_quant_pack = self.pool.get('stock.quant.package') + #create lot A + lot_a = self.pool.get('stock.production.lot').create(cr, uid, {'name': 'Lot A', 'product_id': ref('product1')}, context=context) + #create package + package1 = stock_quant_pack.create(cr, uid, {'name': 'Pallet 1'}, context=context) + package2 = stock_quant_pack.create(cr, uid, {'name': 'Pallet 2'}, context=context) + package3 = stock_quant_pack.create(cr, uid, {'name': 'Pallet 3'}, context=context) #Create package for each line and assign it as result_package_id + #create pack operation + stock_pack.write(cr, uid, record.pack_operation_ids[0].id, {'package_id': package1, 'result_package_id': package1, 'product_qty': 120}) + new_pack1 = stock_pack.create(cr, uid, {'product_id': ref('product1'), 'product_uom_id': ref('product.product_uom_unit'), 'picking_id': ref('pick1'), 'lot_id': lot_a, 'package_id': package2, 'result_package_id': package2, 'product_qty': 120}, context=context) + new_pack2 = stock_pack.create(cr, uid, {'product_id': ref('product1'), 'product_uom_id': ref('product.product_uom_unit'), 'picking_id': ref('pick1'), 'package_id': package3, 'result_package_id': package3, 'product_qty': 60}, context=context) - Use button rereserve and check the qtyremaining on the moves are correct (=0) - - + !python {model: stock.picking}: | + self.rereserve(cr, uid, [ref('pick1')], context=context) + picking = self.browse(cr, uid, ref('pick1'), context=context) + move_reco = self.pool.get('stock.move').browse(cr, uid, picking.move_lines[0].id, context=context) + assert move_reco.remaining_qty == 0.0, "" - Transfer the reception - - + !python {model: stock.picking}: | + self.do_partial(cr, uid, [ref('pick1')], context=context) - Check the system created 3 quants one with 120 pieces on pallet 1, one with 120 pieces on pallet 2 with lot A and 60 pieces on pallet 3 - - + !python {model: stock.quant}: | + reco_id = self.search(cr ,uid , [('product_id','=',ref('product1'))], context=context) + assert len(reco_id) == 3, "" + for rec in self.browse(cr, uid, reco_id, context=context): + if rec.package_id.name == 'Pallet 1': + assert rec.qty == 120, "" + elif rec.package_id.name == 'Pallet 2': + assert rec.qty == 120, "" + elif rec.package_id.name == 'Pallet 3': + assert rec.qty == 60, "" - Check there is no backorder or extra moves created - - + !python {model: stock.picking}: | + picking = self.browse(cr, uid, ref('pick1'), context=context) + backorder = self.search(cr, uid, [('backorder_id', '=', ref('pick1'))]) + assert not backorder, "" + #Check extra moves created + assert len(picking.move_lines) == 1, "" - Make a delivery order of 300 pieces to the customer - - + !record {model: stock.picking, id: delivery_order1}: + name: outgoing picking + partner_id: base.res_partner_4 + picking_type_id: stock.picking_type_out + move_lines: + - product_id: product1 + product_uom_qty: 300.00 + location_id: stock_location_stock + location_dest_id: stock_location_customers - Assign and confirm - - + !python {model: stock.picking}: | + self.action_confirm(cr, uid, [ref('delivery_order1')], context=context) + self.action_assign(cr, uid, [ref('delivery_order1')]) + self.force_assign(cr, uid, [ref('delivery_order1')], context=context) - Instead of doing the 300 pieces, you decide to take pallet 1 (do not mention product in operation here) and 20 pieces from lot A and 10 pieces from pallet 3 - - + !python {model: stock.picking}: | + stock_pack = self.pool.get('stock.pack.operation') + self.do_prepare_partial(cr, uid, [ref('delivery_order1')], context=context) + delivery_id = self.browse(cr, uid, ref('delivery_order1'), context=context) + for rec in delivery_id.pack_operation_ids: + if rec.package_id.name == 'Pallet 1' or rec.product_qty == 120: + stock_pack.write(cr, uid, rec.id, {'product_qty': 120}, context=context) + if rec.package_id.name == 'Pallet 2' or rec.lot_id.name == 'Lot A' : + stock_pack.write(cr, uid, rec.id, {'product_qty': 20}, context=context) + if rec.package_id.name == 'Pallet 3' or rec.product_qty == 60: + stock_pack.write(cr, uid, rec.id, {'product_qty': 10}, context=context) - Process this picking - - + !python {model: stock.picking}: | + self.rereserve(cr, uid, [ref('delivery_order1')], context=context) + self.do_partial(cr, uid, [ref('delivery_order1')], context=context) - Check the quants that you have 120 pieces pallet 1 in customers, 100 pieces pallet 2 in stock and 20 with customers and 50 in stock, 10 in customers from pallet 3 - - + !python {model: stock.quant}: | + reco_id = self.search(cr ,uid , [('product_id','=',ref('product1'))], context=context) + for rec in self.browse(cr, uid, reco_id, context=context): + if rec.package_id.name == 'Pallet 1' and rec.location_id.id == ref('stock_location_customers'): + assert rec.qty == 120, "" + if rec.package_id.name == 'Pallet 2' and rec.location_id.id == ref('stock_location_customers'): + assert rec.qty == 20, "" + if rec.package_id.name == 'Pallet 3' and rec.location_id.id == ref('stock_location_customers'): + assert rec.qty == 10, "" - Check a backorder was created and on that backorder, prepare partial and add an op with 20 pieces (20 that cannot be assigned) with lot B - - + !python {model: stock.picking}: | + picking = self.browse(cr, uid, ref('delivery_order1'), context=context) + backorder = self.search(cr, uid, [('backorder_id.id', '=', picking.id)], context=context) + assert backorder, "" + backorder_id = self.browse(cr, uid, backorder, context=context) + self.action_confirm(cr, uid, backorder, context=context) + self.action_assign(cr, uid, backorder) + self.force_assign(cr, uid, backorder, context=context) + self.do_prepare_partial(cr, uid, backorder, context=context) + #create lot B + lot_b = self.pool.get('stock.production.lot').create(cr, uid, {'name': 'Lot B', 'product_id': ref('product1')}, context=context) + stock_pack = self.pool.get('stock.pack.operation').create(cr, uid, {'picking_id': backorder_id[0].id, 'lot_id': lot_b, 'product_qty': 20}) - Process this backorder - - + !python {model: stock.picking}: | + picking = self.browse(cr, uid, ref('delivery_order1'), context=context) + backorder = self.search(cr, uid, [('backorder_id.id', '=', picking.id)], context=context) + backorder_id = self.browse(cr, uid, backorder, context=context) + self.rereserve(cr, uid, [backorder_id[0].id], context=context) + self.do_partial(cr, uid, [backorder_id[0].id], context=context) - Check you have a negative quant because there were 20 too many that were transferred with lot B - - \ No newline at end of file + !python {model: stock.quant}: | + reco_id = self.search(cr ,uid , [('product_id','=',ref('product1'))], context=context) + for rec in self.browse(cr, uid, reco_id, context=context): + if rec.lot_id.name == 'Lot B': + assert rec.qty != -20, "" From 1a1338fa41c2c77dd11f907f28728e8adc23037a Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 30 Aug 2013 10:16:48 +0200 Subject: [PATCH 09/44] [IMP] Add invoice_state on move in stock_account and make sure it gets passed through procurement on the move bzr revid: jco@openerp.com-20130830081648-mmfxshzl9cuk3jg6 --- addons/sale_stock/sale_stock.py | 5 +- addons/stock/stock.py | 5 +- addons/stock_account/stock.py | 70 ++++++++++++++++----- addons/stock_account/stock_account.py | 5 -- addons/stock_account/stock_account_view.xml | 12 +++- addons/stock_location/stock_location.py | 6 +- 6 files changed, 74 insertions(+), 29 deletions(-) diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index 015347449ae..055b4309d6d 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -168,11 +168,12 @@ class sale_order(osv.osv): # if order_policy<>picking: super() # else: call invoice_on_picking_method() def action_invoice_create(self, cr, uid, ids, grouped=False, states=['confirmed', 'done', 'exception'], date_invoice = False, context=None): - picking_obj = self.pool.get('stock.picking') + move_obj = self.pool.get("stock.move") res = super(sale_order,self).action_invoice_create(cr, uid, ids, grouped=grouped, states=states, date_invoice = date_invoice, context=context) for order in self.browse(cr, uid, ids, context=context): if order.order_policy == 'picking': - picking_obj.write(cr, uid, map(lambda x: x.id, order.picking_ids), {'invoice_state': 'invoiced'}) + for picking in order.picking_ids: + move_obj.write(cr, uid, [x.id for x in picking.move_lines], {'invoice_state': 'invoiced'}, context=context) return res def action_cancel(self, cr, uid, ids, context=None): diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 7ece3c202dc..819762b06c2 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1130,7 +1130,10 @@ class stock_move(osv.osv): 'origin_returned_move_id': fields.many2one('stock.move', 'Origin return move', help='move that created the return move'), 'returned_move_ids': fields.one2many('stock.move', 'origin_returned_move_id', 'All returned moves', help='Optional: all returned moves created from this move'), 'availability': fields.function(_get_product_availability, type='float', string='Availability'), - } + } + + + def copy(self, cr, uid, id, default=None, context=None): if default is None: diff --git a/addons/stock_account/stock.py b/addons/stock_account/stock.py index e404ab3dd7b..312b1668f6d 100644 --- a/addons/stock_account/stock.py +++ b/addons/stock_account/stock.py @@ -22,6 +22,55 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ +#---------------------------------------------------------- +# Procurement Rule +#---------------------------------------------------------- +class procurement_rule(osv.osv): + _inherit = 'procurement.rule' + _columns= { + 'invoice_state': fields.selection([ + ("invoiced", "Invoiced"), + ("2binvoiced", "To Be Invoiced"), + ("none", "Not Applicable")], "Invoice Status", + required=False), + } + +#---------------------------------------------------------- +# Procurement Order +#---------------------------------------------------------- + + +class procurement_order(osv.osv): + _inherit = "procurement.order" + + def _run_move_create(self, cr, uid, procurement, context=None): + res = super(procurement_order, self)._run_move_create(cr, uid, procurement, context=context) + res.update({'invoice_state': procurement.rule_id.invoice_state in ('none', False) and procurement.invoice_state or procurement.rule_id.invoice_state }) + return res + + +#---------------------------------------------------------- +# Move +#---------------------------------------------------------- + +class stock_move(osv.osv): + _inherit = "stock.move" + _columns = { + 'invoice_state': fields.selection([("invoiced", "Invoiced"), + ("2binvoiced", "To Be Invoiced"), + ("none", "Not Applicable")], "Invoice Control", + select=True, required=True, track_visibility='onchange', + states={'draft': [('readonly', False)]}), + } + _defaults= { + 'invoice_state': lambda *args, **argv: 'none' + } + + + +#---------------------------------------------------------- +# Picking +#---------------------------------------------------------- class stock_picking(osv.osv): _inherit = 'stock.picking' @@ -30,22 +79,13 @@ class stock_picking(osv.osv): for pick in self.browse(cr, uid, ids, context=context): result[pick.id] = 'none' for move in pick.move_lines: - if move.procurement_id: - if move.procurement_id.invoice_state=='invoiced': - result[pick.id] = 'invoiced' - elif move.procurement_id.invoice_state=='2binvoiced': - result[pick.id] = '2binvoiced' - break + if move.invoice_state=='invoiced': + result[pick.id] = 'invoiced' + elif move.invoice_state=='2binvoiced': + result[pick.id] = '2binvoiced' + break return result - def __get_picking_procurement(self, cr, uid, ids, context={}): - result = {} - for proc in self.pool.get('procurement.order').browse(cr, uid, ids, context=context): - for move in proc.move_ids: - if move.picking_id: - result[move.picking_id.id] = True - return result.keys() - def __get_picking_move(self, cr, uid, ids, context={}): res = [] for move in self.pool.get('stock.move').browse(cr, uid, ids, context=context): @@ -59,8 +99,8 @@ class stock_picking(osv.osv): ("2binvoiced", "To Be Invoiced"), ("none", "Not Applicable") ], string="Invoice Control", required=True, + store={ - 'procurement.order': (__get_picking_procurement, ['invoice_state'], 10), 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['state'], 10), 'stock.move': (__get_picking_move, ['picking_id'], 10), }, diff --git a/addons/stock_account/stock_account.py b/addons/stock_account/stock_account.py index f9e62fa80e2..659f53adf91 100644 --- a/addons/stock_account/stock_account.py +++ b/addons/stock_account/stock_account.py @@ -34,11 +34,6 @@ import openerp.addons.decimal_precision as dp import logging _logger = logging.getLogger(__name__) -#---------------------------------------------------------- -# Invoice state -#---------------------------------------------------------- - - #---------------------------------------------------------- diff --git a/addons/stock_account/stock_account_view.xml b/addons/stock_account/stock_account_view.xml index a7e6bc8afe9..c6f9a581858 100644 --- a/addons/stock_account/stock_account_view.xml +++ b/addons/stock_account/stock_account_view.xml @@ -29,8 +29,18 @@ - + + + stock.move.form.inherit + stock.move + + + + + + + diff --git a/addons/stock_location/stock_location.py b/addons/stock_location/stock_location.py index 2cdffdad785..fc36d48d7f9 100644 --- a/addons/stock_location/stock_location.py +++ b/addons/stock_location/stock_location.py @@ -133,11 +133,7 @@ class procurement_rule(osv.osv): 'delay': fields.integer('Number of Hours'), 'procure_method': fields.selection([('make_to_stock','Make to Stock'),('make_to_order','Make to Order')], 'Procure Method', required=True, help="'Make to Stock': When needed, take from the stock or wait until re-supplying. 'Make to Order': When needed, purchase or produce for the procurement request."), 'partner_address_id': fields.many2one('res.partner', 'Partner Address'), - 'invoice_state': fields.selection([ - ("invoiced", "Invoiced"), - ("2binvoiced", "To Be Invoiced"), - ("none", "Not Applicable")], "Invoice Status", - required=True,), + 'route_sequence': fields.related('route_id', 'sequence', string='Route Sequence', store={'stock.location.route': (_get_rules, ['sequence'], 10)}), 'sequence': fields.integer('Sequence'), 'propagate': fields.boolean('Propagate cancel and split', help='If checked, when the previous move of the move (which was generated by a next procurement) is cancelled or split, the move generated by this move will too'), From 0291e419ce37b77661fed37fed0bfd39d2a07c53 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Fri, 30 Aug 2013 15:31:53 +0530 Subject: [PATCH 10/44] [IMP]improve string bzr revid: sgo@tinyerp.com-20130830100153-dxnc9uo3k7pv1i0c --- addons/stock/test/shipment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/test/shipment.yml b/addons/stock/test/shipment.yml index 2616bd2d1c0..09eab4784f8 100644 --- a/addons/stock/test/shipment.yml +++ b/addons/stock/test/shipment.yml @@ -23,7 +23,7 @@ !python {model: stock.picking}: | self.action_confirm(cr, uid, [ref("incomming_shipment")]) - - I receive 40kgm Ice-cream so I make backorder of incomming shipment for 40 kgm. + I receive 40kgm Ice-cream so It will make backorder of incomming shipment for 10 kgm. - !python {model: stock.picking}: | pick = self.browse(cr, uid, ref("incomming_shipment"), context=context) From fab4e1b5b8371aebc4e9e808011f343aa919a880 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Fri, 30 Aug 2013 16:00:53 +0530 Subject: [PATCH 11/44] [IMP] add invoice state in stock.move bzr revid: rma@tinyerp.com-20130830103053-qm5ggzg8jmdai3hb --- addons/account_anglo_saxon/test/anglo_saxon.yml | 1 + addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/addons/account_anglo_saxon/test/anglo_saxon.yml b/addons/account_anglo_saxon/test/anglo_saxon.yml index 3ea85fc0d73..0a2dcf5f5fc 100644 --- a/addons/account_anglo_saxon/test/anglo_saxon.yml +++ b/addons/account_anglo_saxon/test/anglo_saxon.yml @@ -195,6 +195,7 @@ product_qty: 1.0 product_uom: product.product_uom_unit location_dest_id: stock.stock_location_customers + invoice_state: 2binvoiced move_type: direct picking_type_id: stock.picking_type_out - diff --git a/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml b/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml index bb6200e148b..6d0b1718c74 100644 --- a/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml +++ b/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml @@ -197,6 +197,7 @@ product_id: product_fifo_anglo_saxon product_qty: 1.0 location_dest_id: stock.stock_location_customers + invoice_state: 2binvoiced move_type: direct picking_type_id: stock.picking_type_out - From 5e65f7d667a105feacb7d30f3f7193e3f0dffb9a Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Fri, 30 Aug 2013 17:48:07 +0530 Subject: [PATCH 12/44] [IMP] improve reun_scheduler_yml bzr revid: rma@tinyerp.com-20130830121807-r0k46ftwaxg1ccg4 --- addons/purchase/test/process/run_scheduler.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/addons/purchase/test/process/run_scheduler.yml b/addons/purchase/test/process/run_scheduler.yml index b8c4019ed1a..ff29a2a39f1 100644 --- a/addons/purchase/test/process/run_scheduler.yml +++ b/addons/purchase/test/process/run_scheduler.yml @@ -6,13 +6,8 @@ !record {model: procurement.order, id: procurement_order_testcase0}: location_id: stock.stock_location_stock name: Test scheduler for RFQ - procure_method: make_to_order product_id: product.product_product_45 product_qty: 15.0 -- - I confirm on procurement order. -- - !workflow {model: procurement.order, action: button_confirm, ref: procurement_order_testcase0} - I run the scheduler. - From 0dba7a7d4aaeb5b08f5bcdd5d37a4786ea0994b5 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 30 Aug 2013 15:25:07 +0200 Subject: [PATCH 13/44] [WIP] Add owner on quants and pack operations. Add owner option in warehouse settings. Change purchase_id on picking. bzr revid: jco@openerp.com-20130830132507-oqrixcaxqjzuboyb --- addons/purchase/stock_view.xml | 6 ++--- addons/stock/res_config.py | 3 +++ addons/stock/res_config_view.xml | 4 +++ addons/stock/security/stock_security.xml | 5 ++++ addons/stock/stock.py | 31 ++++++++++++++++-------- addons/stock/stock_view.xml | 10 +++++--- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/addons/purchase/stock_view.xml b/addons/purchase/stock_view.xml index 07aefef2e14..a924a5c341e 100644 --- a/addons/purchase/stock_view.xml +++ b/addons/purchase/stock_view.xml @@ -13,12 +13,12 @@ - Incoming Picking Inherited + Picking Inherited stock.picking - - + + diff --git a/addons/stock/res_config.py b/addons/stock/res_config.py index 0f9e1e5943f..3abfc34ca23 100644 --- a/addons/stock/res_config.py +++ b/addons/stock/res_config.py @@ -62,6 +62,9 @@ This installs the module product_expiry."""), 'group_stock_tracking_lot': fields.boolean("Track serial number on logistic units (pallets)", implied_group='stock.group_tracking_lot', help="""When you select a serial number on product moves, you can get the upstream or downstream traceability of that product."""), + 'group_stock_tracking_owner': fields.boolean("Manage owner on stock", + implied_group='stock.group_tracking_owner', + help="""This way you can receive products attributed to a certain owner. """), 'module_stock_account': fields.boolean("Generate accounting entries per stock movement", implied_group='stock.group_inventory_valuation', help="""Allows to configure inventory valuations on products and product categories."""), diff --git a/addons/stock/res_config_view.xml b/addons/stock/res_config_view.xml index f5015b146b5..d3654b7abee 100644 --- a/addons/stock/res_config_view.xml +++ b/addons/stock/res_config_view.xml @@ -38,6 +38,10 @@ + + Manage Different Stock Owners + + + diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 819762b06c2..d000d38b04a 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -157,7 +157,7 @@ class stock_quant(osv.osv): 'reservation_id': fields.many2one('stock.move', 'Reserved for Move', help="Is this quant reserved for a stock.move?"), 'lot_id': fields.many2one('stock.production.lot', 'Lot'), 'cost': fields.float('Unit Cost'), - 'partner_id': fields.related('lot_id', 'partner_id', type='many2one', relation="res.partner", string="Owner", store=True), # TODO implement store={} + 'owner_id': fields.many2one('res.partner', 'Owner', help="This is the owner of the quant"), 'create_date': fields.datetime('Creation Date'), 'in_date': fields.datetime('Incoming Date'), @@ -653,9 +653,11 @@ class stock_picking(osv.osv): 'product_qty': qty, 'quant_id': quant.id, 'product_id': quant.product_id.id, - 'lot_id': quant.lot_id.id, + 'lot_id': quant.lot_id and quant.lot_id.id or False, 'product_uom_id': quant.product_id.uom_id.id, + 'owner_id': quant.owner_id and quant.owner_id.id or False, 'cost': quant.cost, + 'package_id': quant.package_id and quant.package_id.id or False, }, context=context) if remaining_qty > 0: pack_operation_obj.create(cr, uid, { @@ -750,7 +752,8 @@ class stock_picking(osv.osv): 'history_ids': [(4, move.id)], 'in_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'company_id': move.company_id.id, - 'lot_id': ops.lot_id and ops.lot_id.id or False, + 'lot_id': ops.lot_id and ops.lot_id.id or False, + 'owner_id': ops.owner_id and ops.owner_id.id or False, 'reservation_id': move.id, #Reserve at once 'package_id': ops.result_package_id and ops.result_package_id.id or False, } @@ -929,7 +932,7 @@ class stock_production_lot(osv.osv): 'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type', '<>', 'service')]), 'quant_ids': fields.one2many('stock.quant', 'lot_id', 'Quants'), 'create_date': fields.datetime('Creation Date'), - 'partner_id': fields.many2one('res.partner', 'Owner'), +# 'partner_id': fields.many2one('res.partner', 'Owner'), } _defaults = { 'name': lambda x, y, z, c: x.pool.get('ir.sequence').get(y, z, 'stock.lot.serial'), @@ -942,8 +945,8 @@ class stock_production_lot(osv.osv): res = [] for lot in self.browse(cr, uid, ids, context=context): name = lot.name - if lot.partner_id: - name += ' (' + lot.partner_id.name + ')' +# if lot.partner_id: +# name += ' (' + lot.partner_id.name + ')' res.append((lot.id, name)) return res @@ -1654,7 +1657,7 @@ class stock_move(osv.osv): }, context=context) if move.move_dest_id and move.propagate: - self.split(self, cr, uid, move.move_dest_id, qty, context=context) + self.split(cr, uid, move.move_dest_id, qty, context=context) return new_move class stock_inventory(osv.osv): @@ -2079,6 +2082,7 @@ class stock_pack_operation(osv.osv): 'lot_id': fields.many2one('stock.production.lot', 'Lot/Serial Number'), 'result_package_id': fields.many2one('stock.quant.package', 'Container Package', help="If set, the operations are packed into this package", required=False, ondelete='cascade'), 'date': fields.datetime('Date', required=True), + 'owner_id': fields.many2one('res.partner', 'Owner', help="Owner of the quants"), #'update_cost': fields.boolean('Need cost update'), 'cost': fields.float("Cost", help="Unit Cost for this product line"), 'currency': fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", ondelete='CASCADE'), @@ -2095,9 +2099,16 @@ class stock_pack_operation(osv.osv): res += "package_id <> " + str(ops.package_id.id) if ops.lot_id: if res: - res += ", lot_id <> " + str(ops.lot_id.id) - else: - res += "lot_id <> " + str(ops.lot_id.id) + res += ", " + res += "lot_id <> " + str(ops.lot_id.id) + if ops.owner_id: + if res: + res += ", " + res += "owner_id <> " + str(ops.owner_id.id) + else: + if res: + res += ", " + res += "owner_id IS NOT NULL" return res diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 30038952ce7..866d0ef64d2 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -614,11 +614,12 @@ - - - + + + + - + @@ -1544,6 +1545,7 @@ + From b38138d555ddcaab48f8efc3e8efd799fbb9320d Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 30 Aug 2013 17:12:01 +0200 Subject: [PATCH 14/44] [IMP] Invoice_state on procurement order should be defined in stock_account bzr revid: jco@openerp.com-20130830151201-6xwnaxymdynaja7h --- addons/sale/sale.py | 6 ------ addons/stock/stock.py | 3 ++- addons/stock_account/stock.py | 9 ++++++++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 6535ed7bc6d..b849c7d62c1 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1072,12 +1072,6 @@ class procurement_order(osv.osv): _inherit = 'procurement.order' _columns = { 'sale_line_id': fields.many2one('sale.order.line', string='Sale Order Line'), - 'invoice_state': fields.selection( - [ - ("invoiced", "Invoiced"), - ("2binvoiced", "To Be Invoiced"), - ("none", "Not Applicable") - ], "Invoice Control", required=True), } _defaults = { 'invoice_state': 'none', diff --git a/addons/stock/stock.py b/addons/stock/stock.py index d000d38b04a..5439d10d225 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1623,10 +1623,11 @@ class stock_move(osv.osv): self.action_done(cr, uid, res, context=context) return res + + def split(self, cr, uid, move, qty, context=None): """ Splits qty from move move into a new move - It will check if it can propagate the split """ if move.product_qty==qty: return move.id diff --git a/addons/stock_account/stock.py b/addons/stock_account/stock.py index 312b1668f6d..a06f00d93a3 100644 --- a/addons/stock_account/stock.py +++ b/addons/stock_account/stock.py @@ -42,10 +42,17 @@ class procurement_rule(osv.osv): class procurement_order(osv.osv): _inherit = "procurement.order" + _columns = { + 'invoice_state': fields.selection( + [("invoiced", "Invoiced"), + ("2binvoiced", "To Be Invoiced"), + ("none", "Not Applicable") + ], "Invoice Control", required=True), + } def _run_move_create(self, cr, uid, procurement, context=None): res = super(procurement_order, self)._run_move_create(cr, uid, procurement, context=context) - res.update({'invoice_state': procurement.rule_id.invoice_state in ('none', False) and procurement.invoice_state or procurement.rule_id.invoice_state }) + res.update({'invoice_state': (procurement.rule_id.invoice_state in ('none', False) and procurement.invoice_state or procurement.rule_id.invoice_state) or 'none'}) return res From 20e762dd242af2959c482db31aa0f64927ca0930 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 30 Aug 2013 17:22:56 +0200 Subject: [PATCH 15/44] [IMP] Invoice_state in procurement order defaults bzr revid: jco@openerp.com-20130830152256-npdkrlefn3lxurwn --- addons/sale/sale.py | 3 --- addons/stock_account/stock.py | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index b849c7d62c1..497b99ef1b8 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1073,7 +1073,4 @@ class procurement_order(osv.osv): _columns = { 'sale_line_id': fields.many2one('sale.order.line', string='Sale Order Line'), } - _defaults = { - 'invoice_state': 'none', - } \ No newline at end of file diff --git a/addons/stock_account/stock.py b/addons/stock_account/stock.py index a06f00d93a3..ed7d9568340 100644 --- a/addons/stock_account/stock.py +++ b/addons/stock_account/stock.py @@ -54,6 +54,10 @@ class procurement_order(osv.osv): res = super(procurement_order, self)._run_move_create(cr, uid, procurement, context=context) res.update({'invoice_state': (procurement.rule_id.invoice_state in ('none', False) and procurement.invoice_state or procurement.rule_id.invoice_state) or 'none'}) return res + + defaults = { + 'invoice_state': 'none' + } #---------------------------------------------------------- From 4e805a6a5a962fc62f5b829e70387b585e64ef3a Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 2 Sep 2013 09:30:12 +0200 Subject: [PATCH 16/44] [FIX] _defaults instead of defaults (psi) bzr revid: jco@openerp.com-20130902073012-p9s5tws5kvisgodi --- addons/stock/stock.py | 4 ++++ addons/stock_account/stock.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 5439d10d225..0f7f7e2b176 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -727,6 +727,10 @@ class stock_picking(osv.osv): for move in picking.move_lines: quant_obj.quants_unreserve(cr, uid, move, context=context) res2[move.id] = move.product_qty + # Resort pack_operation_ids + + + # for ops in picking.pack_operation_ids: #Find moves that correspond if ops.product_id: diff --git a/addons/stock_account/stock.py b/addons/stock_account/stock.py index ed7d9568340..ff48e865737 100644 --- a/addons/stock_account/stock.py +++ b/addons/stock_account/stock.py @@ -55,7 +55,7 @@ class procurement_order(osv.osv): res.update({'invoice_state': (procurement.rule_id.invoice_state in ('none', False) and procurement.invoice_state or procurement.rule_id.invoice_state) or 'none'}) return res - defaults = { + _defaults = { 'invoice_state': 'none' } From 61dba9384c8543d687142fc65cc64639c9d8f57b Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 2 Sep 2013 15:32:52 +0200 Subject: [PATCH 17/44] [IMP] Invoice_state in stock_location: defaults/... should be removed for invoice_state in procrule bzr revid: jco@openerp.com-20130902133252-8mipn3owtwelwqkg --- addons/stock_account/stock_account_view.xml | 12 +++++++++++- addons/stock_location/stock_location.py | 1 - addons/stock_location/stock_location_demo_cpu1.xml | 2 -- addons/stock_location/stock_location_view.xml | 1 - 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/addons/stock_account/stock_account_view.xml b/addons/stock_account/stock_account_view.xml index c6f9a581858..6f3d469b440 100644 --- a/addons/stock_account/stock_account_view.xml +++ b/addons/stock_account/stock_account_view.xml @@ -41,6 +41,16 @@ - + + + stock.procurement.rule.inherit.form + procurement.rule + + + + + + + diff --git a/addons/stock_location/stock_location.py b/addons/stock_location/stock_location.py index fc36d48d7f9..e052063cc3c 100644 --- a/addons/stock_location/stock_location.py +++ b/addons/stock_location/stock_location.py @@ -140,7 +140,6 @@ class procurement_rule(osv.osv): } _defaults = { 'procure_method': 'make_to_stock', - 'invoice_state': 'none', 'propagate': True, 'delay': 0, } diff --git a/addons/stock_location/stock_location_demo_cpu1.xml b/addons/stock_location/stock_location_demo_cpu1.xml index 227be08333f..f89a1f98002 100644 --- a/addons/stock_location/stock_location_demo_cpu1.xml +++ b/addons/stock_location/stock_location_demo_cpu1.xml @@ -38,7 +38,6 @@ - none move @@ -53,7 +52,6 @@ move - none make_to_stock diff --git a/addons/stock_location/stock_location_view.xml b/addons/stock_location/stock_location_view.xml index f3a0a0726c9..34213638b84 100644 --- a/addons/stock_location/stock_location_view.xml +++ b/addons/stock_location/stock_location_view.xml @@ -17,7 +17,6 @@ - From aa877dcfb472acea3c7397a09d7d5e2b724a87f4 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 2 Sep 2013 17:11:08 +0200 Subject: [PATCH 18/44] [FIX] yml test bzr revid: qdp-launchpad@openerp.com-20130902151108-d2r9lpt0z5ertt2m --- addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml b/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml index bb6200e148b..afed068c468 100644 --- a/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml +++ b/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml @@ -203,12 +203,12 @@ I need to check the availability of the product, So I make my picking order for processing later. - !python {model: stock.picking}: | - self.action_confirm(cr, uid, [ref('stock_picking_out001')], context=context) + self.action_confirm(cr, uid, [ref('stock_picking_out001_fifo')], context=context) - I check the product availability, Product is available in the stock and ready to be sent. - !python {model: stock.picking}: | - picking = self.browse(cr, uid, ref("stock_picking_out001")) + picking = self.browse(cr, uid, ref("stock_picking_out001_fifo")) assert picking.state == "confirmed", "Picking should be confirmed." for move_line in picking.move_lines: assert move_line.state == "confirmed", "Move should be confirmed." From 8cf4c8d311795e990798ee59097c5bb4747b65e8 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 2 Sep 2013 17:23:10 +0200 Subject: [PATCH 19/44] [FIX] procurement yml test bzr revid: qdp-launchpad@openerp.com-20130902152310-2cp25k722evo90v4 --- addons/procurement/test/procurement.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/procurement/test/procurement.yml b/addons/procurement/test/procurement.yml index 0e663646c84..353bcaff3e8 100644 --- a/addons/procurement/test/procurement.yml +++ b/addons/procurement/test/procurement.yml @@ -15,8 +15,8 @@ !python {model: procurement.order}: | self.run_scheduler(cr, uid) - - I check that procurement order is done + I check that procurement order is in exception, as at first there isn't any suitable rule - !python {model: procurement.order}: | proc_order = self.browse(cr, uid, ref('procurement_order0'), context=context) - assert proc_order.state == 'done' + assert proc_order.state == 'exception' From 0ebd738ef61e68b720d07c31822f55a442c1fb15 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 2 Sep 2013 17:27:00 +0200 Subject: [PATCH 20/44] [FIX] stock: inventory yaml test bzr revid: qdp-launchpad@openerp.com-20130902152700-sfbrf2v07kf5ld9a --- addons/stock/test/inventory.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/stock/test/inventory.yml b/addons/stock/test/inventory.yml index f36aab303d3..6afc7e9d4ba 100644 --- a/addons/stock/test/inventory.yml +++ b/addons/stock/test/inventory.yml @@ -53,17 +53,17 @@ - !python {model: product.product}: | context['location'] = ref('stock.stock_location_14') - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) + product = self.browse(cr, uid, ref('inventory_product'), context=context) assert product.qty_available == 10, 'Expecting 10 products, got %.2f on location stock_location_14!' % (product.qty_available,) context['location'] = ref('stock.stock_location_stock') - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) + product = self.browse(cr, uid, ref('inventory_product'), context=context) assert product.qty_available == 10, 'Expecting 10 products, got %.2f on location stock_location_stock!' % (product.qty_available,) - I check that the quantity on hand is 0 on a brother location - !python {model: product.product}: | context['location'] = ref('stock.stock_location_components') - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) + product = self.browse(cr, uid, ref('inventory_product'), context=context) assert product.qty_available == 0, 'Expecting 0 products, got %.2f on location stock_location_components!' % (product.qty_available,) - I create another inventory @@ -82,7 +82,7 @@ - !python {model: stock.inventory}: | inv = self.browse(cr, uid, ref('inventory_test1'), context=context) - assert len(inv.line_ids) == 1, "Wrong number of inventory lines." + assert inv.line_ids and len(inv.line_ids) == 1, "Wrong number of inventory lines." assert len(inv.line_ids[0].product_qty) == 10, "Wrong quantity in inventory line." assert len(inv.line_ids[0].product_id.id) == ref('inventory_product'), "Wrong product in inventory line." - From 0bcda6375c82ba51933775966a36167d02ecb2c6 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 2 Sep 2013 19:07:40 +0200 Subject: [PATCH 21/44] [IMP] Order pack operations, reserve should be with domain instead of preferred order bzr revid: jco@openerp.com-20130902170740-o24rqc3brvbytmrc --- addons/stock/stock.py | 56 ++++++++++++++++++++----------------- addons/stock/stock_view.xml | 2 +- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index ecf9bf5dea9..0c34a5085f8 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -634,7 +634,9 @@ class stock_picking(osv.osv): }) back_order_name = self.browse(cr, uid, backorder_id, context=context).name self.message_post(cr, uid, picking.id, body=_("Back order %s created.") % (back_order_name), context=context) - self.pool.get('stock.move').write(cr, uid, backorder_move_ids, {'picking_id': backorder_id}, context=context) + move_obj = self.pool.get("stock.move") + move_obj.write(cr, uid, backorder_move_ids, {'picking_id': backorder_id}, context=context) + self.pool.get("stock.picking").action_confirm(cr, uid, [picking.id], context=context) return backorder_id return False @@ -657,7 +659,7 @@ class stock_picking(osv.osv): 'product_uom_id': quant.product_id.uom_id.id, 'owner_id': quant.owner_id and quant.owner_id.id or False, 'cost': quant.cost, - 'package_id': quant.package_id and quant.package_id.id or False, + 'package_id': quant.package_id and quant.package_id.id or False, }, context=context) if remaining_qty > 0: pack_operation_obj.create(cr, uid, { @@ -729,9 +731,11 @@ class stock_picking(osv.osv): res2[move.id] = move.product_qty # Resort pack_operation_ids - - # - for ops in picking.pack_operation_ids: + orderedpackops = picking.pack_operation_ids + #Sort packing operations such that packing operations with most specific information + orderedpackops.sort(key = lambda x: (x.package_id and -1 or 0) + (x.lot_id and -1 or 0)) + + for ops in orderedpackops: #Find moves that correspond if ops.product_id: #TODO: Should have order such that things with lots and packings are searched first @@ -764,10 +768,13 @@ class stock_picking(osv.osv): quant_id = quant_obj.create(cr, uid, vals, context=context) else: #Quants get - domain = [('reservation_id', '=', False)] - prefered_order = op_obj._get_preferred_order(cr, uid, ops.id, context=context) + prefered_order = "reservation_id IS NOT NULL" + domain = op_obj._get_domain(cr, uid, ops, context=context) quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=domain, prefered_order=prefered_order, context=context) quant_obj.quants_reserve(cr, uid, quants, move, context=context) + #In the end, move quants in correct package + if create and ops.result_package_id: + quant_obj.write(cr, uid, [x[0] for x in quants], {'package_id': ops.result_package_id.id}, context=context) res2[move.id] -= qty res[ops.id] = {} res[ops.id][ops.product_id.id] = qty_to_do @@ -788,6 +795,9 @@ class stock_picking(osv.osv): res2[move.id] -= qty res.setdefault(ops.id, {}).setdefault(quant.product_id.id, 0.0) res[ops.id][quant.product_id.id] += qty_to_do + #Add parent package + if create and ops.result_package_id: + self.pool.get("stock.package").write(cr, uid, [ops.package_id.id], {'parent_id': ops.result_package_id.id}, context=context) return (res, res2) @@ -2098,25 +2108,21 @@ class stock_pack_operation(osv.osv): 'date': fields.date.context_today, } - def _get_preferred_order(self, cr, uid, id, context=None): - ops = self.browse(cr, uid, id, context=context) - res = "" - if ops.package_id: - res += "package_id <> " + str(ops.package_id.id) - if ops.lot_id: - if res: - res += ", " - res += "lot_id <> " + str(ops.lot_id.id) - if ops.owner_id: - if res: - res += ", " - res += "owner_id <> " + str(ops.owner_id.id) - else: - if res: - res += ", " - res += "owner_id IS NOT NULL" - return res + def _get_domain(self, cr, uid, ops, context=None): + ''' + Gives domain for different + ''' + res = [] + if ops.package_id: + res.append(('package_id', '=', ops.package_id.id), ) + if ops.lot_id: + res.append(('lot_id', '=', ops.lot_id.id), ) + if ops.owner_id: + res.append(('owner_id', '=', ops.owner_id.id), ) + else: + res.append(('owner_id', '=', False), ) + return res #TODO: this function can be refactored def _search_and_increment(self, cr, uid, picking_id, key, context=None): diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 866d0ef64d2..f1d30972148 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -1561,7 +1561,7 @@ - + From 35475907aee21343053b8555728e0a15deca46df Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Tue, 3 Sep 2013 10:01:21 +0200 Subject: [PATCH 22/44] [FIX]stock: improve stock_picking_type view bzr revid: csn@openerp.com-20130903080121-xu0zhp555tvk54u7 --- addons/stock/stock.py | 53 ++++++++++++++++++++++++++++++------- addons/stock/stock_data.xml | 24 +++-------------- addons/stock/stock_view.xml | 33 ++++++++++++++--------- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 0c34a5085f8..ab05b169f0d 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -2285,13 +2285,6 @@ class product_template(osv.osv): 'supply_method': 'buy', } -class stock_picking_code(osv.osv): - _name = "stock.picking.code" - _description = "Will group picking types for kanban view" - _columns = { - 'name': fields.char("Picking Type", translate=True), - } - class stock_picking_type(osv.osv): _name = "stock.picking.type" _description = "The picking type determines the picking view" @@ -2383,17 +2376,56 @@ class stock_picking_type(osv.osv): result[type_id]['latest_picking_waiting'] = cmp(pick.date[:10], time.strftime('%Y-%m-%d')) return result + def onchange_picking_code(self, cr, uid, ids, picking_code=False): + if not picking_code: + return False + + obj_data = self.pool.get('ir.model.data') + stock_loc = obj_data.get_object_reference(cr, uid, 'stock','stock_location_stock')[1] + + result = { + 'default_location_src_id': stock_loc, + 'default_location_dest_id': stock_loc, + } + if picking_code == 'incoming': + result['default_location_src_id'] = obj_data.get_object_reference(cr, uid, 'stock','stock_location_suppliers')[1] + return {'value': result} + if picking_code == 'outgoing': + result['default_location_dest_id'] = obj_data.get_object_reference(cr, uid, 'stock','stock_location_customers')[1] + return {'value': result} + else: + return {'value': result} + + def name_get(self, cr, uid, ids, context=None): + """Overides orm name_get method to display 'Warehouse_name: PickingType_name' """ + if not isinstance(ids, list): + ids = [ids] + res = [] + if not ids: + return res + reads = self.browse(cr, uid, ids, context=context) + for record in reads: + name = record.warehouse_id.name+': '+record.name + res.append((record.id, name)) + return res + + def _default_warehouse(self, cr, uid, context=None): + user = self.pool.get('res.users').browse(cr, uid, uid, context) + res = self.pool.get('stock.warehouse').search(cr, uid, [('company_id', '=', user.company_id.id)], limit=1, context=context) + return res and res[0] or False + _columns = { 'name': fields.char('name', translate=True, required=True), - 'pack': fields.boolean('Pack', help='This picking type needs packing interface'), + 'pack': fields.boolean('Prefill Pack Operations', help='This picking type needs packing interface'), 'auto_force_assign': fields.boolean('Automatic Availability', help='This picking type does\'t need to check for the availability in stock'), 'color': fields.integer('Color Index'), 'delivery': fields.boolean('Print delivery'), 'sequence_id': fields.many2one('ir.sequence', 'Sequence', required=True), 'default_location_src_id': fields.many2one('stock.location', 'Default Source Location'), 'default_location_dest_id': fields.many2one('stock.location', 'Default Destination Location'), - 'code_id': fields.many2one('stock.picking.code', 'Picking type code', required=True), + 'code_id': fields.selection([('incoming', 'Suppliers'), ('outgoing', 'Customers'), ('internal', 'Internal')], 'Picking type code', required=True), 'return_picking_type_id': fields.many2one('stock.picking.type', 'Picking Type for Returns'), + 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True), # Statistics for the kanban view 'weekly_picking': fields.function(_get_picking_data, @@ -2422,4 +2454,7 @@ class stock_picking_type(osv.osv): type='string', multi='_get_picking_history'), } + _defaults = { + 'warehouse_id': _default_warehouse, + } diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index ff56e44548f..79d7545f8f4 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -77,12 +77,6 @@ - - - - @@ -106,24 +100,12 @@ - - Suppliers - - - - Customers - - - - Internal - - Receptions - + incoming True @@ -132,13 +114,13 @@ - + outgoing Internal Transfers - + internal diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index f1d30972148..313fcf90a85 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -1205,18 +1205,27 @@ stock.picking.type
- - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + +
From 8a23802e9e6c3ce95f8bbb24cb126cdaa53897de Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 3 Sep 2013 11:03:34 +0200 Subject: [PATCH 23/44] [IMP] stock: removed location input and location output on warehouse bzr revid: qdp-launchpad@openerp.com-20130903090334-iqtk4a762volg5s2 --- addons/point_of_sale/point_of_sale.py | 18 +++++++++++++++--- addons/purchase/purchase.py | 6 ------ addons/purchase/purchase_view.xml | 2 +- .../purchase_requisition.py | 11 +---------- .../sale_stock/test/picking_order_policy.yml | 2 -- addons/stock/stock.py | 12 ++---------- addons/stock/stock_data.xml | 2 -- addons/stock/stock_demo.xml | 4 ---- addons/stock/stock_demo.yml | 2 -- addons/stock/stock_view.xml | 4 ---- 10 files changed, 19 insertions(+), 44 deletions(-) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index 591f65cf925..4767d90f188 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -642,6 +642,7 @@ class pos_order(osv.osv): 'invoice_id': fields.many2one('account.invoice', 'Invoice'), 'account_move': fields.many2one('account.move', 'Journal Entry', readonly=True), 'picking_id': fields.many2one('stock.picking', 'Picking', readonly=True), + 'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type', required=True), 'note': fields.text('Internal Notes'), 'nb_print': fields.integer('Number of Print', readonly=True), 'pos_reference': fields.char('Receipt Ref', size=64, readonly=True), @@ -660,6 +661,13 @@ class pos_order(osv.osv): return session_record.config_id.pricelist_id and session_record.config_id.pricelist_id.id or False return False + def _get_out_picking_type(self, cr, uid, context=None): + try: + picking_type = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'picking_type_out', context=context) + except: + picking_type = False + return picking_type + _defaults = { 'user_id': lambda self, cr, uid, context: uid, 'state': 'draft', @@ -669,6 +677,7 @@ class pos_order(osv.osv): 'session_id': _default_session, 'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id, 'pricelist_id': _default_pricelist, + 'picking_type_id': _get_out_picking_type, } def create(self, cr, uid, values, context=None): @@ -697,18 +706,21 @@ class pos_order(osv.osv): if not order.state=='draft': continue addr = order.partner_id and partner_obj.address_get(cr, uid, [order.partner_id.id], ['delivery']) or {} + picking_type = order.picking_type_id picking_id = picking_obj.create(cr, uid, { 'origin': order.name, 'partner_id': addr.get('delivery',False), - 'picking_type_id': self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'picking_type_out', context=context).id, + 'picking_type_id': picking_type.id, 'company_id': order.company_id.id, 'move_type': 'direct', 'note': order.note or "", 'invoice_state': 'none', }, context=context) self.write(cr, uid, [order.id], {'picking_id': picking_id}, context=context) - location_id = order.warehouse_id.lot_stock_id.id - output_id = order.warehouse_id.lot_output_id.id + location_id = picking_type.default_location_src_id.id + output_id = picking_type.default_location_dest_id.id + if not location_id or not output_id: + raise osv.except_osv(_('Error!'), _('Missing source or destination location for picking type %s. Please configure those fields and try again.' % (picking_type.name,))) for line in order.lines: if line.product_id and line.product_id.type == 'service': diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index ec4144f4cc6..d0876df7ef1 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -308,12 +308,6 @@ class purchase_order(osv.osv): values.update({'location_id': location_id}) return {'value':values} - def onchange_warehouse_id(self, cr, uid, ids, warehouse_id): - if not warehouse_id: - return {} - warehouse = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id) - return {'value':{'location_id': warehouse.lot_input_id.id, 'dest_address_id': False}} - def onchange_partner_id(self, cr, uid, ids, partner_id): partner = self.pool.get('res.partner') if not partner_id: diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 973757770c4..f152d5ba066 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -196,7 +196,7 @@ - + diff --git a/addons/purchase_requisition/purchase_requisition.py b/addons/purchase_requisition/purchase_requisition.py index 85fda69a65e..6d08d163696 100644 --- a/addons/purchase_requisition/purchase_requisition.py +++ b/addons/purchase_requisition/purchase_requisition.py @@ -136,22 +136,13 @@ class purchase_requisition(osv.osv): return res def _prepare_purchase_order(self, cr, uid, requisition, supplier, context=None): - if not requisition.warehouse_id: - warehouse_obj = self.pool.get('stock.warehouse') - - warehouse_id = warehouse_obj.search(cr, uid, [('company_id', '=', requisition.company_id.id)], context=context) - if not warehouse_id: - raise osv.except_osv(_('Warning!'), _('No warehouse found for this company.')) - location_id = warehouse_obj.browse(cr, uid, warehouse_id, context=context)[0].lot_input_id.id - else: - location_id = requisition.warehouse_id.lot_input_id.id supplier_pricelist = supplier.property_product_pricelist_purchase and supplier.property_product_pricelist_purchase.id or False return { 'origin': requisition.name, 'date_order': requisition.date_end or fields.date.context_today(self, cr, uid, context=context), 'partner_id': supplier.id, 'pricelist_id': supplier_pricelist, - 'location_id': location_id, + #'location_id': location_id, 'company_id': requisition.company_id.id, 'fiscal_position': supplier.property_account_position and supplier.property_account_position.id or False, 'requisition_id': requisition.id, diff --git a/addons/sale_stock/test/picking_order_policy.yml b/addons/sale_stock/test/picking_order_policy.yml index f903d160400..4251c7a98a8 100644 --- a/addons/sale_stock/test/picking_order_policy.yml +++ b/addons/sale_stock/test/picking_order_policy.yml @@ -58,7 +58,6 @@ assert picking.invoice_state == (sale_order.order_policy=='picking' and '2binvoiced') or 'none',"Invoice policy is not correspond with sale order." assert len(picking.move_lines) == len(sale_order.order_line), "Total move of delivery order are not corresposning with total sale order lines." location_id = sale_order.warehouse_id.lot_stock_id.id - output_id = sale_order.warehouse_id.lot_output_id.id for move in picking.move_lines: order_line = move.procurement_id.sale_line_id date_planned = datetime.strptime(sale_order.date_order, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=order_line.delay or 0.0) @@ -72,7 +71,6 @@ assert move.product_packaging.id == order_line.product_packaging.id,"Product packaging is not correspond." assert move.partner_id.id == order_line.address_allotment_id.id or sale_order.partner_shipping_id.id,"Address is not correspond" #assert move.location_id.id == location_id,"Source Location is not correspond." - #assert move.location_dest_id == output_id,"Destination Location is not correspond." assert move.price_unit == order_line.product_id.standard_price or 0.0,"Price Unit is not correspond" - Now, I dispatch delivery order. diff --git a/addons/stock/stock.py b/addons/stock/stock.py index ab05b169f0d..494105a7784 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1921,24 +1921,16 @@ class stock_warehouse(osv.osv): 'name': fields.char('Name', size=128, required=True, select=True), 'company_id': fields.many2one('res.company', 'Company', required=True, select=True), 'partner_id': fields.many2one('res.partner', 'Owner Address'), - 'lot_input_id': fields.many2one('stock.location', 'Location Input', required=True, domain=[('usage', '<>', 'view')]), 'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True, domain=[('usage', '=', 'internal')]), - 'lot_output_id': fields.many2one('stock.location', 'Location Output', required=True, domain=[('usage', '<>', 'view')]), } - def _default_lot_input_stock_id(self, cr, uid, context=None): + def _default_stock_id(self, cr, uid, context=None): lot_input_stock = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'stock_location_stock') return lot_input_stock.id - def _default_lot_output_id(self, cr, uid, context=None): - lot_output = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'stock_location_output') - return lot_output.id - _defaults = { 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.inventory', context=c), - 'lot_input_id': _default_lot_input_stock_id, - 'lot_stock_id': _default_lot_input_stock_id, - 'lot_output_id': _default_lot_output_id, + 'lot_stock_id': _default_stock_id, } diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index 79d7545f8f4..b591263f4b2 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -210,9 +210,7 @@ watch your stock valuation, and track production lots upstream and downstream (b --> - - diff --git a/addons/stock/stock_demo.xml b/addons/stock/stock_demo.xml index 7d1515c427f..c42e216f636 100644 --- a/addons/stock/stock_demo.xml +++ b/addons/stock/stock_demo.xml @@ -251,20 +251,16 @@ - Chicago Warehouse - - Birmingham Warehouse - diff --git a/addons/stock/stock_demo.yml b/addons/stock/stock_demo.yml index cf8d1f71572..07763ee8cc1 100644 --- a/addons/stock/stock_demo.yml +++ b/addons/stock/stock_demo.yml @@ -22,9 +22,7 @@ - !record {model: stock.warehouse, id: warehouse_icecream}: name: Ice Cream Shop - lot_input_id: location_refrigerator lot_stock_id: location_refrigerator - lot_output_id: location_delivery_counter - !record {model: product.product, id: product_icecream}: default_code: 001 diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 313fcf90a85..d78f825bb1b 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -498,9 +498,7 @@

- - @@ -517,9 +515,7 @@ - - From bbf0113c618748497d165a3650ff9159e90fbd48 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 3 Sep 2013 11:07:46 +0200 Subject: [PATCH 24/44] [FIX] stock: inventory yaml test bzr revid: qdp-launchpad@openerp.com-20130903090746-64s7pv9fi212pvi3 --- addons/stock/test/inventory.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/stock/test/inventory.yml b/addons/stock/test/inventory.yml index 6afc7e9d4ba..b687aded288 100644 --- a/addons/stock/test/inventory.yml +++ b/addons/stock/test/inventory.yml @@ -83,8 +83,8 @@ !python {model: stock.inventory}: | inv = self.browse(cr, uid, ref('inventory_test1'), context=context) assert inv.line_ids and len(inv.line_ids) == 1, "Wrong number of inventory lines." - assert len(inv.line_ids[0].product_qty) == 10, "Wrong quantity in inventory line." - assert len(inv.line_ids[0].product_id.id) == ref('inventory_product'), "Wrong product in inventory line." + assert inv.line_ids[0].product_qty == 10, "Wrong quantity in inventory line." + assert inv.line_ids[0].product_id.id == ref('inventory_product'), "Wrong product in inventory line." - I modify the inventory line and set the quantity to 20 product on this new inventory - From 82ef7cb00e12a19e6891376d28692debebca7cfd Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Tue, 3 Sep 2013 11:17:26 +0200 Subject: [PATCH 25/44] [FIX] Creating quants only when usage is correct and prefered_order works without <> bzr revid: jco@openerp.com-20130903091726-l8aeona692964nyu --- addons/stock/stock.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 494105a7784..b922a3c5566 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -750,7 +750,7 @@ class stock_picking(osv.osv): qty = move.remaining_qty qty_to_do -= move.remaining_qty - if create and move.location_id != 'internal': + if create and move.location_id.usage != 'internal': # Create quants vals = { 'product_id': move.product_id.id, @@ -841,7 +841,6 @@ class stock_picking(osv.osv): if res2[move] > 0: mov = stock_move_obj.browse(cr, uid, move, context=context) newmove_id = stock_move_obj.split(cr, uid, mov, res2[move], context=context) - stock_move_obj.action_done(cr, uid, extra_moves + [x.id for x in orig_moves], context=context) picking.refresh() self._create_backorder(cr, uid, picking, context=context) @@ -1505,13 +1504,12 @@ class stock_move(osv.osv): # quant_obj.quants_move(cr, uid, quants, move, location_dest_id, context=context) # should replace the above 2 lines domain = ['|', ('reservation_id', '=', False), ('reservation_id', '=', move.id)] - prefered_order = 'reservation_id<>' + str(move.id) + prefered_order = 'reservation_id' # if lot_id: # prefered_order = 'lot_id<>' + lot_id + ", " + prefered_order # if pack_id: # prefered_order = 'pack_id<>' + pack_id + ", " + prefered_order quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=domain, prefered_order = prefered_order, context=context) - #Will move all quants_get and as such create negative quants quant_obj.quants_move(cr, uid, quants, move, context=context) quant_obj.quants_unreserve(cr, uid, move, context=context) From a19a3ae5b2ae57890fce98c013c34c701f0cb902 Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Tue, 3 Sep 2013 11:26:36 +0200 Subject: [PATCH 26/44] [FIX]stock_complex_route: code_id is now a selection bzr revid: csn@openerp.com-20130903092636-l9448und718n8c0q --- addons/stock_complex_routes/stock_complex_routes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock_complex_routes/stock_complex_routes.xml b/addons/stock_complex_routes/stock_complex_routes.xml index d1850560e5f..f2c71735527 100644 --- a/addons/stock_complex_routes/stock_complex_routes.xml +++ b/addons/stock_complex_routes/stock_complex_routes.xml @@ -14,7 +14,7 @@ dropship - + incoming From 23dfd3bbbcc7c6fb764047a2088b211392fa2473 Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Tue, 3 Sep 2013 11:42:14 +0200 Subject: [PATCH 27/44] [FIX]remove required warehouse_id field on stock_picking_type and remove warehouse_id field from route + rename some route for better understanding bzr revid: csn@openerp.com-20130903094214-i4knuovdvfdn0b9m --- addons/stock/stock.py | 6 ++++-- addons/stock_location/stock_location.py | 8 -------- addons/stock_location/stock_location_data.xml | 6 +++--- addons/stock_location/stock_location_view.xml | 10 ---------- 4 files changed, 7 insertions(+), 23 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index b922a3c5566..4e1d4310b6d 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -2395,7 +2395,9 @@ class stock_picking_type(osv.osv): return res reads = self.browse(cr, uid, ids, context=context) for record in reads: - name = record.warehouse_id.name+': '+record.name + name = record.name + if record.warehouse_id: + name = record.warehouse_id.name+': '+name res.append((record.id, name)) return res @@ -2415,7 +2417,7 @@ class stock_picking_type(osv.osv): 'default_location_dest_id': fields.many2one('stock.location', 'Default Destination Location'), 'code_id': fields.selection([('incoming', 'Suppliers'), ('outgoing', 'Customers'), ('internal', 'Internal')], 'Picking type code', required=True), 'return_picking_type_id': fields.many2one('stock.picking.type', 'Picking Type for Returns'), - 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True), + 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'), # Statistics for the kanban view 'weekly_picking': fields.function(_get_picking_data, diff --git a/addons/stock_location/stock_location.py b/addons/stock_location/stock_location.py index e052063cc3c..bedf59baf1e 100644 --- a/addons/stock_location/stock_location.py +++ b/addons/stock_location/stock_location.py @@ -29,28 +29,20 @@ class stock_location_route(osv.osv): _description = "Inventory Routes" _order = 'sequence' - def _default_warehouse(self, cr, uid, context=None): - user = self.pool.get('res.users').browse(cr, uid, uid, context) - res = self.pool.get('stock.warehouse').search(cr, uid, [('company_id', '=', user.company_id.id)], limit=1, context=context) - return res and res[0] or False - _columns = { 'name': fields.char('Route Name', required=True), 'sequence': fields.integer('Sequence'), 'pull_ids': fields.one2many('procurement.rule', 'route_id', 'Pull Rules'), 'push_ids': fields.one2many('stock.location.path', 'route_id', 'Push Rules'), - 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'), } _defaults = { 'sequence': lambda self,cr,uid,ctx: 0, - 'warehouse_id': _default_warehouse, } class stock_warehouse(osv.osv): _inherit = 'stock.warehouse' _columns = { 'route_id': fields.many2one('stock.location.route', 'Default Logistic Route', help='Default route through the warehouse', required=True), - 'route_ids': fields.one2many('stock.location.route', 'warehouse_id', 'All Routes'), } diff --git a/addons/stock_location/stock_location_data.xml b/addons/stock_location/stock_location_data.xml index b282fcbf08c..c5f438b920a 100644 --- a/addons/stock_location/stock_location_data.xml +++ b/addons/stock_location/stock_location_data.xml @@ -22,7 +22,7 @@ --> - Ship only + Sale: Ship only 20 @@ -79,7 +79,7 @@ - Pack + Ship + Sale: Pack + Ship 15 @@ -128,7 +128,7 @@ - Pick + Pack + Ship + Sale: Pick + Pack + Ship 20 diff --git a/addons/stock_location/stock_location_view.xml b/addons/stock_location/stock_location_view.xml index 34213638b84..f74b2d9321b 100644 --- a/addons/stock_location/stock_location_view.xml +++ b/addons/stock_location/stock_location_view.xml @@ -156,14 +156,6 @@ - - - - - - - - @@ -174,7 +166,6 @@ -
@@ -187,7 +178,6 @@
- From 010a830a32cdf47fb9e54ee4f613cf9b9b883a0a Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 3 Sep 2013 12:11:16 +0200 Subject: [PATCH 28/44] [FIX] stock: yml tests (procrule.yml and move.yml) + [IMP] set mrp_jit as auto_install bzr revid: qdp-launchpad@openerp.com-20130903101116-ruess6702g1xqgsb --- addons/mrp_jit/__openerp__.py | 2 +- addons/mrp_jit/mrp_jit.py | 1 - addons/stock/test/move.yml | 109 ++++++++++++++++++++------------- addons/stock/test/procrule.yml | 9 ++- 4 files changed, 74 insertions(+), 47 deletions(-) diff --git a/addons/mrp_jit/__openerp__.py b/addons/mrp_jit/__openerp__.py index 945ad269db9..b1e4773f99f 100644 --- a/addons/mrp_jit/__openerp__.py +++ b/addons/mrp_jit/__openerp__.py @@ -44,6 +44,6 @@ In that case, you can not use priorities any more on the different picking. 'demo': [], 'test': ['test/mrp_jit.yml'], 'installable': True, - 'auto_install': False, + 'auto_install': True, } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp_jit/mrp_jit.py b/addons/mrp_jit/mrp_jit.py index 01d94692a9d..4ad5cca5f20 100644 --- a/addons/mrp_jit/mrp_jit.py +++ b/addons/mrp_jit/mrp_jit.py @@ -27,7 +27,6 @@ class procurement_order(osv.osv): def create(self, cr, uid, vals, context=None): procurement_id = super(procurement_order, self).create(cr, uid, vals, context=context) - # TODO: maybe this is not necessary anymore as we do this already self.run(cr, uid, [procurement_id], context=context) self.check(cr, uid, [procurement_id], context=context) return procurement_id diff --git a/addons/stock/test/move.yml b/addons/stock/test/move.yml index 696ef6f8976..f2fceb4a2b6 100644 --- a/addons/stock/test/move.yml +++ b/addons/stock/test/move.yml @@ -1,9 +1,15 @@ - - I create a move of 5 products from stock to customer + I first create a new product +- + !record {model: product.product, id: move_product}: + name: move prod + type: product +- + In order to test the negative quants, I create a move of 5 products from stock to customer - !record {model: stock.move, id: move_test0}: name: Move Products - product_id: product.product_product_3 + product_id: move_product product_uom_qty: 5 product_uom: product.product_uom_unit product_uos_qty: 5 @@ -16,63 +22,38 @@ !python {model: stock.move}: | self.action_confirm(cr, uid, [ref('move_test0')], context=context) - - I check that the quantity on hand is 18 and virtual is 13 + I check that the quantity on hand is 0 and virtual is -5 - !python {model: product.product}: | context['location'] = False - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) - assert product.qty_available==18, 'Expecting 18 products in stock, got %.2f!' % (product.qty_available,) - assert product.virtual_available==13.0, 'Expecting 13 products in virtual stock, got %.2f!' % (product.virtual_available,) + product = self.browse(cr, uid, ref('move_product'), context=context) + assert product.qty_available == 0, 'Expecting 0 products in stock, got %.2f!' % (product.qty_available,) + assert product.virtual_available == -5.0, 'Expecting -5 products in virtual stock, got %.2f!' % (product.virtual_available,) - I validate the move - !python {model: stock.move}: | self.action_done(cr, uid, [ref('move_test0')], context=context) - - I check that the quantity on hand is 13 and 5 products are at customer location + I check that the quantity on hand is -5 and 5 products are at customer location - !python {model: product.product}: | context['location'] = False - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) - assert product.qty_available==13, 'Expecting 13 products in stock, got %.2f!' % (product.qty_available,) + product = self.browse(cr, uid, ref('move_product'), context=context) + assert product.qty_available == -5, 'Expecting -5 products in stock, got %.2f!' % (product.qty_available,) context['location'] = ref('stock.stock_location_customers') - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) - assert product.qty_available==5, 'Expecting 5 products in customer location, got %.2f!' % (product.qty_available,) + product = self.browse(cr, uid, ref('move_product'), context=context) + assert product.qty_available == 5, 'Expecting 5 products in customer location, got %.2f!' % (product.qty_available,) - - In order to test negative quants, I will deliver 14 products to the customer -- - !record {model: stock.move, id: move_test1}: - name: Move 14 Products - product_id: product.product_product_3 - product_uom_qty: 14 - product_uom: product.product_uom_unit - product_uos_qty: 14 - product_uos: product.product_uom_unit - location_id: stock.stock_location_stock - location_dest_id: stock.stock_location_customers -- - I confirm and validate the move -- - !python {model: stock.move}: | - self.action_confirm(cr, uid, [ref('move_test1')], context=context) - self.action_done(cr, uid, [ref('move_test1')], context=context) -- - I check that the quantity on hand is -2 -- - !python {model: product.product}: | - context['location'] = False - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) - assert product.qty_available == -1, 'Expecting -1 products in stock, got %.2f!' % (product.qty_available,) -- - To compensate negative quants, I will receive 5 products from the supplier + To compensate negative quants, I will receive 15 products from the supplier - !record {model: stock.move, id: move_test2}: name: Move 15 Products - product_id: product.product_product_3 - product_uom_qty: 5 + product_id: move_product + product_uom_qty: 15 product_uom: product.product_uom_unit - product_uos_qty: 5 + product_uos_qty: 15 product_uos: product.product_uom_unit location_id: stock.stock_location_suppliers location_dest_id: stock.stock_location_stock @@ -83,9 +64,51 @@ self.action_confirm(cr, uid, [ref('move_test2')], context=context) self.action_done(cr, uid, [ref('move_test2')], context=context) - - I check that the quantity on hand is 4 + I check that the quantity on hand is 10 - !python {model: product.product}: | context['location'] = False - product = self.browse(cr, uid, ref('product.product_product_3'), context=context) - assert product.qty_available == 4, 'Expecting 4 products in stock, got %.2f!' % (product.qty_available,) + product = self.browse(cr, uid, ref('move_product'), context=context) + assert product.qty_available == 10, 'Expecting 10 products in stock, got %.2f!' % (product.qty_available,) + assert product.virtual_available == 10.0, 'Expecting 10 products in virtual stock, got %.2f!' % (product.virtual_available,) +- + I create a move of 2 products from stock to customer +- + !record {model: stock.move, id: move_test1}: + name: Move Products + product_id: move_product + product_uom_qty: 2 + product_uom: product.product_uom_unit + product_uos_qty: 2 + product_uos: product.product_uom_unit + location_id: stock.stock_location_stock + location_dest_id: stock.stock_location_customers +- + I confirm the move to be processed in the future +- + !python {model: stock.move}: | + self.action_confirm(cr, uid, [ref('move_test1')], context=context) +- + I check that the quantity on hand is 10 and virtual is 8 +- + !python {model: product.product}: | + context['location'] = False + product = self.browse(cr, uid, ref('move_product'), context=context) + assert product.qty_available == 10, 'Expecting 10 products in stock, got %.2f!' % (product.qty_available,) + assert product.virtual_available == 8.0, 'Expecting 8 products in virtual stock, got %.2f!' % (product.virtual_available,) +- + I validate the move +- + !python {model: stock.move}: | + self.action_done(cr, uid, [ref('move_test1')], context=context) +- + I check that the quantity on hand is 8 and 7 products are at customer location +- + !python {model: product.product}: | + context['location'] = False + product = self.browse(cr, uid, ref('move_product'), context=context) + assert product.qty_available == 8, 'Expecting 10 products in stock, got %.2f!' % (product.qty_available,) + + context['location'] = ref('stock.stock_location_customers') + product = self.browse(cr, uid, ref('move_product'), context=context) + assert product.qty_available == 7, 'Expecting 7 products in customer location, got %.2f!' % (product.qty_available,) diff --git a/addons/stock/test/procrule.yml b/addons/stock/test/procrule.yml index 61d1c920bab..0a13ef6f073 100644 --- a/addons/stock/test/procrule.yml +++ b/addons/stock/test/procrule.yml @@ -25,11 +25,16 @@ - !python {model: stock.picking}: | self.action_confirm(cr, uid, [ref('pick_output')]) +- + I run the scheduler. +- + !python {model: procurement.order}: | + self.run_scheduler(cr, uid) - Check a picking was created from stock to output. - !python {model: stock.move }: | picking = self.pool.get("stock.picking").browse(cr, uid, ref("pick_output")) move_id = self.search(cr, uid, [('product_id', '=', ref('product.product_product_3')),('location_id', '=', ref('stock.stock_location_stock')), - ('location_dest_id', '=', ref('stock.stock_location_output'), ('move_dest_id', '=', picking.move_lines[0].id))]) - assert len(move_id) == 1, "It should have created a picking from Stock to Output with the original picking as destination" \ No newline at end of file + ('location_dest_id', '=', ref('stock.stock_location_output')), ('move_dest_id', '=', picking.move_lines[0].id)]) + assert len(move_id) == 1, "It should have created a picking from Stock to Output with the original picking as destination" From 29a396a9a58c1f1d4c344933c715cec936e93618 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 3 Sep 2013 12:17:36 +0200 Subject: [PATCH 29/44] [IMP] mrp_jit is now installable from warehouse settings bzr revid: qdp-launchpad@openerp.com-20130903101736-nncvdgrdn1f43chu --- addons/mrp/res_config.py | 5 ----- addons/mrp/res_config_view.xml | 4 ---- addons/stock/res_config.py | 5 +++++ addons/stock/res_config_view.xml | 4 ++++ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/addons/mrp/res_config.py b/addons/mrp/res_config.py index 22a14addcd1..840d6c71086 100644 --- a/addons/mrp/res_config.py +++ b/addons/mrp/res_config.py @@ -44,11 +44,6 @@ class mrp_config_settings(osv.osv_memory): Without this module: A + B + C -> D. With this module: A + B + C -> D + E. This installs the module mrp_byproduct."""), - 'module_mrp_jit': fields.boolean("Generate procurement in real time", - help="""This allows Just In Time computation of procurement orders. - All procurement orders will be processed immediately, which could in some - cases entail a small performance impact. - This installs the module mrp_jit."""), 'module_stock_no_autopicking': fields.boolean("Manage manual picking to fulfill manufacturing orders ", help="""This module allows an intermediate picking process to provide raw materials to production orders. For example to manage production made by your suppliers (sub-contracting). diff --git a/addons/mrp/res_config_view.xml b/addons/mrp/res_config_view.xml index 2c7047380a8..25f3e0b0931 100644 --- a/addons/mrp/res_config_view.xml +++ b/addons/mrp/res_config_view.xml @@ -44,10 +44,6 @@