Romain Deheele - Camptocamp has proposed merging lp:~camptocamp/stock-logistic-flows/7.0-picking_dispatch_wave-according-defined-number-of-sales_rde into lp:stock-logistic-flows.
Requested reviews: Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c): code review, no test For more details, see: https://code.launchpad.net/~camptocamp/stock-logistic-flows/7.0-picking_dispatch_wave-according-defined-number-of-sales_rde/+merge/214568 Hello, This MP adds an addon named picking_dispatch_wave, the principle : - Allows to set a 'sale order wave' to pick according a number n of sales that you set. 1.The picker sets a number n of sale orders. 2.The wizard will select moves from n oldest sales that are linked to ready pickings. 3.A picking dispatch is created with found moves Regards, Romain -- https://code.launchpad.net/~camptocamp/stock-logistic-flows/7.0-picking_dispatch_wave-according-defined-number-of-sales_rde/+merge/214568 Your team Stock and Logistic Core Editors is subscribed to branch lp:stock-logistic-flows.
=== added directory 'picking_dispatch_wave' === added file 'picking_dispatch_wave/__init__.py' --- picking_dispatch_wave/__init__.py 1970-01-01 00:00:00 +0000 +++ picking_dispatch_wave/__init__.py 2014-04-14 09:33:05 +0000 @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Alexandre Fayolle, Romain Deheele +# Copyright 2014 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 dispatch_wave # noqa === added file 'picking_dispatch_wave/__openerp__.py' --- picking_dispatch_wave/__openerp__.py 1970-01-01 00:00:00 +0000 +++ picking_dispatch_wave/__openerp__.py 2014-04-14 09:33:05 +0000 @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Alexandre Fayolle, Romain Deheele +# Copyright 2014 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": "Picking Dispatch Wave", + "version": "0.1", + "depends": ['picking_dispatch', 'sale_stock'], + "author": "Camptocamp", + 'license': 'AGPL-3', + "description": """Allows to set a wave to pick +according the number of sales/pickings that you set: + +* The picker sets a number n of pickings to done. + +* The wizard will select moves from n pickings with oldest min_date. + +* A picking dispatch is created with found moves""", + "website": "http://www.camptocamp.com", + "category": "Warehouse Management", + "demo": [], + "data": ['dispatch_wave_view.xml'], + "test": ['test/test_dispatch_wave.yml'], + "installable": True, +} === added file 'picking_dispatch_wave/dispatch_wave.py' --- picking_dispatch_wave/dispatch_wave.py 1970-01-01 00:00:00 +0000 +++ picking_dispatch_wave/dispatch_wave.py 2014-04-14 09:33:05 +0000 @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Alexandre Fayolle, Romain Deheele +# Copyright 2014 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, fields +from openerp.tools.translate import _ +_logger = logging.getLogger(__name__) + + +class StockPickingDispatchWave(orm.TransientModel): + _name = "stock.picking.dispatch.wave" + + def _get_pickings_to_done(self, cr, uid, nb, context=None): + context = context or {} + move_obj = self.pool['stock.move'] + move_ids = [] + picking_ids = [] + move_ids = move_obj.search(cr, uid, + [('dispatch_id', '=', False), + ('state', '=', 'assigned'), + ('type', '=', 'out')], + order='date_expected DESC', + context=context) + for move in move_obj.browse(cr, uid, move_ids, context=context): + if len(picking_ids) == nb: + break + if move.picking_id.id not in picking_ids: + picking_ids.append(move.picking_id.id) + return picking_ids + + def _get_moves_from_picking_list(self, cr, uid, picking_ids, context=None): + context = context or {} + move_obj = self.pool['stock.move'] + move_ids = move_obj.search(cr, uid, + [('picking_id', 'in', picking_ids)], + context=context) + return move_ids + + def _get_moves_from_pickings_to_done(self, cr, uid, nb, context=None): + context = context or {} + move_ids = [] + picking_ids = self._get_pickings_to_done(cr, uid, nb, context=context) + if picking_ids: + move_ids = self._get_moves_from_picking_list(cr, uid, picking_ids, + context=context) + return move_ids + + + _columns = { + 'nb': fields.integer('How many sales?'), + 'picker_id': fields.many2one('res.users', 'Picker', required=True, + help='the user to which the pickings ' + 'are assigned'), + } + _defaults = { + 'nb': 0, + 'picker_id': lambda self, cr, uid, ctx: uid, + } + + def action_create_picking_dispatch(self, cr, uid, ids, context=None): + context = context or {} + wave = self.browse(cr, uid, ids, context=context)[0] + if wave.nb: + # we base search on pickings instead of sales: + # in most cases, it provides a very similar result + move_ids = self._get_moves_from_pickings_to_done(cr, uid, + wave.nb, + context=context) + if move_ids: + # create picking_dispatch + dispatch_obj = self.pool['picking.dispatch'] + dispatch_vals = { + 'picker_id': wave.picker_id.id + } + dispatch_id = dispatch_obj.create(cr, uid, + dispatch_vals, + context=context) + # affect move_ids on the new dispatch + self.pool['stock.move'].write(cr, uid, move_ids, + {'dispatch_id': dispatch_id}, + context=context) + context['active_id'] = dispatch_id + return { + 'domain': str([('id', '=', dispatch_id)]), + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'picking.dispatch', + 'type': 'ir.actions.act_window', + 'context': context, + 'res_id': dispatch_id, + } + else: + raise orm.except_orm(_('Information'), + _('No ready pickings to deliver!')) + else: + raise orm.except_orm(_('Error'), + _('You need to set at least one unit to do.')) === added file 'picking_dispatch_wave/dispatch_wave_view.xml' --- picking_dispatch_wave/dispatch_wave_view.xml 1970-01-01 00:00:00 +0000 +++ picking_dispatch_wave/dispatch_wave_view.xml 2014-04-14 09:33:05 +0000 @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + + <act_window id="action_prepare_picking_dispatch" + name="Prepare Picking Dispatch" + res_model="stock.picking.dispatch.wave" + view_type="form" + view_mode="form" + target="new" + /> + + <menuitem id="menu_prepare_picking_dispatch" + parent="stock.menu_stock_warehouse_mgmt" + sequence="40" + action="action_prepare_picking_dispatch" + groups="stock.group_stock_user,stock.group_stock_manager" + /> + + <record model="ir.ui.view" id="picking_dispatch_prepare_form"> + <field name="name">stock.picking.dispatch.wave form</field> + <field name="model">stock.picking.dispatch.wave</field> + <field name="arch" type="xml"> + <form string="Prepare Picking Dispatch Wave" version="7.0"> + <group> + <p class="oe_grey"> + This action will prepare you a picking dispatch + according the number of sale orders that you set. + </p> + </group> + <group> + <field name="nb"/> + <field name="picker_id"/> + </group> + <footer> + <button name="action_create_picking_dispatch" string="Prepare Picking Dispatch" type="object" + class="oe_highlight"/> + or + <button string="Cancel" class="oe_link" special="cancel" /> + </footer> + </form> + </field> + </record> + + </data> +</openerp> === added directory 'picking_dispatch_wave/i18n' === added file 'picking_dispatch_wave/i18n/fr.po' --- picking_dispatch_wave/i18n/fr.po 1970-01-01 00:00:00 +0000 +++ picking_dispatch_wave/i18n/fr.po 2014-04-14 09:33:05 +0000 @@ -0,0 +1,59 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * picking_dispatch_wave +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-04-07 15:37+0000\n" +"PO-Revision-Date: 2014-04-07 15:37+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: picking_dispatch_wave +#: view:stock.picking.dispatch.wave:0 +msgid "Cancel" +msgstr "Annuler" + +#. module: picking_dispatch_wave +#: model:ir.model.fields,field_description:picking_dispatch_wave.field_stock_picking_dispatch_wave_nb_sales +#: field:stock.picking.dispatch.wave,nb_sales:0 +msgid "How many sales?" +msgstr "Nombre de commandes de vente?" + +#. module: picking_dispatch_wave +#: model:ir.actions.act_window,name:picking_dispatch_wave.action_prepare_picking_dispatch +#: model:ir.ui.menu,name:picking_dispatch_wave.menu_prepare_picking_dispatch +#: view:stock.picking.dispatch.wave:0 +msgid "Prepare Picking Dispatch" +msgstr "Préparer un bon de préparation" + +#. module: picking_dispatch_wave +#: view:stock.picking.dispatch.wave:0 +msgid "Prepare Picking Dispatch Wave" +msgstr "Prépare un bon de préparation" + +#. module: picking_dispatch_wave +#: view:stock.picking.dispatch.wave:0 +msgid "This action will prepare you a picking dispatch\n" +" according the sale order number that you set." +msgstr "Cette action va vous préparer un bon de préparation\n" +" selon le nombre de commandes de vente voulu." + +#. module: picking_dispatch_wave +#: view:stock.picking.dispatch.wave:0 +msgid "or" +msgstr "ou" + +#. module: picking_dispatch_wave +#: code:_description:0 +#: model:ir.model,name:picking_dispatch_wave.model_stock_picking_dispatch_wave +#, python-format +msgid "stock.picking.dispatch.wave" +msgstr "stock.picking.dispatch.wave" + === added file 'picking_dispatch_wave/i18n/picking_dispatch_wave.pot' --- picking_dispatch_wave/i18n/picking_dispatch_wave.pot 1970-01-01 00:00:00 +0000 +++ picking_dispatch_wave/i18n/picking_dispatch_wave.pot 2014-04-14 09:33:05 +0000 @@ -0,0 +1,58 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * picking_dispatch_wave +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-04-07 15:37+0000\n" +"PO-Revision-Date: 2014-04-07 15:37+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: picking_dispatch_wave +#: view:stock.picking.dispatch.wave:0 +msgid "Cancel" +msgstr "" + +#. module: picking_dispatch_wave +#: model:ir.model.fields,field_description:picking_dispatch_wave.field_stock_picking_dispatch_wave_nb_sales +#: field:stock.picking.dispatch.wave,nb_sales:0 +msgid "How many sales?" +msgstr "" + +#. module: picking_dispatch_wave +#: model:ir.actions.act_window,name:picking_dispatch_wave.action_prepare_picking_dispatch +#: model:ir.ui.menu,name:picking_dispatch_wave.menu_prepare_picking_dispatch +#: view:stock.picking.dispatch.wave:0 +msgid "Prepare Picking Dispatch" +msgstr "" + +#. module: picking_dispatch_wave +#: view:stock.picking.dispatch.wave:0 +msgid "Prepare Picking Dispatch Wave" +msgstr "" + +#. module: picking_dispatch_wave +#: view:stock.picking.dispatch.wave:0 +msgid "This action will prepare you a picking dispatch\n" +" according the sale order number that you set." +msgstr "" + +#. module: picking_dispatch_wave +#: view:stock.picking.dispatch.wave:0 +msgid "or" +msgstr "" + +#. module: picking_dispatch_wave +#: code:_description:0 +#: model:ir.model,name:picking_dispatch_wave.model_stock_picking_dispatch_wave +#, python-format +msgid "stock.picking.dispatch.wave" +msgstr "" + === added directory 'picking_dispatch_wave/test' === added file 'picking_dispatch_wave/test/test_dispatch_wave.yml' --- picking_dispatch_wave/test/test_dispatch_wave.yml 1970-01-01 00:00:00 +0000 +++ picking_dispatch_wave/test/test_dispatch_wave.yml 2014-04-14 09:33:05 +0000 @@ -0,0 +1,47 @@ +- + In order to test stock picking wave + I have to ensure when a picking dispatch wave is set, a picking dispatch is well created. +- + I create a product +- + !record {model: product.product, id: prod_wave}: + name: product_wave + procure_method: make_to_stock + supply_method: buy +- + I create a SO +- + !record {model: sale.order, id: so_wave}: + partner_id: base.res_partner_2 + order_policy: 'manual' + picking_policy: 'direct' + order_line: + - product_id: prod_wave + product_uom_qty: 3 +- + Then I confirm the order +- + !workflow {model: sale.order, action: order_confirm, ref: so_wave} +- + Then (for test needs) I force the picking as ready to deliver +- + !python {model: stock.picking}: | + picking = self.search(cr, uid, [('sale_id', '=', ref("so_wave"))]) + self.force_assign(cr, uid, picking) +- + Then I ask a picking dispatch wave with 1 unit. +- + !record {model: stock.picking.dispatch.wave, id: wiz_wave}: + nb: 1 + picker_id: base.user_demo +- + Then I confirm the demand +- + !python {model: stock.picking.dispatch.wave}: + self.action_create_picking_dispatch(cr, uid, [ref("wiz_wave")], context=context) +- + Then I check if the picking dispatch is created +- + !python {model: picking.dispatch}: | + dispatchs = self.search(cr, uid, [('state','=','draft'),('picker_id','=',ref("base.user_demo"))]) + assert len(dispatchs) == 1, "The dispatch is ready" \ No newline at end of file
-- Mailing list: https://launchpad.net/~openerp-community-reviewer Post to : openerp-community-reviewer@lists.launchpad.net Unsubscribe : https://launchpad.net/~openerp-community-reviewer More help : https://help.launchpad.net/ListHelp