openerp-community-reviewer team mailing list archive
-
openerp-community-reviewer team
-
Mailing list archive
-
Message #00156
lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
Alexandre Fayolle - camptocamp has proposed merging lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0.
Requested reviews:
Nicolas Bessi - Camptocamp (nbessi-c2c)
For more details, see:
https://code.launchpad.net/~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe/+merge/187772
[ADD] stock_recompute_availability_on_force
when forcing a picking availability, recompute availability of other pickings which could be affected by the forcing
--
https://code.launchpad.net/~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe/+merge/187772
Your team Stock and Logistic Core Editors is subscribed to branch lp:stock-logistic-flows/7.0.
=== added directory 'stock_recompute_availability_on_force'
=== added file 'stock_recompute_availability_on_force/__init__.py'
--- stock_recompute_availability_on_force/__init__.py 1970-01-01 00:00:00 +0000
+++ stock_recompute_availability_on_force/__init__.py 2013-09-26 13:14:02 +0000
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Alexandre Fayolle
+# Copyright 2013 Camptocamp SA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from . import stock
=== added file 'stock_recompute_availability_on_force/__openerp__.py'
--- stock_recompute_availability_on_force/__openerp__.py 1970-01-01 00:00:00 +0000
+++ stock_recompute_availability_on_force/__openerp__.py 2013-09-26 13:14:02 +0000
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Alexandre Fayolle
+# Copyright 2013 Camptocamp SA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+{
+ 'name' : 'Recompute stock move state on Force Availability',
+ 'version' : '0.1',
+ 'category' : 'Warehouse Management',
+ 'description': '''
+ When the user forced availability of a stock.picking, recompute the availability of other pickings which could be affected by this forcing.
+ ''',
+ 'author' : 'Camptocamp',
+ 'website' : 'http://www.camptocamp.com',
+ 'depends' : ['stock', 'procurement'],
+ 'data' : ['procurement_workflow.xml',
+ ],
+ 'demo' : [],
+ 'test' : [],
+ 'installable': True,
+ 'auto_install' : False,
+ 'application' : False,
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'stock_recompute_availability_on_force/procurement_workflow.xml'
--- stock_recompute_availability_on_force/procurement_workflow.xml 1970-01-01 00:00:00 +0000
+++ stock_recompute_availability_on_force/procurement_workflow.xml 2013-09-26 13:14:02 +0000
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record id="trans_ready_confirm" model="workflow.transition">
+ <field name="act_from" ref="procurement.act_make_done"/>
+ <field name="act_to" ref="procurement.act_confirm"/>
+ <field name="condition">check_cancel_assigned_moves()</field>
+ <field name="signal">button_recompute_availability</field>
+ </record>
+
+ </data>
+</openerp>
=== added file 'stock_recompute_availability_on_force/stock.py'
--- stock_recompute_availability_on_force/stock.py 1970-01-01 00:00:00 +0000
+++ stock_recompute_availability_on_force/stock.py 2013-09-26 13:14:02 +0000
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Alexandre Fayolle
+# Copyright 2013 Camptocamp SA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import logging
+from openerp.osv import orm
+from openerp import netsvc
+
+_logger = logging.getLogger(__name__)
+
+class stock_picking(orm.Model):
+ _inherit = 'stock.picking'
+
+ def force_assign(self, cr, uid, ids, *args):
+ """
+ when forcing availability on a picking, get the procurements
+ for all the assigned moves for the same product on the same
+ stock location, and send the recompute_availability signal to
+ reset them in confirmed state. The scheduler can then be run
+ to recompute availability.
+ """
+ _logger.debug('stock.picking force_assign %s', ids)
+ move_obj = self.pool.get('stock.move')
+ procurement_obj = self.pool.get('procurement.order')
+ product_locations = set()
+ for pick in self.browse(cr, uid, ids):
+ for move in pick.move_lines:
+ product_locations.add((move.product_id.id, move.location_id.id))
+ res = super(stock_picking, self).force_assign(cr, uid, ids, *args)
+ other_move_ids = []
+ for product_id, location_id in product_locations:
+ other_move_ids += move_obj.search(cr, uid,
+ [('product_id', '=', product_id),
+ ('location_id', '=', location_id),
+ ('state', '=', 'assigned'),
+ ('picking_id', 'not in', ids),
+ ])
+ procurement_ids = procurement_obj.search(cr, uid,
+ [('move_id', 'in', other_move_ids),
+ ('procure_method', '=', 'make_to_stock'),
+ ])
+ move_ids = [proc.move_id.id for proc in procurement_obj.browse(cr, uid, procurement_ids)]
+ move_obj.cancel_assign(cr, uid, move_ids)
+ wf_service = netsvc.LocalService("workflow")
+ for proc_id in procurement_ids:
+ _logger.debug('button_recompute_availability on procurement.order %d', proc_id)
+ wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_recompute_availability', cr)
+ our_procurement_ids = procurement_obj.search(cr, uid, [('move_id.picking_id', 'in', ids)])
+ for proc_id in our_procurement_ids:
+ _logger.debug('button_check on procurement.order %d', proc_id)
+ wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_check', cr)
+ return res
+
+class stock_picking_in(orm.Model):
+ _inherit = 'stock.picking.in'
+ def force_assign(self, cr, uid, ids, *args):
+ return self.pool.get('stock.picking').force_assign(cr, uid, ids, *args)
+
+class stock_picking_out(orm.Model):
+ _inherit = 'stock.picking.out'
+ def force_assign(self, cr, uid, ids, *args):
+ return self.pool.get('stock.picking').force_assign(cr, uid, ids, *args)
+
+
+class procurement_order(orm.Model):
+ _inherit = 'procurement.order'
+
+ def check_cancel_assigned_moves(self, cr, uid, ids, context=None):
+ return all(procurement.move_id.state == 'confirmed' for procurement in self.browse(cr, uid, ids, context=context))
=== added file 'stock_recompute_availability_on_force/stock_view.xml'
--- stock_recompute_availability_on_force/stock_view.xml 1970-01-01 00:00:00 +0000
+++ stock_recompute_availability_on_force/stock_view.xml 2013-09-26 13:14:02 +0000
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+
+ </data>
+</openerp>
=== added directory 'stock_recompute_availability_on_force/test'
=== added directory 'stock_recompute_availability_on_force/tests'
=== added file 'stock_recompute_availability_on_force/tests/__init__.py'
--- stock_recompute_availability_on_force/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ stock_recompute_availability_on_force/tests/__init__.py 2013-09-26 13:14:02 +0000
@@ -0,0 +1,5 @@
+from . import test_force_recompute
+
+checks = [
+ test_force_recompute,
+]
=== added file 'stock_recompute_availability_on_force/tests/test_force_recompute.py'
--- stock_recompute_availability_on_force/tests/test_force_recompute.py 1970-01-01 00:00:00 +0000
+++ stock_recompute_availability_on_force/tests/test_force_recompute.py 2013-09-26 13:14:02 +0000
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+
+import logging
+
+from openerp import tools
+from openerp.tests import common
+from openerp import netsvc
+
+_logger = logging.getLogger('openerp.test.force_recompute')
+
+class TestForceRecompute(common.TransactionCase):
+
+ def setUp(self):
+ super(TestForceRecompute, self).setUp()
+ cr, uid = self.cr, self.uid
+ self.procurement = self.registry('procurement.order')
+ self.stock_move = self.registry('stock.move')
+ self.stock_picking = self.registry('stock.picking.out')
+ self.stock_location = self.registry('stock.location')
+ self.product_product = self.registry('product.product')
+ self.res_partner = self.registry('res.partner')
+ self.wf_service = netsvc.LocalService("workflow")
+
+ #
+ # create picking and procurement for CARD
+ #
+
+ prod_id = self.product_product.search(cr, uid, [('default_code', '=', 'CARD')])[0]
+ location_data = self.stock_location.default_get(cr, uid,['active', 'usage',
+ 'chained_location_type',
+ 'chainged_auto_packing',
+ 'company_id',
+ 'posx', 'posy', 'posz', 'icon',
+ 'scrap_location'])
+ location_data.update({'name': 'test', 'usage': 'internal'})
+ location_id = self.stock_location.create(cr, uid, location_data)
+ location_dest_id = self.stock_location.search(cr, uid, [('name', '=', 'Customers')])[0]
+ location_supplier_id = self.stock_location.search(cr, uid, [('name', '=', 'Suppliers')])[0]
+ move_data = self.stock_move.default_get(cr, uid,
+ ['state', 'company_id', 'priority', 'scrapped', 'date', 'date_expected'])
+ move_data.update({'product_id': prod_id,
+ 'product_qty': 15,
+ 'product_uom': 1,
+ 'location_dest_id': location_id,
+ 'location_id': location_supplier_id,
+ 'name': 'initial inventory'})
+ move_id = self.stock_move.create(cr, uid, move_data)
+ self.stock_move.action_done(cr, uid, [move_id])
+ self.picking_ids = []
+ self.procurement_ids = []
+ for i in range(2):
+ picking_data = self.stock_picking.default_get(cr, uid,
+ ['company_id', 'name', 'state', 'move_type', 'type', 'invoice_state', 'date'])
+ move_data = self.stock_move.default_get(cr, uid,
+ ['state', 'company_id', 'priority', 'scrapped', 'date', 'date_expected'])
+ proc_data = self.procurement.default_get(cr, uid, ['state', 'priority', 'date_planned', 'close_move', 'company_id'])
+ picking_id = self.stock_picking.create(cr, uid,
+ picking_data)
+ self.picking_ids.append(picking_id)
+ move_data.update({'location_id': location_id,
+ 'location_dest_id': location_dest_id,
+ 'product_id': prod_id,
+ 'product_qty': 10,
+ 'product_uom': 1,
+ 'partner_id': self.res_partner.search(cr, uid, [('name', '=', 'Camptocamp')])[0],
+ 'picking_id': picking_id,
+ 'name': 'test move card',
+ })
+ move_id = self.stock_move.create(cr, uid, move_data)
+ proc_data.update({'name': 'test procurement',
+ 'product_id': prod_id,
+ 'product_qty': 10,
+ 'product_uom': 1,
+ 'procure_method': 'make_to_stock',
+ 'location_id': location_id,
+ 'move_id': move_id
+ })
+ procurement_id = self.procurement.create(cr, uid, proc_data)
+ self.procurement_ids.append(procurement_id)
+ self.wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
+ self.wf_service.trg_validate(uid, 'procurement.order', procurement_id, 'button_confirm', cr)
+ self.wf_service.trg_validate(uid, 'procurement.order', procurement_id, 'button_check', cr)
+
+ def test_setup(self):
+ cr, uid = self.cr, self.uid
+ picking1 = self.stock_picking.browse(cr, uid, self.picking_ids[0])
+ self.assertEqual(picking1.state, 'assigned')
+ procurement1 = self.procurement.browse(cr, uid, self.procurement_ids[0])
+ self.assertEqual(procurement1.state, 'ready')
+ picking2 = self.stock_picking.browse(cr, uid, self.picking_ids[1])
+ self.assertEqual(picking2.state, 'confirmed')
+ procurement2 = self.procurement.browse(cr, uid, self.procurement_ids[1])
+ self.assertEqual(procurement2.state, 'exception')
+
+ def test_force_assign(self):
+ cr, uid = self.cr, self.uid
+ self.stock_picking.force_assign(cr, uid, [self.picking_ids[1]])
+ # tests
+ picking2 = self.stock_picking.browse(cr, uid, self.picking_ids[1])
+ for move in picking2.move_lines:
+ self.assertEqual(move.state, 'assigned')
+ self.assertEqual(picking2.state, 'assigned')
+ procurement2 = self.procurement.browse(cr, uid, self.procurement_ids[1])
+ self.assertEqual(procurement2.state, 'ready')
+ picking1 = self.stock_picking.browse(cr, uid, self.picking_ids[0])
+ for move in picking1.move_lines:
+ self.assertEqual(move.state, 'confirmed')
+ self.assertEqual(picking1.state, 'confirmed')
+ procurement1 = self.procurement.browse(cr, uid, self.procurement_ids[0])
+ self.assertEqual(procurement1.state, 'confirmed')
+
Follow ups
-
Re: [Merge] lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows
From: Yannick Vaucher @ Camptocamp, 2014-02-21
-
Re: lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows
From: Lionel Sausin - Numérigraphe, 2014-01-24
-
lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
From: Maxime Chambreuil (http://www.savoirfairelinux.com), 2013-12-27
-
Re: lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
From: Alexandre Fayolle - camptocamp, 2013-11-29
-
Re: lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
From: Lionel Sausin - Numérigraphe, 2013-11-07
-
Re: lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
From: Lionel Sausin - Numérigraphe, 2013-11-07
-
Re: lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
From: Joël Grand-Guillaume, 2013-10-08
-
Re: lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
From: Quentin THEURET @TeMPO Consulting, 2013-10-03
-
Re: lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
From: Nicolas Bessi - Camptocamp, 2013-09-27
-
Re: lp:~camptocamp/stock-logistic-flows/7.0-add-stock_recompute_availability_on_force-afe into lp:stock-logistic-flows/7.0
From: Nicolas Bessi - Camptocamp, 2013-09-26