diff --git a/stock_move_location/__init__.py b/stock_move_location/__init__.py index 93569fb46..91ba63a47 100644 --- a/stock_move_location/__init__.py +++ b/stock_move_location/__init__.py @@ -3,3 +3,4 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from . import wizard +from . import models diff --git a/stock_move_location/models/__init__.py b/stock_move_location/models/__init__.py new file mode 100644 index 000000000..d8a43735d --- /dev/null +++ b/stock_move_location/models/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from . import stock_move diff --git a/stock_move_location/models/stock_move.py b/stock_move_location/models/stock_move.py new file mode 100644 index 000000000..b9c4883ea --- /dev/null +++ b/stock_move_location/models/stock_move.py @@ -0,0 +1,20 @@ +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import api, fields, models + + +class StockMove(models.Model): + _inherit = "stock.move" + + location_move = fields.Boolean( + string="Part of move location", + help="Wether this move is a part of stock_location moves", + ) + + @api.depends("location_move") + def _compute_show_details_visible(self): + super()._compute_show_details_visible() + for move in self: + if move.location_move: + move.show_details_visible = True diff --git a/stock_move_location/wizard/stock_move_location.py b/stock_move_location/wizard/stock_move_location.py index eae00cb72..65c39134b 100644 --- a/stock_move_location/wizard/stock_move_location.py +++ b/stock_move_location/wizard/stock_move_location.py @@ -2,6 +2,8 @@ # Copyright 2018 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from itertools import groupby + from odoo import api, fields, models @@ -34,6 +36,19 @@ class StockMoveLocationWizard(models.TransientModel): def _onchange_locations(self): self._clear_lines() + @api.onchange("stock_move_location_line_ids") + def _onchange_stock_move_location_line_ids(self): + lines_to_update = self.stock_move_location_line_ids.filtered( + lambda x: x.custom is True and + not all([x.origin_location_id, x.destination_location_id]) + ) + lines_to_update.update({ + "origin_location_id": self.origin_location_id, + "destination_location_id": self.destination_location_id, + }) + # for an easier extension of this function + return lines_to_update + def _clear_lines(self): origin = self.origin_location_id destination = self.destination_location_id @@ -54,8 +69,55 @@ class StockMoveLocationWizard(models.TransientModel): 'location_dest_id': self.destination_location_id.id, }) + @api.multi + def group_lines(self): + sorted_lines = sorted( + self.stock_move_location_line_ids, + key=lambda x: x.product_id, + ) + groups = groupby(sorted_lines, key=lambda x: x.product_id) + groups_dict = {} + for prod, lines in groups: + groups_dict[prod.id] = list(lines) + return groups_dict + + @api.multi def _create_moves(self, picking): - return self.stock_move_location_line_ids.create_move_lines(picking) + self.ensure_one() + groups = self.group_lines() + moves = self.env["stock.move"] + for group, lines in groups.items(): + move = self._create_move(picking, lines) + moves |= move + return moves + + def _get_move_values(self, picking, lines): + # locations are same for the products + location_from_id = lines[0].origin_location_id.id + location_to_id = lines[0].destination_location_id.id + product_id = lines[0].product_id.id + product_uom_id = lines[0].product_uom_id.id + qty = sum([x.move_quantity for x in lines]) + return { + "name": "test", + "location_id": location_from_id, + "location_dest_id": location_to_id, + "product_id": product_id, + "product_uom": product_uom_id, + "product_uom_qty": qty, + "picking_id": picking.id, + "location_move": True, + } + + @api.multi + def _create_move(self, picking, lines): + self.ensure_one() + move = self.env["stock.move"].create( + self._get_move_values(picking, lines), + ) + for line in lines: + line.create_move_lines(picking, move) + return move @api.multi def action_move_location(self): @@ -63,6 +125,8 @@ class StockMoveLocationWizard(models.TransientModel): picking = self._create_picking() self._create_moves(picking) if not self.env.context.get("planned"): + picking.action_confirm() + picking.action_assign() picking.button_validate() self.picking_id = picking return self._get_picking_action(picking.id) @@ -111,6 +175,7 @@ class StockMoveLocationWizard(models.TransientModel): 'lot_id': group.get("lot_id") or False, 'product_uom_id': product.uom_id.id, 'move_location_wizard_id': self.id, + 'custom': False, }) return product_data @@ -118,7 +183,9 @@ class StockMoveLocationWizard(models.TransientModel): self.ensure_one() if not self.stock_move_location_line_ids: for line_val in self._get_stock_move_location_lines_values(): - self.env["wiz.stock.move.location.line"].create(line_val).id + if line_val.get('max_quantity') <= 0: + continue + self.env["wiz.stock.move.location.line"].create(line_val) return { "type": "ir.actions.do_nothing", } diff --git a/stock_move_location/wizard/stock_move_location.xml b/stock_move_location/wizard/stock_move_location.xml index 263366e1d..6ae9831ed 100755 --- a/stock_move_location/wizard/stock_move_location.xml +++ b/stock_move_location/wizard/stock_move_location.xml @@ -16,15 +16,16 @@