From 038aee2d06f89d97b075d825f9f862b3aabf3dfd Mon Sep 17 00:00:00 2001 From: "Bharat R. Devnani (OpenERP)" Date: Wed, 21 Aug 2013 15:07:42 +0530 Subject: [PATCH 01/25] [IMP] improved the code bzr revid: bde@tinyerp.com-20130821093742-rt0lvwdw98aiwx3w --- addons/stock/procurement.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index 4eeca78e0a1..e0c93957459 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -97,7 +97,6 @@ class procurement_order(osv.osv): move_obj = self.pool.get('stock.move') move_dict = self._run_move_create(cr, uid, procurement, context=context) move_id = move_obj.create(cr, uid, move_dict, context=context) - self.write(cr, uid, procurement.id, {'move_dest_id': move_id}, context=context) move_obj.action_confirm(cr, uid, [move_id], context=context) return move_id return super(procurement_order, self)._run(cr, uid, procurement, context) From 95c6b17bdef105c13627986809247bc899e2fe97 Mon Sep 17 00:00:00 2001 From: "Bharat R. Devnani (OpenERP)" Date: Thu, 22 Aug 2013 15:59:52 +0530 Subject: [PATCH 02/25] [IMP] improved the code bzr revid: bde@tinyerp.com-20130822102952-3kep0jyz0gnbq5fx --- addons/stock/procurement.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index e0c93957459..eae63e50642 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -86,7 +86,7 @@ class procurement_order(osv.osv): 'rule_id': procurement.rule_id.id, 'origin': procurement.origin, 'picking_type_id': procurement.rule_id.picking_type_id.id, - 'price_unit': procurement.sale_line_id.product_id.standard_price + 'price_unit': procurement.sale_line_id.product_id and procurement.sale_line_id.product_id.standard_price, } def _run(self, cr, uid, procurement, context=None): From 79d4ed0b8fd8058ee990ccc2aeefa03de140e1fd Mon Sep 17 00:00:00 2001 From: "Pooja Zankhariya (OpenERP Trainee)" Date: Thu, 22 Aug 2013 18:02:05 +0530 Subject: [PATCH 03/25] [IMP]Improved procurementexception yml bzr revid: pooja.zakhariya@gmail.com-20130822123205-ia2qzcdy0ou7ltbv --- addons/stock_complex_routes/__openerp__.py | 2 +- .../test/procurementexception.yml | 98 ++++++++++++------- 2 files changed, 63 insertions(+), 37 deletions(-) diff --git a/addons/stock_complex_routes/__openerp__.py b/addons/stock_complex_routes/__openerp__.py index 5426e2c7aca..476066a78ed 100644 --- a/addons/stock_complex_routes/__openerp__.py +++ b/addons/stock_complex_routes/__openerp__.py @@ -38,7 +38,7 @@ This adds a route on the sales order and sales order line (mini module) 'init_xml': [], 'update_xml': ['stock_complex_routes.xml'], 'demo_xml': [], - 'test': [], + 'test': ['test/procurementexception.yml'], 'installable': True, 'auto_install': True, } diff --git a/addons/stock_complex_routes/test/procurementexception.yml b/addons/stock_complex_routes/test/procurementexception.yml index 67afc101089..f94bed726f0 100644 --- a/addons/stock_complex_routes/test/procurementexception.yml +++ b/addons/stock_complex_routes/test/procurementexception.yml @@ -1,37 +1,63 @@ -- - Create product with no seller_ids - - -- - Create a sales order with 1 piece for that product and route crossdock -- - !record{sale.order} -- - Confirm sales order -- - !python { -- - Check there is a procurement in exception that has the procurement group of the sales order -- - !python { - assert -- - Adjust the product that it has at least one seller_id -- - !record{id: model: product.product) or in !python -- - Run the Scheduler -- - !python -- - Check the status changed there is no procurement order in exception any more from that procurement group -- - !python{model: procurement.order} - search procurement from -- - Check a purchase quotation was created -- - - - - + I create a product with no supplier define for it. +- + !record {model: product.product, id: product_with_no_seller}: + name: 'product with no seller' + list_price: 20.00 + standard_price: 15.00 + categ_id: product.product_category_1 +- + I create a sales order with this product with route crossdock. +- + !record {model: sale.order, id: sale_order_route_crossdock}: + partner_id: base.res_partner_2 + partner_invoice_id: base.res_partner_address_3 + partner_shipping_id: base.res_partner_address_3 + note: crossdock route + payment_term: account.account_payment_term + order_line: + - product_id: product_with_no_seller + product_uom_qty: 1 + route_id: stock_location.route_warehouse0_crossdock +- + I confirm the sales order. +- + !workflow {model: sale.order, ref: sale_order_route_crossdock, action: order_confirm} +- + I check there is a procurement in exception that has the procurement group of the sales order created before. +- + !python {model: procurement.order}: | + self.run_scheduler(cr, uid) + sale_id = self.pool.get('sale.order').browse(cr, uid, ref("sale_order_route_crossdock")) + proc_id = self.search(cr, uid, [('group_id.name', '=', sale_id.name), ('state', '=', 'exception')]) + assert proc_id, 'No Procurement!' +- + I set the at least one supplier on the product. +- + !record {model: product.product, id: product_with_no_seller}: + seller_ids: + - delay: 1 + name: base.res_partner_2 + min_qty: 2.0 +- + I run the Scheduler. +- + !python {model: procurement.order}: | + sale_id = self.pool.get('sale.order').browse(cr, uid, ref("sale_order_route_crossdock")) + proc_id = self.search(cr, uid, [('group_id.name', '=', sale_id.name), ('state', '=', 'exception')]) + self.run(cr, uid, proc_id) +- + I check the status changed there is no procurement order in exception any more from that procurement group +- + !python {model: procurement.order}: | + sale_id = self.pool.get('sale.order').browse(cr, uid, ref("sale_order_route_crossdock")) + proc_id = self.search(cr, uid, [('group_id.name', '=', sale_id.name), ('state', '=', 'exception')]) + assert not proc_id, 'Procurement should be in running state' +- + I check a purchase quotation was created. +- + !python {model: procurement.order}: | + sale_id = self.pool.get('sale.order').browse(cr, uid, ref("sale_order_route_crossdock")) + proc_ids = self.search(cr, uid, [('group_id.name', '=', sale_id.name)]) + purchase_id = self.browse(cr, uid, proc_ids)[1].purchase_id + assert purchase_id, 'No Purchase Quotation is created' From b42f8b53db1c84c1e07e43bae27347565fef7497 Mon Sep 17 00:00:00 2001 From: "Bharat R. Devnani (OpenERP)" Date: Fri, 23 Aug 2013 12:21:19 +0530 Subject: [PATCH 04/25] [IMP] improved _get_orders method and added _get_orders_procurements method to complete the flow of Sale Order bzr revid: bde@tinyerp.com-20130823065119-6yje7t9nyfi3r5fl --- addons/sale_stock/sale_stock.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index 3163365ffc0..920be1793c1 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -57,11 +57,18 @@ class sale_order(osv.osv): def _get_orders(self, cr, uid, ids, context=None): res = set() - for move in self.browse(cr, uid, ids, context=context): + for move in self.pool.get('stock.move').browse(cr, uid, ids, context=context): if move.procurement_id and move.procurement_id.sale_line_id: res.add(move.procurement_id.sale_line_id.order_id.id) return list(res) - + + def _get_orders_procurements(self, cr, uid, ids, context=None): + res = set() + for proc in self.pool.get('procurement.order').browse(cr, uid, ids, context=context): + if proc.sale_line_id: + res.add(proc.sale_line_id.order_id.id) + return list(res) + def _get_picking_ids(self, cr, uid, ids, name, args, context=None): res = {} for sale in self.browse(cr, uid, ids, context=context): @@ -107,7 +114,10 @@ class sale_order(osv.osv): ('prepaid', 'Before Delivery'), ], 'Create Invoice', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="""On demand: A draft invoice can be created from the sales order when needed. \nOn delivery order: A draft invoice can be created from the delivery order when the products have been delivered. \nBefore delivery: A draft invoice is created from the sales order and must be paid before the products can be delivered."""), - 'shipped': fields.function(_get_shipped, string='Delivered', type='boolean', store={'stock.move': (_get_orders, ['state'], 10)}), + 'shipped': fields.function(_get_shipped, string='Delivered', type='boolean', store={ + 'stock.move': (_get_orders, ['state'], 10), + 'procurement.order': (_get_orders_procurements, ['state'], 10) + }), 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True), 'picking_ids': fields.function(_get_picking_ids, method=True, type='one2many', relation='stock.picking', string='Picking associated to this sale'), } @@ -223,7 +233,7 @@ class sale_order(osv.osv): self.pool.get('sale.order.line').write(cr, uid, write_done_ids, {'state': 'done'}) if write_cancel_ids: self.pool.get('sale.order.line').write(cr, uid, write_cancel_ids, {'state': 'exception'}) - + if mode == 'finished': return finished elif mode == 'canceled': @@ -265,7 +275,7 @@ class sale_order(osv.osv): class sale_order_line(osv.osv): _inherit = 'sale.order.line' - + def _number_packages(self, cr, uid, ids, field_name, arg, context=None): res = {} for line in self.browse(cr, uid, ids, context=context): From b97a9da42dfdbd5ec1bc76f2f0860e4f5f0cce0d Mon Sep 17 00:00:00 2001 From: "Bharat R. Devnani (OpenERP)" Date: Mon, 26 Aug 2013 12:44:05 +0530 Subject: [PATCH 05/25] [REVERT] reverted the changes in _get_orders method bzr revid: bde@tinyerp.com-20130826071405-yax8hqw0esrll766 --- addons/sale_stock/sale_stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index 920be1793c1..015347449ae 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -57,7 +57,7 @@ class sale_order(osv.osv): def _get_orders(self, cr, uid, ids, context=None): res = set() - for move in self.pool.get('stock.move').browse(cr, uid, ids, context=context): + for move in self.browse(cr, uid, ids, context=context): if move.procurement_id and move.procurement_id.sale_line_id: res.add(move.procurement_id.sale_line_id.order_id.id) return list(res) From 30685ddffb634397dc91e3398a0fe0a816d142db Mon Sep 17 00:00:00 2001 From: "Bharat R. Devnani (OpenERP)" Date: Mon, 26 Aug 2013 15:49:14 +0530 Subject: [PATCH 06/25] [IMP] overrided _run_move_create method to get standard price of a product bzr revid: bde@tinyerp.com-20130826101914-24jt4eqx8zqpvvbg --- addons/sale/sale.py | 8 +++++++- addons/stock/procurement.py | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index f733cfd9ff1..fa041b11370 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1082,4 +1082,10 @@ class procurement_order(osv.osv): _defaults = { 'invoice_state': 'none', } - + + 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({ + 'price_unit': procurement.sale_line_id and procurement.sale_line_id.product_id and procurement.sale_line_id.product_id.standard_price or 0.0, + }) + return res diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index eae63e50642..7f36871b9d1 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -86,7 +86,6 @@ class procurement_order(osv.osv): 'rule_id': procurement.rule_id.id, 'origin': procurement.origin, 'picking_type_id': procurement.rule_id.picking_type_id.id, - 'price_unit': procurement.sale_line_id.product_id and procurement.sale_line_id.product_id.standard_price, } def _run(self, cr, uid, procurement, context=None): From 8a3640f70eff3543dccad922ae36a3c77f43a76e Mon Sep 17 00:00:00 2001 From: "Pooja Zankhariya (OpenERP Trainee)" Date: Tue, 27 Aug 2013 14:33:25 +0530 Subject: [PATCH 07/25] [IMP]Improved Code bzr revid: pooja.zakhariya@gmail.com-20130827090325-umd88itb3p16v6ry --- addons/stock_complex_routes/test/procurementexception.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/stock_complex_routes/test/procurementexception.yml b/addons/stock_complex_routes/test/procurementexception.yml index f94bed726f0..e5c7dbfd72c 100644 --- a/addons/stock_complex_routes/test/procurementexception.yml +++ b/addons/stock_complex_routes/test/procurementexception.yml @@ -40,7 +40,7 @@ name: base.res_partner_2 min_qty: 2.0 - - I run the Scheduler. + I run the Procurement. - !python {model: procurement.order}: | sale_id = self.pool.get('sale.order').browse(cr, uid, ref("sale_order_route_crossdock")) @@ -59,5 +59,5 @@ !python {model: procurement.order}: | sale_id = self.pool.get('sale.order').browse(cr, uid, ref("sale_order_route_crossdock")) proc_ids = self.search(cr, uid, [('group_id.name', '=', sale_id.name)]) - purchase_id = self.browse(cr, uid, proc_ids)[1].purchase_id + purchase_id = [proc.purchase_id for proc in self.browse(cr, uid, proc_ids) if proc.purchase_id] assert purchase_id, 'No Purchase Quotation is created' From cc4764f48fde77fc37f77d6e6e318a811da01e60 Mon Sep 17 00:00:00 2001 From: "Bharat R. Devnani (OpenERP)" Date: Tue, 27 Aug 2013 14:42:17 +0530 Subject: [PATCH 08/25] [REVERT] reverted price_unit changes bzr revid: bde@tinyerp.com-20130827091217-9l7wbz2v6weaxuoz --- addons/sale/sale.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 354a3b48301..83ec686b898 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1082,10 +1082,4 @@ class procurement_order(osv.osv): _defaults = { 'invoice_state': 'none', } - - 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({ - 'price_unit': procurement.sale_line_id and procurement.sale_line_id.product_id and procurement.sale_line_id.product_id.standard_price or 0.0, - }) - return res + \ No newline at end of file From 72e1113082a87664c3f52ec25b8ced327fe896e5 Mon Sep 17 00:00:00 2001 From: "Bharat R. Devnani (OpenERP)" Date: Tue, 27 Aug 2013 15:47:09 +0530 Subject: [PATCH 09/25] [IMP] assigned picking_policy of SO in move_type of procurement.group bzr revid: bde@tinyerp.com-20130827101709-8mp60l9rke2rpcqj --- addons/sale/sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 83ec686b898..6535ed7bc6d 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -658,7 +658,7 @@ class sale_order(osv.osv): for order in self.browse(cr, uid, ids, context=context): proc_ids = [] group_id = self.pool.get("procurement.group").create(cr, uid, { - 'name': order.name, 'partner_id': order.partner_shipping_id.id + 'name': order.name, 'partner_id': order.partner_shipping_id.id, 'move_type': order.picking_policy }, context=context) order.write({'procurement_group_id': group_id}, context=context) for line in order.order_line: From b1611b9fa7332d46c1959841685d93d76b176003 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Thu, 29 Aug 2013 11:53:27 +0200 Subject: [PATCH 10/25] [IMP] Remove procure_method in timesheet (branch bde) bzr revid: jco@openerp.com-20130829095327-jn9b06q1b3g3n07i --- .../test/worktask_entry_to_timesheetline_entry.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/project_timesheet/test/worktask_entry_to_timesheetline_entry.yml b/addons/project_timesheet/test/worktask_entry_to_timesheetline_entry.yml index 99e5fc41401..2d95eb89d71 100644 --- a/addons/project_timesheet/test/worktask_entry_to_timesheetline_entry.yml +++ b/addons/project_timesheet/test/worktask_entry_to_timesheetline_entry.yml @@ -14,8 +14,7 @@ !record {model: product.product, id: product_product_hrmanger0}: categ_id: product.product_category_6 mes_type: fixed - name: HR Manger - procure_method: make_to_stock + name: HR Manager standard_price: 1.0 supply_method: buy type: service From c729a2529fc0e2e70ea8842724ca96f990397907 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Thu, 29 Aug 2013 15:28:33 +0530 Subject: [PATCH 11/25] [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 12/25] [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 9cd5e3f2f7600ef9d69f5222a29f464a517a3360 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Thu, 29 Aug 2013 17:00:13 +0530 Subject: [PATCH 13/25] [IMP/ADD]dropship yml improve and add crossdock yml bzr revid: sgo@tinyerp.com-20130829113013-cqcpzoulg88lbdu2 --- addons/purchase/purchase.py | 2 + addons/stock_complex_routes/__openerp__.py | 6 +- .../stock_complex_routes/test/crossdock.yml | 38 +++++++ addons/stock_complex_routes/test/dropship.yml | 98 ++++++++++++------- 4 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 addons/stock_complex_routes/test/crossdock.yml diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 660b70a488c..8efacf7f75e 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -386,6 +386,8 @@ class purchase_order(osv.osv): ''' This function returns an action that display existing picking orders of given purchase order ids. ''' + if context is None: + context = {} mod_obj = self.pool.get('ir.model.data') pick_ids = [] for po in self.browse(cr, uid, ids, context=context): diff --git a/addons/stock_complex_routes/__openerp__.py b/addons/stock_complex_routes/__openerp__.py index 872f42d98b5..0b2110b3eda 100644 --- a/addons/stock_complex_routes/__openerp__.py +++ b/addons/stock_complex_routes/__openerp__.py @@ -38,7 +38,11 @@ This adds a route on the sales order and sales order line (mini module) 'init_xml': [], 'update_xml': ['stock_complex_routes.xml'], 'demo_xml': [], - 'test': ['test/lifo_price.yml'], + 'test': [ + 'test/crossdock.yml', + 'test/dropship.yml', + 'test/lifo_price.yml' + ], 'installable': True, 'auto_install': True, } diff --git a/addons/stock_complex_routes/test/crossdock.yml b/addons/stock_complex_routes/test/crossdock.yml new file mode 100644 index 00000000000..dfdd08330b7 --- /dev/null +++ b/addons/stock_complex_routes/test/crossdock.yml @@ -0,0 +1,38 @@ +- + Create new product without any routes +- + !record {model: product.product, id: cross_shop_product}: + name: PCE + 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 + type: product + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit +- + Create a sales order with a line of 100 PCE incoming shipment, with route_id crossdock shipping. +- + !record {model: sale.order, id: sale_order_crossdock_shpng}: + partner_id: base.res_partner_4 + note: Create Sales order + order_line: + - product_id: cross_shop_product + product_uom_qty: 100.00 + route_id: stock_location.route_warehouse0_crossdock +- + Confirm sales order +- + !python {model: sale.order}: | + self.action_button_confirm(cr, uid, [ref('sale_order_crossdock_shpng')]) +- + Check a quotation was created to a certain supplier and confirm so it becomes a confirmed purchase order +- + !python {model: purchase.order}: | + po_id = self.search(cr, uid, [('partner_id', '=', ref('base.res_partner_2'))]) + self.wkf_confirm_order(cr, uid, po_id) diff --git a/addons/stock_complex_routes/test/dropship.yml b/addons/stock_complex_routes/test/dropship.yml index 7bcb1b93a71..e63d072a118 100644 --- a/addons/stock_complex_routes/test/dropship.yml +++ b/addons/stock_complex_routes/test/dropship.yml @@ -1,53 +1,77 @@ - - Create new product without any routes + Create new product without any routes - - !record {model:product.product, id:} + !record {model: product.product, id: drop_shop_product}: + name: Pen drive + 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 a sales order with a line of 200 PCE incoming shipment, with route_id drop shipping + Create a sales order with a line of 200 PCE incoming shipment, with route_id drop shipping. - - !record {model: sale.order, id: } : - customer: - - product_id: - product_qty: 200 - product_uom: - supplier_ids: - - + !record {model: sale.order, id: sale_order_drp_shpng}: + partner_id: base.res_partner_2 + note: Create sale order for drop shipping + payment_term: account.account_payment_term + order_line: + - product_id: drop_shop_product + product_uom_qty: 200 + price_unit: 100.00 + route_id: route_drop_shipping - - Confirm sales order + Confirm sales order - - !python{model: sale.order}: | - self.browse(cr, uid, ref()).action_b + !workflow {model: sale.order, action: order_confirm, ref: sale_order_drp_shpng} - - Check the sales order created a procurement group which has a procurement of 200 pieces + Check the sales order created a procurement group which has a procurement of 200 pieces - - !python{model: procurement.group}: | - proc_group = self.search(cr, uid, [('sale_id', '=', ref())]) - assert self.browse(cr, uid, proc_group)[0].procurement_ids[0].product_qty == 200 + !python {model: procurement.group}: | + sale_record = self.pool.get("sale.order").browse(cr, uid, ref('sale_order_drp_shpng')) + assert self.browse(cr, uid, sale_record.procurement_group_id.id).procurement_ids[0].product_qty == 200 - - Check a quotation was created to a certain supplier and confirm so it becomes a confirmed purchase order + Check a quotation was created to a certain supplier and confirm so it becomes a confirmed purchase order +- + !python {model: purchase.order}: | + from openerp import netsvc + sale_record = self.pool.get("sale.order").browse(cr, uid, ref('sale_order_drp_shpng')) + procurement_order = self.pool.get("procurement.group").browse(cr, uid, sale_record.procurement_group_id.id).procurement_ids[0] + purchase_id = procurement_order.purchase_id.id + wf_service = netsvc.LocalService('workflow') + wf_service.trg_validate(uid, 'purchase.order', purchase_id, 'purchase_confirm', cr) - - + Use 'Receive Products' button to immediately view this picking, it should have created a picking with 200 pieces.. +- + !python {model: purchase.order}: | + po_id = self.search(cr, uid, [('partner_id', '=', ref('base.res_partner_2'))]) + picking_id = self.search(cr, uid, [('purchase_id', '=', po_id[0])]) + context.update({'active_model': 'stock.picking', 'active_id': backorder_id[0], 'active_ids': backorder_id}) + self.view_picking(cr, uid, po_id) +- + Send the 200 pieces. - - Check the sales order has one picking with 200 pieces + !python {model: stock.picking}: | + po_id = self.pool.get('purchase.order').search(cr, uid, [('partner_id', '=', ref('base.res_partner_2'))]) + picking_id = self.search(cr, uid, [('purchase_id', '=', po_id[0])]) + self.do_partial(cr, uid, picking_id) - - !python{model: sale.order}: | - assert len(self.browse(cr, uid, ref()).picking_ids) == 1 + Check one quant was created in Customers location with 200 pieces and one move in the history_ids - - Use 'View Delivery Order' button to immediately view this picking and check shipped of purchase order is False -- - -- - Send the 200 pieces -- - !python{model: stock.partial.picking}: | - - -- - Check one quant was created in Customers location with 200 pieces and one move in the move_history_ids -- - + !python {model: stock.quant}: | + quant_id = self.search(cr, uid, [('location_id', '=', ref('stock.stock_location_customers')),('qty', '=', 200)]) + assert len(self.browse(cr, uid, quant_id)[0].history_ids) == 1 + assert len(quant_id) == 1 - Check the sum of the moves related to this product and the sum of the quants is equal - - + !python {model: stock.quant}: | + move_ids = self.pool.get('stock.move').search(cr, uid, [('product_id', '=', ref('drop_shop_product'))]) + quant_ids = self.search(cr, uid, [('product_id', '=', ref('drop_shop_product'))]) + assert len(move_ids) == len(quant_ids) From fd88e3fd232f721ff2c597f851685a5af617bd69 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Thu, 29 Aug 2013 17:05:01 +0530 Subject: [PATCH 14/25] [IMP]improve code used sale order confirm workflow instead of method bzr revid: sgo@tinyerp.com-20130829113501-cvxtjp3e0i7f27ma --- addons/stock_complex_routes/test/crossdock.yml | 3 +-- addons/stock_complex_routes/test/dropship.yml | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/addons/stock_complex_routes/test/crossdock.yml b/addons/stock_complex_routes/test/crossdock.yml index dfdd08330b7..e757cbfd554 100644 --- a/addons/stock_complex_routes/test/crossdock.yml +++ b/addons/stock_complex_routes/test/crossdock.yml @@ -28,8 +28,7 @@ - Confirm sales order - - !python {model: sale.order}: | - self.action_button_confirm(cr, uid, [ref('sale_order_crossdock_shpng')]) + !workflow {model: sale.order, action: order_confirm, ref: sale_order_crossdock_shpng} - Check a quotation was created to a certain supplier and confirm so it becomes a confirmed purchase order - diff --git a/addons/stock_complex_routes/test/dropship.yml b/addons/stock_complex_routes/test/dropship.yml index e63d072a118..9b3a786acd1 100644 --- a/addons/stock_complex_routes/test/dropship.yml +++ b/addons/stock_complex_routes/test/dropship.yml @@ -51,8 +51,6 @@ - !python {model: purchase.order}: | po_id = self.search(cr, uid, [('partner_id', '=', ref('base.res_partner_2'))]) - picking_id = self.search(cr, uid, [('purchase_id', '=', po_id[0])]) - context.update({'active_model': 'stock.picking', 'active_id': backorder_id[0], 'active_ids': backorder_id}) self.view_picking(cr, uid, po_id) - Send the 200 pieces. From 6d7f4b4f08897b8ebcf715956b6b86946b8350a7 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (OpenERP)" Date: Thu, 29 Aug 2013 18:30:56 +0530 Subject: [PATCH 15/25] [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 48f217177953cd6ecc38b4966ead137a0a1dd886 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Thu, 29 Aug 2013 15:02:07 +0200 Subject: [PATCH 16/25] [WIP] Split of moves bzr revid: jco@openerp.com-20130829130207-vablfdmy0hfq8ar8 --- addons/stock/stock.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 740e60b9a50..7ece3c202dc 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -332,7 +332,7 @@ class stock_quant(osv.osv): def quants_unreserve(self, cr, uid, move, context=None): #cr.execute('update stock_quant set reservation_id=NULL where reservation_id=%s', (move.id,)) #need write for related store of remaining qty - related_quants = self.search(cr, uid, [('reservation_id', '=', move.id)], context=context) + related_quants = [x.id for x in move.reserved_quant_ids] self.write(cr, uid, related_quants, {'reservation_id': False}, context=context) return True @@ -1442,6 +1442,8 @@ class stock_move(osv.osv): """ context = context or {} for move in self.browse(cr, uid, ids, context=context): + if move.reserved_quant_ids: + self.pool.get("stock.quant").quants_unreserve(cr, uid, move, context=context) if move.move_dest_id: if move.propagate: self.action_cancel(cr, uid, [move.move_dest_id.id], context=context) @@ -1616,10 +1618,9 @@ class stock_move(osv.osv): return res def split(self, cr, uid, move, qty, context=None): - """ Partially (or not) moves a stock.move. - @param partial_datas: Dictionary containing details of partial picking - like partner_id, delivery_date, delivery - moves with product_id, product_qty, uom + """ + 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 @@ -1648,6 +1649,9 @@ class stock_move(osv.osv): 'product_uos_qty': move.product_uos_qty - uos_qty, # 'reserved_quant_ids': [(6,0,[])] SHOULD NOT CHANGE as it has been reserved already }, context=context) + + if move.move_dest_id and move.propagate: + self.split(self, cr, uid, move.move_dest_id, qty, context=context) return new_move class stock_inventory(osv.osv): @@ -1925,7 +1929,7 @@ report_sxw.report_sxw('report.stock.quant.package.barcode', 'stock.quant.package class stock_package(osv.osv): """ - These are the packages, containing quants and/or others packages + These are the packages, containing quants and/or other packages """ _name = "stock.quant.package" _description = "Physical Packages" From 6d55144ca9c4d3bfd12a9f9d5df55cbd16652998 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Thu, 29 Aug 2013 15:05:29 +0200 Subject: [PATCH 17/25] [IMP] Correct error from merge bzr revid: jco@openerp.com-20130829130529-1nuyi9qijuh9cyw6 --- addons/stock_complex_routes/test/dropship.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/addons/stock_complex_routes/test/dropship.yml b/addons/stock_complex_routes/test/dropship.yml index 9b3a786acd1..a8f19969dc4 100644 --- a/addons/stock_complex_routes/test/dropship.yml +++ b/addons/stock_complex_routes/test/dropship.yml @@ -66,10 +66,3 @@ quant_id = self.search(cr, uid, [('location_id', '=', ref('stock.stock_location_customers')),('qty', '=', 200)]) assert len(self.browse(cr, uid, quant_id)[0].history_ids) == 1 assert len(quant_id) == 1 -- - Check the sum of the moves related to this product and the sum of the quants is equal -- - !python {model: stock.quant}: | - move_ids = self.pool.get('stock.move').search(cr, uid, [('product_id', '=', ref('drop_shop_product'))]) - quant_ids = self.search(cr, uid, [('product_id', '=', ref('drop_shop_product'))]) - assert len(move_ids) == len(quant_ids) From 81cb96eb9290f3e890620fd1506d4f88c3a0fd8b Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Thu, 29 Aug 2013 18:04:33 +0200 Subject: [PATCH 18/25] [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 19/25] [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 20/25] [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 21/25] [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 0dba7a7d4aaeb5b08f5bcdd5d37a4786ea0994b5 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 30 Aug 2013 15:25:07 +0200 Subject: [PATCH 22/25] [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 23/25] [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 24/25] [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 25/25] [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' }